<?xml version="1.0" encoding="UTF-8"?>
<rss version='2.0' xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Mark Coleman</title>
    <description>Mark Coleman is a full stack developer focusing on the latest in web technologies. Mark enjoys learning about new programming trends. Mark also likes to share his knowledge by attending local development groups and blogging (kramnameloc.com) about programming topics. When Mark is not absorbing everything development he enjoys photography, anything pertaining to The Simpsons, and a part time craft beer/bacon aficionado.</description>
    <link>https://markcoleman.silvrback.com/feed</link>
    <atom:link href="https://markcoleman.silvrback.com/feed" rel="self" type="application/rss+xml"/>
    <category domain="markcoleman.silvrback.com">Content Management/Blog</category>
    <language>en-us</language>
      <pubDate>Thu, 29 Apr 2021 22:05:43 -0400</pubDate>
    <managingEditor>markcoleman@gmail.com (Mark Coleman)</managingEditor>
      <item>
        <guid>http://kramnameloc.com/automating-disney#51829</guid>
          <pubDate>Thu, 29 Apr 2021 22:05:43 -0400</pubDate>
        <link>http://kramnameloc.com/automating-disney</link>
        <title>Automating Disney</title>
        <description>Setting up a pipedream.com workflow</description>
        <content:encoded><![CDATA[<h1 id="the-problem">The Problem</h1>

<p>My family had the dream of going to Disney for my sister in law birthday in April and after coordinating the house, plane tickets, multiple families, and tickets we had a problem.  The park tickets were not purchased at the exact same moment and some of the family was not able to <a href="https://disneyworld.disney.go.com/experience-updates/park-reservations/">reserve their park</a>! How could we fix this so the family can go to the park together? </p>

<h2 id="the-calendar">The Calendar</h2>

<p><img alt="Silvrback blog image " src="https://silvrback.s3.amazonaws.com/uploads/a94b16cf-40e1-4a93-b4f2-7248726e3d00/calendar.png" /><br>
We could do the following...</p>

<ul>
<li>Manually Click Dates</li>
<li>Check Available Parks</li>
<li>Repeat above…forever…hoping to get lucky</li>
</ul>

<p>This clearly is not something we can do...there must be a way to dig deeper and automate the checking.</p>

<h2 id="finding-the-data">Finding The Data</h2>

<p><img alt="Silvrback blog image " src="https://silvrback.s3.amazonaws.com/uploads/a94b16cf-40e1-4a93-b4f2-7248726e3d00/preview.png" /></p>

<p>Lets look to see how the calendar actually works.</p>

<ul>
<li>Inspect page load via developer tools</li>
<li>Check XHR to see if there are any api requests....</li>
<li>Looking through the requests we see <code>calendar</code></li>
</ul>

<h2 id="the-api">The API</h2>

<p>If you view the request in a new window we get some nicely formatted <code>json</code> and the url is human readable.</p>

<blockquote>
<p><a href="https://disneyworld.disney.go.com/availability-calendar/api/calendar?segment=tickets&startDate=2021-04-05&endDate=2021-04-30">https://disneyworld.disney.go.com/availability-calendar/api/calendar?segment=tickets&amp;startDate=2021-04-05&amp;endDate=2021-04-30</a></p>
</blockquote>

<p>Thankful we see that the query string has a lot of helpful parameters</p>

<ul>
<li><code>startDate</code></li>
<li><code>endDate</code></li>
<li><code>segment</code></li>
</ul>

<h2 id="decoding-response">Decoding Response</h2>

<p>Now that we discovered the format of the request next we need to understand the response.</p>
<div class="highlight"><pre><span></span><span class="p">[</span>
  <span class="p">{</span>
    <span class="nt">&quot;date&quot;</span><span class="p">:</span> <span class="s2">&quot;2021-04-17&quot;</span><span class="p">,</span>
    <span class="nt">&quot;availability&quot;</span><span class="p">:</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span>
    <span class="nt">&quot;parks&quot;</span><span class="p">:</span> <span class="p">[]</span>
  <span class="p">},</span>
  <span class="p">{</span>
    <span class="nt">&quot;date&quot;</span><span class="p">:</span> <span class="s2">&quot;2021-04-18&quot;</span><span class="p">,</span>
    <span class="nt">&quot;availability&quot;</span><span class="p">:</span> <span class="s2">&quot;partial&quot;</span><span class="p">,</span>
    <span class="nt">&quot;parks&quot;</span><span class="p">:</span> <span class="p">[</span>
      <span class="s2">&quot;80007838&quot;</span>
    <span class="p">]</span>
  <span class="p">},</span>
  <span class="p">{</span>
    <span class="nt">&quot;date&quot;</span><span class="p">:</span> <span class="s2">&quot;2021-04-19&quot;</span><span class="p">,</span>
    <span class="nt">&quot;availability&quot;</span><span class="p">:</span> <span class="s2">&quot;partial&quot;</span><span class="p">,</span>
    <span class="nt">&quot;parks&quot;</span><span class="p">:</span> <span class="p">[</span>
      <span class="s2">&quot;80007838&quot;</span>
    <span class="p">]</span>
  <span class="p">},</span>
  <span class="p">{</span>
    <span class="nt">&quot;date&quot;</span><span class="p">:</span> <span class="s2">&quot;2021-04-20&quot;</span><span class="p">,</span>
    <span class="nt">&quot;availability&quot;</span><span class="p">:</span> <span class="s2">&quot;partial&quot;</span><span class="p">,</span>
    <span class="nt">&quot;parks&quot;</span><span class="p">:</span> <span class="p">[</span>
      <span class="s2">&quot;80007823&quot;</span><span class="p">,</span>
      <span class="s2">&quot;80007838&quot;</span>
    <span class="p">]</span>
  <span class="p">}</span>
<span class="p">]</span>
</pre></div>
<p>The good news the json response is fairly straight forward except for some magic numbers.</p>

<ul>
<li><code>date</code></li>
<li><code>availability</code> </li>
<li><code>parks</code> list of parks that are available

<ul>
<li><code>Epcot 80007838</code></li>
<li><code>Animal Kingdom 80007823</code></li>
<li><code>Magic Kingdom 80007944</code></li>
<li><code>Hollywood Studios  80007998</code></li>
</ul></li>
</ul>

<p><em>We were able to reverse engineer the above magic numbers by clicking around the calendar and recording which numbers showed up compared to what was displayed on the screen.</em></p>

<h2 id="nodejs">NodeJs</h2>

<p>Now that we had an api, understood the request and response lets use turn this into a small program using NodeJs and <a href="https://github.com/axios/axios"><code>🔗axios</code></a>.  Our program will need to do the following.</p>

<ul>
<li>Request Data from the API</li>
<li>Parse the response</li>
<li>If availability do…….something.</li>
</ul>

<p>Once we put this all together we ended up with the following.</p>
<div class="highlight"><pre><span></span><span class="kr">const</span> <span class="nx">axios</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;axios&quot;</span><span class="p">);</span>

<span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span>
    <span class="s2">&quot;https://disneyworld.disney.go.com/availability-calendar/api/calendar?segment=tickets&amp;startDate=2021-04-17&amp;endDate=2021-04-17&quot;</span><span class="p">;</span>

<span class="p">(</span><span class="nx">async</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
    <span class="k">try</span> <span class="p">{</span>
        <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>

        <span class="kd">var</span> <span class="nx">epcot</span> <span class="o">=</span> <span class="s2">&quot;80007838&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">animalKingdom</span> <span class="o">=</span> <span class="s2">&quot;80007823&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">magicKingdom</span> <span class="o">=</span> <span class="s2">&quot;80007944&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">hollywood</span> <span class="o">=</span> <span class="s2">&quot;80007998&quot;</span><span class="p">;</span>

        <span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">alert</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

        <span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">date</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
            <span class="nx">message</span> <span class="o">+=</span> <span class="sb">`Date: </span><span class="si">${</span><span class="nx">date</span><span class="p">.</span><span class="nx">date</span><span class="si">}</span><span class="sb"> | Parks:`</span><span class="p">;</span>
            <span class="kd">var</span> <span class="nx">parkNames</span> <span class="o">=</span> <span class="p">[];</span>
            <span class="nx">date</span><span class="p">.</span><span class="nx">parks</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">park</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">epcot</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Epcot&quot;</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">animalKingdom</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Animal Kingdom&quot;</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">magicKingdom</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">alert</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Magic Kingdom&quot;</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">hollywood</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Hollywood&quot;</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">});</span>
            <span class="nx">message</span> <span class="o">+=</span> <span class="sb">`</span><span class="si">${</span><span class="nx">parkNames</span><span class="p">.</span><span class="nx">join</span><span class="p">()</span><span class="si">}</span><span class="sb"> </span><span class="err">\</span><span class="sb">n`</span><span class="p">;</span>
        <span class="p">});</span>
        <span class="k">if</span> <span class="p">(</span><span class="nx">alert</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">//send alert</span>
        <span class="p">}</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">})();</span>
</pre></div>
<p>As you can see from the above we parsed the response and then captured the parks that are available and only trigger an alert for <code>Magic Kingdom</code> as that was the park the family wanted to go to on the day <code>2021-04-17</code></p>

<h2 id="automation">Automation</h2>

<p>Now that we had a node program we needed to run this on a schedule to automagically check ever so often to see if any new parks open up. We could run via cron or similar scheduling tools, manually run it, or a server-less approach.</p>

<p><img alt="Silvrback blog image " src="https://silvrback.s3.amazonaws.com/uploads/a94b16cf-40e1-4a93-b4f2-7248726e3d00/pipedream.png" /></p>

<p>I decided to go with <a href="https://pipedream.com">pipedream</a> as it ticked all the boxes.</p>

<blockquote>
<p>Stop writing boilerplate code, struggling with authentication and managing infrastructure. Start connecting APIs with code-level control when you need it — and no code when you don&#39;t.</p>
</blockquote>

<h3 id="convert-to-workflow">Convert to Workflow</h3>

<p>It was fairly straightforward to convert the NodeJs program to a pipe dream workflow as it had node support at its core which made the migration easy.</p>

<h3 id="steps">Steps</h3>

<p>The first thing we needed to do is define a few steps to help flow together what has to happen at each execution along the way.</p>

<h4 id="dates">Dates</h4>

<p>We had a step for date that just returns the date we want to check for the calendar checking step.</p>
<div class="highlight"><pre><span></span><span class="nx">async</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">steps</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="nx">date</span><span class="o">:</span> <span class="s2">&quot;2021-04-17&quot;</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
<h4 id="check-api">Check API</h4>

<p>As you can see this is a fairly easy migration but a few changes happened to make it work in pipedream</p>

<ul>
<li>pass in the <code>date</code> via the <code>steps</code> object <code>steps.date_to_check.$return_value.date;</code></li>
<li>return an object so it can be used in future steps</li>
</ul>
<div class="highlight"><pre><span></span>        <span class="k">return</span> <span class="p">{</span>
            <span class="nx">alert</span><span class="o">:</span> <span class="nx">alert</span><span class="p">,</span>
            <span class="nx">message</span><span class="o">:</span> <span class="nx">message</span>
        <span class="p">};</span>
</pre></div><div class="highlight"><pre><span></span><span class="nx">async</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">steps</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
    <span class="kr">const</span> <span class="nx">axios</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;axios&quot;</span><span class="p">);</span>

    <span class="kd">let</span> <span class="nx">date</span> <span class="o">=</span> <span class="nx">steps</span><span class="p">.</span><span class="nx">date_to_check</span><span class="p">.</span><span class="nx">$return_value</span><span class="p">.</span><span class="nx">date</span><span class="p">;</span>
    <span class="kd">let</span> <span class="nx">url</span> <span class="o">=</span>
        <span class="sb">`https://disneyworld.disney.go.com/availability-calendar/api/calendar?segment=tickets&amp;startDate=</span><span class="si">${</span><span class="nx">date</span><span class="si">}</span><span class="sb">&amp;endDate=</span><span class="si">${</span><span class="nx">date</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>

    <span class="k">try</span> <span class="p">{</span>
        <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="nx">await</span> <span class="nx">axios</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>

        <span class="kd">var</span> <span class="nx">epcot</span> <span class="o">=</span> <span class="s2">&quot;80007838&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">animalKingdom</span> <span class="o">=</span> <span class="s2">&quot;80007823&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">magicKingdom</span> <span class="o">=</span> <span class="s2">&quot;80007944&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">hollywood</span> <span class="o">=</span> <span class="s2">&quot;80007998&quot;</span><span class="p">;</span>

        <span class="kd">var</span> <span class="nx">message</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">;</span>
        <span class="kd">var</span> <span class="nx">alert</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>

        <span class="nx">response</span><span class="p">.</span><span class="nx">data</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">date</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
            <span class="nx">message</span> <span class="o">+=</span> <span class="sb">`Date: </span><span class="si">${</span><span class="nx">date</span><span class="p">.</span><span class="nx">date</span><span class="si">}</span><span class="sb"> | Parks:`</span><span class="p">;</span>
            <span class="kd">var</span> <span class="nx">parkNames</span> <span class="o">=</span> <span class="p">[];</span>
            <span class="nx">date</span><span class="p">.</span><span class="nx">parks</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">park</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">epcot</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Epcot&quot;</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">animalKingdom</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Animal Kingdom&quot;</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">magicKingdom</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">alert</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Magic Kingdom&quot;</span><span class="p">);</span>
                <span class="p">}</span>
                <span class="k">if</span> <span class="p">(</span><span class="nx">park</span> <span class="o">===</span> <span class="nx">hollywood</span><span class="p">)</span> <span class="p">{</span>
                    <span class="nx">parkNames</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s2">&quot;Hollywood&quot;</span><span class="p">);</span>
                <span class="p">}</span>
            <span class="p">});</span>
            <span class="nx">message</span> <span class="o">+=</span> <span class="sb">`</span><span class="si">${</span><span class="nx">parkNames</span><span class="p">.</span><span class="nx">join</span><span class="p">()</span><span class="si">}</span><span class="sb"> </span><span class="err">\</span><span class="sb">n`</span><span class="p">;</span>
        <span class="p">});</span>
        <span class="k">return</span> <span class="p">{</span>
            <span class="nx">alert</span><span class="o">:</span> <span class="nx">alert</span><span class="p">,</span>
            <span class="nx">message</span><span class="o">:</span> <span class="nx">message</span>
        <span class="p">};</span>
    <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
        <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">body</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
<h4 id="email">Email</h4>

<p>As we said above we want to do something this if the alert is triggered which in this workflow happens to be an email.  My favorite zero friction email service happens to be <a href="https://sendgrid.com">sendgrid</a>  and good news is <a href="https://pipedream.com/apps/sendgrid">pipedream has a built in connector to send grid</a>.</p>
<div class="highlight"><pre><span></span><span class="nx">async</span> <span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">steps</span><span class="p">,</span> <span class="nx">params</span><span class="p">,</span> <span class="nx">auths</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
    <span class="kr">const</span> <span class="nx">axios</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;axios&#39;</span><span class="p">)</span>
    <span class="k">if</span> <span class="p">(</span><span class="nx">steps</span><span class="p">.</span><span class="nx">check_disney_calendar</span><span class="p">.</span><span class="nx">$return_value</span><span class="p">.</span><span class="nx">alert</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">return</span> <span class="nx">await</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;@pipedreamhq/platform&quot;</span><span class="p">).</span><span class="nx">axios</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="p">{</span>
            <span class="nx">url</span><span class="o">:</span> <span class="sb">`https://api.sendgrid.com/v3/mail/send`</span><span class="p">,</span>
            <span class="nx">headers</span><span class="o">:</span> <span class="p">{</span>
                <span class="nx">Authorization</span><span class="o">:</span> <span class="sb">`Bearer </span><span class="si">${</span><span class="nx">auths</span><span class="p">.</span><span class="nx">sendgrid</span><span class="p">.</span><span class="nx">api_key</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span>
            <span class="p">},</span>
            <span class="nx">method</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
            <span class="nx">data</span><span class="o">:</span> <span class="p">{</span>
                <span class="s2">&quot;personalizations&quot;</span><span class="o">:</span> <span class="p">[{</span>
                    <span class="s2">&quot;to&quot;</span><span class="o">:</span> <span class="p">[{</span>
                        <span class="s2">&quot;email&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">to_email</span><span class="p">,</span>
                        <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">to_name</span>
                    <span class="p">}],</span>
                    <span class="s2">&quot;subject&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">subject</span>
                <span class="p">}],</span>
                <span class="s2">&quot;from&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;email&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">from_email</span><span class="p">,</span>
                    <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">from_name</span>
                <span class="p">},</span>
                <span class="s2">&quot;reply_to&quot;</span><span class="o">:</span> <span class="p">{</span>
                    <span class="s2">&quot;email&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">reply_to_email</span><span class="p">,</span>
                    <span class="s2">&quot;name&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">reply_to_name</span>
                <span class="p">},</span>
                <span class="s2">&quot;content&quot;</span><span class="o">:</span> <span class="p">[{</span>
                    <span class="s2">&quot;type&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">type</span><span class="p">,</span>
                    <span class="s2">&quot;value&quot;</span><span class="o">:</span> <span class="nx">params</span><span class="p">.</span><span class="nx">value</span>
                <span class="p">}]</span>
            <span class="p">}</span>
        <span class="p">})</span>
    <span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p><em>we modified the built in template slightly to only send the email if <code>steps.check_disney_calendar.$return_value.alert</code> is actually true</em></p>

<p>Now that we have all of these in place it is time to try it out by finding a date that has availability and use that in the <code>date</code> step.</p>

<h3 id="testing-it-out">Testing It Out</h3>

<p><img alt="Silvrback blog image " src="https://silvrback.s3.amazonaws.com/uploads/a94b16cf-40e1-4a93-b4f2-7248726e3d00/email.png" /></p>

<p>We set the workflow to trigger every 10 minutes and as soon as we hit the right condition we got the above email.</p>

<h2 id="time-to-wait-did-it-work">Time To Wait...Did it work?</h2>

<h3 id="yes">Yes</h3>

<p>It actually did work we triggered the check every 10 minutes and as soon as I got the email I resorted to the manual flow of contacting every family member.  I could have easily used twilio to make a phone call, maybe that will be in the next iteration.</p>
]]></content:encoded>
      </item>
      <item>
        <guid>http://kramnameloc.com/pushing-image-to-gitlab#47589</guid>
          <pubDate>Sun, 28 Jul 2019 11:58:46 -0400</pubDate>
        <link>http://kramnameloc.com/pushing-image-to-gitlab</link>
        <title>Push Container to Registry in GitLab</title>
        <description></description>
        <content:encoded><![CDATA[<h2 id="generate-personal-access-token-for-docker-login">Generate Personal Access Token for Docker Login</h2>

<p>Navigate over to the <a href="https://gitlab.com/profile/personal_access_tokens">access token</a> section in your profile.</p>

<p>Scope to <code>api</code> and set your expiration date.</p>

<p><em>store this key in your favorite password vault as it is not accessible after the generation process</em></p>

<h2 id="docker-login">docker login</h2>
<div class="highlight"><pre><span></span>docker login registry.gitlab.com

username: <span class="o">{</span>your username <span class="k">for</span> gitlab<span class="o">}</span>
password: <span class="o">{</span>the access toke you just crated<span class="o">}</span>
</pre></div>
<h2 id="build-and-push-your-image">build and push your image</h2>
<div class="highlight"><pre><span></span><span class="nb">cd</span> site <span class="o">&amp;&amp;</span> bundle <span class="nb">exec</span> jekyll build
<span class="nb">cd</span> ..
docker build . -t registry.gitlab.com/markcoleman/vikingmill:1.0 -t registry.gitlab.com/markcoleman/vikingmill:latest
docker push registry.gitlab.com/markcoleman/vikingmill
</pre></div>
<p><em>tagged via a version and also latest</em></p>

<h2 id="container-registry">Container Registry</h2>

<p><img alt="Silvrback blog image " src="https://silvrback.s3.amazonaws.com/uploads/959007ea-aae0-4788-9dc3-463e7d4c8fe7/Screen%20Shot%202019-07-28%20at%2011.55.18%20AM.png" /></p>
]]></content:encoded>
      </item>
      <item>
        <guid>http://kramnameloc.com/setting-up-a-gitlab-pipeline#47576</guid>
          <pubDate>Sat, 27 Jul 2019 11:38:19 -0400</pubDate>
        <link>http://kramnameloc.com/setting-up-a-gitlab-pipeline</link>
        <title>Setting Up a GitLab Pipeline</title>
        <description></description>
        <content:encoded><![CDATA[<p>I have been slowly exploring the free tier of <a href="https://www.gitlab.com">gitlab</a> and today wanted to setup a build in the <code>CI</code> job.  The following steps are taken to create a build of a static site via jekyll. </p>

<h2 id="create-gitlab-ci-yml">Create <code>.gitlab-ci.yml</code></h2>
<div class="highlight"><pre><span></span>touch .gitlab-ci.yml 
</pre></div>
<h3 id="edit-the-file">Edit the file</h3>

<p>As with any build script I simply put the steps I ran locally and placed them into the <code>yml</code> file.</p>
<div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">image</span><span class="p p-Indicator">:</span> <span class="s">&quot;ruby:2.5&quot;</span>
<span class="l l-Scalar l-Scalar-Plain">build</span><span class="p p-Indicator">:</span>
  <span class="l l-Scalar l-Scalar-Plain">script</span><span class="p p-Indicator">:</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">cd ./site/ &amp;&amp; bundle install</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">bundle exec jekyll build</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">zip -r site-build.zip ./_site</span>
</pre></div>
<p><em>note, unlike circleci each script execution will persist directory structure, e.g. <code>cd site</code> now puts you in the <code>site</code> folder for any  proceeding script items.</em></p>

<h3 id="the-first-error">The first Error</h3>
<div class="highlight"><pre><span></span>$ zip -r site-build.zip ./_site
/bin/bash: line <span class="m">90</span>: zip: <span class="nb">command</span> not found
</pre></div>
<p>It appears our image does not contain, <code>zip</code> so we will need to install it via a <code>before_script</code> block.</p>
<div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">image</span><span class="p p-Indicator">:</span> <span class="s">&quot;ruby:2.5&quot;</span>
<span class="l l-Scalar l-Scalar-Plain">before_script</span><span class="p p-Indicator">:</span>
  <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">apt-get install -y p7zip</span>
<span class="l l-Scalar l-Scalar-Plain">build</span><span class="p p-Indicator">:</span>
  <span class="l l-Scalar l-Scalar-Plain">script</span><span class="p p-Indicator">:</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">cd ./site/ &amp;&amp; bundle install</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">ls</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">bundle exec jekyll build</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">zip -r site-build.zip ./_site</span>
</pre></div>
<h3 id="another-error">Another Error</h3>
<div class="highlight"><pre><span></span>root@item:/# apt-get install p7zip
Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package p7zip
</pre></div>
<p>I learned that since this is a fresh image you also need to run the <code>update</code> command first.</p>
<div class="highlight"><pre><span></span>image: <span class="s2">&quot;ruby:2.5&quot;</span>
before_script:
  - apt-get update -qy
  - apt-get -y install zip unzip
</pre></div>
<p><em>Don&#39;t forget to add in <code>-y</code> to auto answer the prompt.</em></p>

<h3 id="the-final-build-yml-file">The final build <code>yml</code> file</h3>
<div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">image</span><span class="p p-Indicator">:</span> <span class="s">&quot;ruby:2.5&quot;</span>
<span class="l l-Scalar l-Scalar-Plain">before_script</span><span class="p p-Indicator">:</span>
  <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">apt-get update -qy</span>
  <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">apt-get -y install zip unzip</span>
<span class="l l-Scalar l-Scalar-Plain">build</span><span class="p p-Indicator">:</span>
  <span class="l l-Scalar l-Scalar-Plain">script</span><span class="p p-Indicator">:</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">cd ./site/ &amp;&amp; bundle install</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">bundle exec jekyll build</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">zip -r site-build.zip ./_site</span>
</pre></div>
<h2 id="artifacts">Artifacts</h2>

<p>Now we have all of your pieces in order and our build is successful next up getting an <a href="https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html">artifact</a> of the build which happens to be the rendered site from <code>jekyll</code>.</p>

<h3 id="storing-the-contents-of-the-zip-as-an-artifact">Storing the contents of the zip as an artifact</h3>
<div class="highlight"><pre><span></span>  artifacts:
    name: <span class="s2">&quot;viking-mill&quot;</span>
    paths:
      - ./site/site-build.zip
    expire_in: <span class="m">30</span> days
</pre></div>
<p><em>note, this new block will reset to the root working folder so you need to specify the full path from the root</em></p>

<h2 id="the-final-gitlab-ci-yml">The Final <code>.gitlab-ci.yml</code></h2>
<div class="highlight"><pre><span></span><span class="l l-Scalar l-Scalar-Plain">image</span><span class="p p-Indicator">:</span> <span class="s">&quot;ruby:2.5&quot;</span>
<span class="l l-Scalar l-Scalar-Plain">before_script</span><span class="p p-Indicator">:</span>
  <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">apt-get update -qy</span>
  <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">apt-get -y install zip unzip</span>
<span class="l l-Scalar l-Scalar-Plain">build</span><span class="p p-Indicator">:</span>
  <span class="l l-Scalar l-Scalar-Plain">script</span><span class="p p-Indicator">:</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">cd ./site/ &amp;&amp; bundle install</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">bundle exec jekyll build</span>
    <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">zip -r site-build.zip ./_site</span>
  <span class="l l-Scalar l-Scalar-Plain">artifacts</span><span class="p p-Indicator">:</span>
    <span class="l l-Scalar l-Scalar-Plain">name</span><span class="p p-Indicator">:</span> <span class="s">&quot;viking-mill&quot;</span>
    <span class="l l-Scalar l-Scalar-Plain">paths</span><span class="p p-Indicator">:</span>
      <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">./site/site-build.zip</span>
    <span class="l l-Scalar l-Scalar-Plain">expire_in</span><span class="p p-Indicator">:</span> <span class="l l-Scalar l-Scalar-Plain">30 days</span>
</pre></div>
<h2 id="finish">Finish</h2>

<p>Now we have a build setup inside of gitlab for the static jekyll site</p>
]]></content:encoded>
      </item>
  </channel>
</rss>