DEV Community

Jared Fraser
Jared Fraser

Posted on

Using Headless Chrome to Automate Image Generation on Heroku

I automate some posting some daily shop rotations in popular games on my site xstats.gg to twitter - see an example

Building the image as a webpage first allows me to iterate quickly and keep the styles in parity with the rest of the site.

I use Chrome to load up the page and take a screenshot, and a seperate process tweets the image and posts to other social media.

Buildpacks

1. heroku/ruby
2. https://github.com/heroku/heroku-buildpack-chromedriver
3. https://github.com/heroku/heroku-buildpack-google-chrome
Enter fullscreen mode Exit fullscreen mode

Code

class Screenshot
  def capture
    setup
    take_photo
  end

  def setup
    chrome_shim = ENV.fetch("GOOGLE_CHROME_SHIM", nil)
    chrome_bin = ENV.fetch("GOOGLE_CHROME_BIN", nil)

    Selenium::WebDriver::Chrome.path = chrome_bin if chrome_bin
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('--headless')
    options.add_argument('--hide-scrollbars')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-dev-shm-usage')
    options.binary = chrome_shim if chrome_shim
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def tmp_file_path
    Rails.root.join("tmp", "screenshot-#{name}.png")
  end

  def take_photo
    driver.navigate.to("https://xstats.gg#{url}")
    max_height = driver.execute_script("return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight);")
    driver.manage.window.resize_to(1000, max_height)
    driver.save_screenshot tmp_file_path
    driver.close
  end
end
Enter fullscreen mode Exit fullscreen mode

Latest comments (0)