<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: JJ. Ramirez</title>
    <description>The latest articles on DEV Community by JJ. Ramirez (@whoisjuan).</description>
    <link>https://dev.to/whoisjuan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F799536%2F7b5a2c19-4b49-46f6-8530-e05cf8490e8f.png</url>
      <title>DEV Community: JJ. Ramirez</title>
      <link>https://dev.to/whoisjuan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/whoisjuan"/>
    <language>en</language>
    <item>
      <title>How to Build a Bulk Screenshot App with Google Sheets</title>
      <dc:creator>JJ. Ramirez</dc:creator>
      <pubDate>Sat, 12 Mar 2022 01:31:34 +0000</pubDate>
      <link>https://dev.to/whoisjuan/how-to-build-a-bulk-screenshot-app-with-google-sheets-4kk6</link>
      <guid>https://dev.to/whoisjuan/how-to-build-a-bulk-screenshot-app-with-google-sheets-4kk6</guid>
      <description>&lt;p&gt;Have you ever been in a situation where you need to screenshot a long list of websites? Perhaps, the list is so long that doing it manually would take days?&lt;/p&gt;

&lt;p&gt;If that sounds familiar, this post is for you. In this tutorial, we will go through the process of building a bulk screenshot app on top of Google Sheets and the GetScreenshot API. &lt;/p&gt;

&lt;p&gt;After you finish this tutorial you will have a powerful little app to take screenshots at scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A Google Sheets Spreadsheet&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://www.getscreenshotapi.com" rel="noopener noreferrer"&gt;screenshot API&lt;/a&gt; token from GetScreenshot (5 USD/month for 2500 screenshot but the first month is free)&lt;/li&gt;
&lt;li&gt;Some small JS knowledge would be helpful but not necessary.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Tutorial
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Creating a spreadsheet in Google Sheets and opening the scripting environment (Google App Script)
&lt;/h3&gt;

&lt;p&gt;The first step of this tutorial is to create a spreadsheet and configure the script that will be the core function of our bulk screenshot application. &lt;/p&gt;

&lt;p&gt;After you have created a Google Sheet you will need to open the Google App Script Editor. To do this go to the top bar of Google Sheets and click on &lt;em&gt;Tools&lt;/em&gt; and then in &lt;em&gt;Script Editor&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8vo4jvdxlmeb7u38vw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm8vo4jvdxlmeb7u38vw0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Add the bulk screenshot code to Google App Script
&lt;/h3&gt;

&lt;p&gt;Once you have your Google App Script editor open you will see an empty function like the one shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztoiti1s7kbpqe9ttn1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fztoiti1s7kbpqe9ttn1s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go ahead and delete the initial starter code and add our own custom code which will allow us to create a function to invoke the screenshot API.&lt;/p&gt;

&lt;p&gt;The code that you want to paste into the editor is the following one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// You need to replace the API_KEY value with an actual API Key from GetScreenshot.&lt;/span&gt;
&lt;span class="c1"&gt;// You can sign-up for an account at https://www.getscreenshotapi.com to get an API Key.&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Your-API-Key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;retrieveScreenshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;apiEndpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.rasterwise.com/v1/get-screenshot?apikey=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;url=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="c1"&gt;// Create our json request, w/ text, language, type &amp;amp; encoding&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nlData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;document&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PLAIN_TEXT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;   &lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="c1"&gt;//  Package all of the options and the data together for the call&lt;/span&gt;
 &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;nlOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="na"&gt;method&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;};&lt;/span&gt;

 &lt;span class="c1"&gt;//  And make the call&lt;/span&gt;
 &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UrlFetchApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiEndpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;nlOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;jsonified&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;screenshotImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;stringA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonified&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;stringA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Google App Script Editor should now look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtypvfwxm64qnds7qb9o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqtypvfwxm64qnds7qb9o.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Get a screenshot API key from GetScreenshot and add it to your script.
&lt;/h3&gt;

&lt;p&gt;Google Sheets doesn't have a native API or functionality to take screenshots from the cloud. So we will need to rely on a Screenshot API provider for this part of the operation. &lt;/p&gt;

&lt;p&gt;In this tutorial, we are using &lt;a href="https://www.getscreenshotapi.com" rel="noopener noreferrer"&gt;GetScreenshot&lt;/a&gt; because it's reliable, accurate, and cheaper than all the other options I've seen out there. But you can use any other screenshot API of your choice. However, you will need to change the parameters to fit whatever API you end up using.&lt;/p&gt;

&lt;p&gt;Once you have signed up, you will receive an API key. Go ahead and replace the variable &lt;code&gt;var API_KEY = "Your-API-Key"&lt;/code&gt; with whatever API key you receive. After doing it, it should look something like this var &lt;code&gt;API_KEY = "dLDd123dn13KDAsd1n239K34"&lt;/code&gt; where the random characters correspond to the API Key you received.&lt;/p&gt;

&lt;p&gt;Now simply save the script and close the editor:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F735oef10boffdjxsntpz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F735oef10boffdjxsntpz.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Test the function invocation from your Google Sheet
&lt;/h3&gt;

&lt;p&gt;What we did with the process above was to instrument our spreadsheet with the function &lt;code&gt;retrieveScreenshot()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Now you can use this function in any cell of the spreadsheet in the same way you can invoke any other standard function by typing &lt;code&gt;=&lt;/code&gt; and the name of the function. For example &lt;code&gt;=SUM()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Have in mind that our &lt;code&gt;retrieveScreenshot()&lt;/code&gt; function can only receive a valid website URL in order to return back the URL of a screenshot.&lt;/p&gt;

&lt;p&gt;To pass the URL of a website you will need to pass it verbatim, for example &lt;code&gt;=retrieveScreenshot('https://google.com')&lt;/code&gt; but of course you can also pass the contents of another cell that has a website URL.&lt;/p&gt;

&lt;p&gt;This is where our bulk screenshot app comes alive. You can have a list of websites in one column and then do the invocation in the next column. Something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxed9j6u8kuknjbbg1zj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxed9j6u8kuknjbbg1zj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you invoke the &lt;code&gt;retrieveScreenshot()&lt;/code&gt; function you will see an interim state that reads "Loading...". &lt;br&gt;
This means that the screenshot process is underway and the screenshot URL is about to be returned:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkm76e664wwfggs5eg5s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftkm76e664wwfggs5eg5s.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, you can do a corner drop operation to make the same screenshot operation replicated across all the rows in the first column. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdonrcpzdj5t0af7dph1k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdonrcpzdj5t0af7dph1k.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;BOOM!! Your screenshot bulk machine is up and ready. Now you can use this spreadsheet to generate screenshots at scale.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Caveats and Recommendations
&lt;/h3&gt;

&lt;p&gt;1) You won't see a typeahead or suggestion for the &lt;code&gt;retrieveScreenshot()&lt;/code&gt; when you enter it like you do when you type native functions in a cell. &lt;br&gt;
That's alright, the function is there and you should be able to call it normally.&lt;/p&gt;

&lt;p&gt;2) Once you’re done with a bulk screenshot operation, you will need to select the results, and then copy and paste the values on the same column. More precisely you need to select the whole column, right-click copy the whole selection, and paste in the same position as &lt;strong&gt;Values Only&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you skip doing this the next time you open the Google Sheet, it will attempt to do the whole bulk screenshot operation again (for all the URLs). This will likely consume your GetScreenshot quota unnecessarily so that's why I recommend pasting the results as values.&lt;/p&gt;




&lt;p&gt;That's it. You're done. Enjoy your bulk screenshot app 😃&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
