<?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: Javin Lacson</title>
    <description>The latest articles on DEV Community by Javin Lacson (@jiadar).</description>
    <link>https://dev.to/jiadar</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%2F310325%2Fe606fec7-ba2a-4ad6-ac02-0a0dbbf403e2.png</url>
      <title>DEV Community: Javin Lacson</title>
      <link>https://dev.to/jiadar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jiadar"/>
    <language>en</language>
    <item>
      <title>Exploring JSON API data from Node REPL</title>
      <dc:creator>Javin Lacson</dc:creator>
      <pubDate>Sun, 16 Feb 2020 00:29:54 +0000</pubDate>
      <link>https://dev.to/jiadar/exploring-json-api-data-from-node-repl-39a7</link>
      <guid>https://dev.to/jiadar/exploring-json-api-data-from-node-repl-39a7</guid>
      <description>&lt;p&gt;When just starting out at web programming, it is good to understand the underlying data transport format - JSON and how to interact with it. For this we will use some json data from reddit.&lt;/p&gt;

&lt;p&gt;Start up a new directory with a node project and install the JSON library. Then download the json data from reddit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir json_demo
cd json_demo
npm init
npm install JSON --save
wget https://www.reddit.com/r/videos.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's start an interactive session with node so that we can load the data and manipulate it. To do this, run &lt;code&gt;node&lt;/code&gt;. In the node REPL (read-eval-print loop), let's first import the fs and JSON modules which we need to read the file from the disk, and parse the data into an object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node
var fs = require('fs')
var JSON = require('JSON')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Next, let's read the data from the disk into a variable. We will see that videos is just a string, so we can't really use it that easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;videos = fs.readFileSync('videos.json', 'utf8')
typeof(videos)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Let's load the videos into an object with the JSON library. Now we see that videos_dict is a javascript object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;videos_dict = JSON.parse(videos)
typeof(videos_dict)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We can query the keys to travel into the object and find the data we want. Ultimately I'd like to print the URL's for all the videos. Let's go through the object, determining the type and keys, and descending through the keys until we get to the data we want. Ultimately we find the data at &lt;code&gt;videos_dict.data.children[n].data.url&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Object.keys(videos_dict)
typeof(videos_dict.data)
Object.keys(videos_dict.data)
typeof(videos_dict.data.children)
Object.keys(videos_dict.data.children)
typeof(videos_dict.data.children)
Object.keys(videos_dict.data.children[0])
typeof(videos_dict.data.children[0].data)
Object.keys(videos_dict.data.children[0].data)
videos_dict.data.children[0].data.url
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, map over the &lt;code&gt;videos_dict.data.children&lt;/code&gt; to print all the video URL's.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;videos_dict.data.children.map( (child) =&amp;gt; { return child.data.url } )
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For any arbitrary JSON from an unfamiliar API, you can easily explore the data and how to use it in your app! &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Connect Todoist with Postbox via Applescript</title>
      <dc:creator>Javin Lacson</dc:creator>
      <pubDate>Mon, 06 Jan 2020 23:15:40 +0000</pubDate>
      <link>https://dev.to/jiadar/connect-todoist-with-postbox-via-applescript-1kj1</link>
      <guid>https://dev.to/jiadar/connect-todoist-with-postbox-via-applescript-1kj1</guid>
      <description>&lt;p&gt;I use the GTD workflow for my task management, and until recently have been using Omnifocus on the Mac. I had Omnifocus set up with custom scripts to generate reports and receive events from other applications. It's not really built to be scriptable and doesn't provide easy access to the underlying data. It also only works well on my desktop.&lt;/p&gt;

&lt;p&gt;Due to these shortcomings, I decided to take the plunge and try &lt;a href="https://todoist.com/r/javin_lacson_bsbfug"&gt;Todoist&lt;/a&gt;. The main reason for this decision is the ability to leverage the API. One of the things I liked about Omnifocus is that can be scripted even if it's not that easy. &lt;a href="https://todoist.com/r/javin_lacson_bsbfug"&gt;Todoist&lt;/a&gt;, with the API, provides similar capabilities in a much more straightforward fashion. However, there was one missing feature - a seamless link to add Postbox messages to &lt;a href="https://todoist.com/r/javin_lacson_bsbfug"&gt;Todoist&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In the paid version of &lt;a href="https://todoist.com/r/javin_lacson_bsbfug"&gt;Todoist&lt;/a&gt;, you can get a unique email address to forward your emails as todo items. This doesn't really work with Inbox Zero and GTD, as if you add an email todo to reply later, you'd then have to go search for that email. It creates quite a bit of friction. To eliminate that, Postbox provides a link that will open the email directly in Postbox. The idea is that when you are going through your todo list processing emails saved for later, you can click the todo and end up right in the message. Meanwhile, you can archive the message and have Inbox Zero knowing that there's an item linking back to it in your todo list. &lt;/p&gt;

&lt;h3&gt;
  
  
  What do we want
&lt;/h3&gt;

&lt;p&gt;To that end, I'd like to have a hotkey in Postbox to do this when I'm reading a message that generates a todo. The hotkey would copy the message subject and link back to it in my todo list. After that, it would automatically archive the message, clearing it from my inbox. All in all, this is possible with a few quick lines of applescript and a few hours of fighting with Mojave sandbox security and permissions. &lt;/p&gt;

&lt;h3&gt;
  
  
  Automate The Things
&lt;/h3&gt;

&lt;p&gt;First, get the &lt;a href="https://github.com/sachaos/todoist"&gt;todoist CLI&lt;/a&gt; and set that up. I alias this to a shell command "td".&lt;/p&gt;

&lt;p&gt;Create a bash script to add the todo. Name this add.sh and make it executable. The script takes 2 arguments - the subject of the message and the link.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
/usr/local/bin/td add &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;](&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt; &amp;amp;
&lt;span class="nb"&gt;echo &lt;/span&gt;Todo scheduled &lt;span class="k"&gt;for &lt;/span&gt;addition
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Open automator and create a new quick action. Use the applescript automation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight applescript"&gt;&lt;code&gt;&lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="nb"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Postbox"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;emailMessage&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;messageURL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;URL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;emailMessage&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;messageSubject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;subject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;emailMessage&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Postbox"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;activate&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;application&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"System Events"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nv"&gt;keystroke&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;tell&lt;/span&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nb"&gt;do shell script&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/path/to/add.sh "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;messageSubject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\""&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;messageURL&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"\""&lt;/span&gt;&lt;span class="w"&gt;


    &lt;/span&gt;&lt;span class="nb"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;run&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Replace the path to your add.sh script. Save this and recall the name, I used AddTodoFromMessageAction. &lt;/p&gt;

&lt;h3&gt;
  
  
  Hotkeys and Permissions
&lt;/h3&gt;

&lt;p&gt;Set up a hotkey. Go to Apple -&amp;gt; Settings -&amp;gt; Keyboard -&amp;gt; Shortcuts. Select Services and under General you should see your automation. Select this and set up a hotkey shortcut. I used command + D. You will need to pick a shortcut that is not used by Postbox. &lt;/p&gt;

&lt;p&gt;Finally, set up the permissions. Go to Apple -&amp;gt; Settings -&amp;gt; Security and Privacy -&amp;gt; Privacy -&amp;gt; Accessibility. Add Automator and Postbox from applications and add System Events from HD -&amp;gt; System -&amp;gt; Core Services. &lt;/p&gt;

&lt;p&gt;Test in postbox with your shortcut. Accept the security dialogs to allow the automation, it will only ask once. &lt;/p&gt;

&lt;p&gt;This was written for Mojave 10.14.6. If it doesn't work, test the components up the stack in this order: Todoist CLI, Bash script, Applescript stand alone, then Automator script. &lt;/p&gt;

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