<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>instagram on Wouter Bulten</title>
    <link>https://www.wouterbulten.nl/tags/instagram/</link>
    <description>Recent content in instagram on Wouter Bulten</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>Copyright Wouter Bulten (except otherwise noted) &amp;copy; 2023 • All rights reserved.
</copyright>
    <lastBuildDate>Sat, 10 Jun 2017 00:00:00 +0000</lastBuildDate><atom:link href="https://www.wouterbulten.nl/tags/instagram/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Import/Adding Instagram posts to Jekyll</title>
      <link>https://www.wouterbulten.nl/posts/import-instagram-for-jekyll/</link>
      <pubDate>Sat, 10 Jun 2017 00:00:00 +0000</pubDate>
      
      <guid>https://www.wouterbulten.nl/posts/import-instagram-for-jekyll/</guid>
      <description>To integrate Instagram posts in to my website I created a small helper script that does the importing. In this post I&amp;#39;ll explain how it works.</description>
      <content:encoded><![CDATA[<p>Most of my food projects are first published on Instagram. Some interesting ones I also post here with a full recipe. For this I required a fast and (most importantly) simple way to add Instagram posts to a Jekyll blog. For this I created a shell script that can automatically create Jekyll post drafts from published Instagram posts.</p>
<p><em>Purely interested in the code?</em> The latest version of the code can be found in the <a href="https://github.com/wouterbulten/jekyll-instagram-importer">GitHub repository</a>.</p>
<h2 id="retrieving-post-images-from-instagram">Retrieving post images from Instagram</h2>
<p>Instagram has its own [API](<a href="https://www.instagram.com/de">https://www.instagram.com/de</a>  veloper/) but for most things you will need to register as an application to get a API key. For a simple importer script this is to much hassle and it is debatable whether Instagram would accept such a case as an application. Luckily, the Instagram API also has an <a href="https://www.instagram.com/developer/embedding/">embedding chapter</a> with calls that <strong>don&rsquo;t require an API key</strong>.</p>
<p>The first endpoint is the <code>media</code> endpoint, useful to retrieve images of a specific post:</p>
<pre tabindex="0"><code>GET /p/{shortcode}/media/?size={size}
</code></pre><p>This endpoint returns an image based on the id/shortcode of the Instagram post. For example, retrieving the thumbnail of my <a href="https://www.instagram.com/p/BVAWwPXjE2b/">latest food project</a> would result in the following call:</p>
<pre tabindex="0"><code>GET https://www.instagram.com/p/BVAWwPXjE2b/media/?size=t
</code></pre><p>My script imports the regular, large and small (thumbnail) image using <em>wget</em>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">wget --output-document<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$imgDir</span><span class="s2">/</span><span class="nv">$fileName</span><span class="s2">.jpg&#34;</span> <span class="s2">&#34;https://www.instagram.com/p/</span><span class="nv">$post</span><span class="s2">/media&#34;</span>
</span></span><span class="line"><span class="cl">wget --output-document<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$imgDir</span><span class="s2">/</span><span class="si">${</span><span class="nv">fileName</span><span class="si">}</span><span class="s2">_large.jpg&#34;</span> <span class="s2">&#34;https://www.instagram.com/p/</span><span class="nv">$post</span><span class="s2">/media?size=l&#34;</span>
</span></span><span class="line"><span class="cl">wget --output-document<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$imgDir</span><span class="s2">/</span><span class="si">${</span><span class="nv">fileName</span><span class="si">}</span><span class="s2">_thumbnail.jpg&#34;</span> <span class="s2">&#34;https://www.instagram.com/p/</span><span class="nv">$post</span><span class="s2">/media?size=t&#34;</span>
</span></span></code></pre></div><h2 id="getting-the-post-snippet">Getting the post snippet</h2>
<p>To embed the post itself we can use a snippet that Instagram provides. Unfortunately, this snippet is different for each post. We can however request this from the API. For this step we need a JSON parser for which I use <a href="https://stedolan.github.io/jq/">jq</a>. The endpoint for the snippet code is:</p>
<pre tabindex="0"><code>GET https://api.instagram.com/oembed/?url=http://instagr.am/p/{shortcode}
</code></pre><p>This call returns a JSON object containing the snippet, example:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;version&#34;</span><span class="p">:</span><span class="s2">&#34;1.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;title&#34;</span><span class="p">:</span><span class="s2">&#34;Spring dessert: Lemon mousse with pistachio and ginger #food #desserts #platingfood #dessert #mousse #cooking  #dessertporn #foodporn #homemade&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;author_name&#34;</span><span class="p">:</span><span class="s2">&#34;wouterbulten&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;author_url&#34;</span><span class="p">:</span><span class="s2">&#34;https://www.instagram.com/wouterbulten&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;author_id&#34;</span><span class="p">:</span><span class="mi">4219314927</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;media_id&#34;</span><span class="p">:</span><span class="s2">&#34;1531323945365294491_4219314927&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;provider_name&#34;</span><span class="p">:</span><span class="s2">&#34;Instagram&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;provider_url&#34;</span><span class="p">:</span><span class="s2">&#34;https://www.instagram.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;type&#34;</span><span class="p">:</span><span class="s2">&#34;rich&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;width&#34;</span><span class="p">:</span><span class="mi">658</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;height&#34;</span><span class="p">:</span><span class="kc">null</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;html&#34;</span><span class="p">:</span><span class="s2">&#34;\u003cblockquote class=\&#34;instagram-media\&#34; data-instgrm-captioned data-instgrm-version=\&#34;7\&#34; style=\&#34; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);\&#34;\u003e\u003cdiv style=\&#34;padding:8px;\&#34;\u003e \u003cdiv style=\&#34; background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;\&#34;\u003e \u003cdiv style=\&#34; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;\&#34;\u003e\u003c/div\u003e\u003c/div\u003e \u003cp style=\&#34; margin:8px 0 0 0; padding:0 4px;\&#34;\u003e \u003ca href=\&#34;https://www.instagram.com/p/BVAWwPXjE2b/\&#34; style=\&#34; color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;\&#34; target=\&#34;_blank\&#34;\u003eSpring dessert: Lemon mousse with pistachio and ginger #food #desserts #platingfood #dessert #mousse #cooking  #dessertporn #foodporn #homemade\u003c/a\u003e\u003c/p\u003e \u003cp style=\&#34; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\&#34;\u003eA post shared by Wouter Bulten (@wouterbulten) on \u003ctime style=\&#34; font-family:Arial,sans-serif; font-size:14px; line-height:17px;\&#34; datetime=\&#34;2017-06-06T16:54:21+00:00\&#34;\u003eJun 6, 2017 at 9:54am PDT\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\&#34;//platform.instagram.com/en_US/embeds.js\&#34;\u003e\u003c/script\u003e&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;thumbnail_url&#34;</span><span class="p">:</span><span class="s2">&#34;https://scontent-amt2-1.cdninstagram.com/t51.2885-15/s640x640/sh0.08/e35/18950105_2007839122778210_1395817508811833344_n.jpg&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;thumbnail_width&#34;</span><span class="p">:</span><span class="mi">640</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="nt">&#34;thumbnail_height&#34;</span><span class="p">:</span><span class="mi">640</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>With jq we can retrieve only the relevant part of the object (jq must be on your path):</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">curl -s <span class="s2">&#34;https://api.instagram.com/oembed/?url=http://instagr.am/p/BVAWwPXjE2b&#34;</span> <span class="p">|</span> jq -r <span class="s1">&#39;.html&#39;</span> 
</span></span></code></pre></div><h2 id="tying-everything-together">Tying everything together</h2>
<p>To create a new Jekyll post the only step left is to create a correctly formatted Markdown file. My importer script asks for some basic info (ig post id, title, date, etc.) and then saves the images and the post file to the correct directories. The full script is shown below and can also be found on the <a href="https://github.com/wouterbulten/jekyll-instagram-importer">GitHub repository</a>.</p>
<p>In all, pretty simple but is saves a lot of time :) It could even be extended to extract the title and keywords and use these in Jekyll; that&rsquo;s something for the future though.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/bin/bash
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;INSTAGRAM TO JEKYLL IMPORTER&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[?] Which Instagram post would you like to import?&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">read</span> post
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[?] What is the title of your new post?&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">read</span> title
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[?] What should the publish date of the post be? (y-m-d)&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">read</span> date
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[?] Where should the post be saved?&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">read</span> postDir
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;[?] Where should the images be saved?&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">read</span> imgDir
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Format filename</span>
</span></span><span class="line"><span class="cl"><span class="nv">fileName</span><span class="o">=</span><span class="k">$(</span><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$date</span><span class="s2">-</span><span class="nv">$title</span><span class="s2">&#34;</span> <span class="p">|</span> iconv -t ascii//TRANSLIT <span class="p">|</span> sed -E s/<span class="o">[</span>^a-zA-Z0-9<span class="o">]</span>+/-/g <span class="p">|</span> sed -E s/^-+<span class="se">\|</span>-+$//g <span class="p">|</span> tr A-Z a-z<span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">path</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$postDir</span><span class="s2">/</span><span class="nv">$fileName</span><span class="s2">.md&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Show confirmation on screen</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;Starting import&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;--&gt; importing post with id &#39;</span><span class="nv">$post</span><span class="s2">&#39;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;--&gt; output file: </span><span class="nv">$fileName</span><span class="s2">.md&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Download the images</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;--&gt; import images&#34;</span>
</span></span><span class="line"><span class="cl">wget --output-document<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$imgDir</span><span class="s2">/</span><span class="nv">$fileName</span><span class="s2">.jpg&#34;</span> <span class="s2">&#34;https://www.instagram.com/p/</span><span class="nv">$post</span><span class="s2">/media&#34;</span>
</span></span><span class="line"><span class="cl">wget --output-document<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$imgDir</span><span class="s2">/</span><span class="si">${</span><span class="nv">fileName</span><span class="si">}</span><span class="s2">_large.jpg&#34;</span> <span class="s2">&#34;https://www.instagram.com/p/</span><span class="nv">$post</span><span class="s2">/media?size=l&#34;</span>
</span></span><span class="line"><span class="cl">wget --output-document<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$imgDir</span><span class="s2">/</span><span class="si">${</span><span class="nv">fileName</span><span class="si">}</span><span class="s2">_thumbnail.jpg&#34;</span> <span class="s2">&#34;https://www.instagram.com/p/</span><span class="nv">$post</span><span class="s2">/media?size=t&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output markdown file</span>
</span></span><span class="line"><span class="cl"><span class="nv">content</span><span class="o">=</span><span class="s2">&#34;---
</span></span></span><span class="line"><span class="cl"><span class="s2">layout: post
</span></span></span><span class="line"><span class="cl"><span class="s2">title:  &#39;</span><span class="nv">$title</span><span class="s2">&#39;
</span></span></span><span class="line"><span class="cl"><span class="s2">date:   </span><span class="nv">$date</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">instagram_id: </span><span class="nv">$ost</span><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">tags: []
</span></span></span><span class="line"><span class="cl"><span class="s2">post_image: </span><span class="nv">$imgDir</span><span class="s2">/</span><span class="nv">$fileName</span><span class="s2">.jpg
</span></span></span><span class="line"><span class="cl"><span class="s2">post_image_large: </span><span class="nv">$imgDir</span><span class="s2">/</span><span class="si">${</span><span class="nv">fileName</span><span class="si">}</span><span class="s2">_large.jpg
</span></span></span><span class="line"><span class="cl"><span class="s2">post_image_small: </span><span class="nv">$imgDir</span><span class="s2">/</span><span class="si">${</span><span class="nv">fileName</span><span class="si">}</span><span class="s2">_thumbnail.jpg
</span></span></span><span class="line"><span class="cl"><span class="s2">---
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">&lt;!-- begin ig snippet --&gt;&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$content</span><span class="s2">&#34;</span> &gt;&gt; <span class="s2">&#34;</span><span class="nv">$path</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Download IG snippet</span>
</span></span><span class="line"><span class="cl">curl -s <span class="s2">&#34;https://api.instagram.com/oembed/?url=http://instagr.am/p/</span><span class="nv">$post</span><span class="s2">&#34;</span> <span class="p">|</span> jq -r <span class="s1">&#39;.html&#39;</span> &gt;&gt; <span class="s2">&#34;</span><span class="nv">$path</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;&lt;!-- end ig snippet --&gt;&#34;</span> &gt;&gt; <span class="s2">&#34;</span><span class="nv">$path</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;IMPORT COMPLETE&#34;</span>
</span></span></code></pre></div>]]></content:encoded>
    </item>
    
  </channel>
</rss>
