<?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: Claire Froelich</title>
    <description>The latest articles on DEV Community by Claire Froelich (@clairefro).</description>
    <link>https://dev.to/clairefro</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%2F396936%2Fb425c6ee-c5f9-4780-9e8b-5e905ddad830.png</url>
      <title>DEV Community: Claire Froelich</title>
      <link>https://dev.to/clairefro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/clairefro"/>
    <language>en</language>
    <item>
      <title>Free automated backups of Obsidian notes to GDrive for Mac, Windows and Linux</title>
      <dc:creator>Claire Froelich</dc:creator>
      <pubDate>Mon, 18 Dec 2023 14:34:55 +0000</pubDate>
      <link>https://dev.to/clairefro/free-automated-backups-of-obsidian-notes-to-gdrive-for-mac-windows-and-linux-40bh</link>
      <guid>https://dev.to/clairefro/free-automated-backups-of-obsidian-notes-to-gdrive-for-mac-windows-and-linux-40bh</guid>
      <description>&lt;p&gt;No one wants to lose all their years of note-taking to a spilled cup of coffee on the keyboard.&lt;/p&gt;

&lt;p&gt;Obsidian has a robust paid &lt;a href="https://obsidian.md/sync"&gt;Obsidian Sync&lt;/a&gt; proprietary service that enables two-way sync between devices both on and offline, version history and end-to-end encryption. If these features are important to you, I recommend this service. &lt;/p&gt;

&lt;p&gt;However, if you just want simple free, automated backups of your local notes to GDrive you have options.  &lt;/p&gt;

&lt;p&gt;These solutions are scalable in that they only sync file changes and do not copy your entire vault every time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free backups for Mac/Windows
&lt;/h2&gt;

&lt;p&gt;Luckily this one is easy. Google has a free &lt;a href="https://support.google.com/drive/answer/10838124?hl=en#zippy=%2Copen-drive-for-desktop%2Cdownload-drive-for-desktop"&gt;Google Drive for Desktop&lt;/a&gt; client available for these operating systems that enables automated real-time, two-way syncing of local directories on your computer.&lt;/p&gt;

&lt;p&gt;Once installed, follow &lt;a href="https://support.google.com/drive/answer/10838124?hl=en#zippy=%2Csync-a-folder-with-google-drive-or-google-photos"&gt;these instructions&lt;/a&gt; to sync your vault folder to GDrive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Free backups for Linux
&lt;/h2&gt;

&lt;p&gt;Unfortunately there is no Google Drive for Desktop client for Linux today. Here is something I hacked together using &lt;a href="https://freefilesync.org/"&gt;FreeFileSync&lt;/a&gt; and a shell script run on a 5 minute cron job. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note&lt;/strong&gt; FreeFileSync does not encrypt your files. If that is important to you, check out &lt;a href="https://freefilesync.org/forum/viewtopic.php?t=9682"&gt;this thread&lt;/a&gt; for some solutions.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install &lt;a href="https://freefilesync.org/download.php"&gt;FreeFileSync&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This tool can be used 100% free for the purposes of this article. &lt;/p&gt;

&lt;p&gt;Consider downloading the &lt;a href="https://freefilesync.org/download.php"&gt;Donation version&lt;/a&gt; with some extra thank-you features if you appreciate their service.&lt;/p&gt;

&lt;p&gt;Don't be fooled by the malwaresque look of their website. The service is great, community is friendly, and I haven't been frauded yet since making a donation.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create a new sync configuration
&lt;/h3&gt;

&lt;p&gt;Open FreeFileSync and create a "New" sync configuration from the upper left. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dFiERJZa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fih0rda5ynxjue79wjz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dFiERJZa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1fih0rda5ynxjue79wjz.png" alt="Image description" width="318" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Configure source and destination directories
&lt;/h3&gt;

&lt;p&gt;On the left, select the directory of your Obsidian vault.&lt;/p&gt;

&lt;p&gt;On the right, click the cloud icon to configure a connection to your GDrive &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---mQBHS4h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vg4xo9n7pdc6pnetpqst.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---mQBHS4h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vg4xo9n7pdc6pnetpqst.png" alt="Image description" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you click the cloud icon, a connection menu will appear. Authorize a connection to your GDrive, select which drive you will save to, and select a destination directory. &lt;/p&gt;

&lt;p&gt;By default, it will sync to the root of your drive - this is messy! I recommend specifying a destination directory for your vault files, (you can create one if it doesn't exist yet). I named mine the same as my local vault, "claire-thinkpad"&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3mOoInr4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t9crtb9d1gzpygihauf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3mOoInr4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t9crtb9d1gzpygihauf.png" alt="Image description" width="638" height="714"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once set up, your configure screen should look something like below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QrURgOQ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ei4oz0xsbjw4lwz135zb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QrURgOQ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ei4oz0xsbjw4lwz135zb.png" alt="Image description" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;FreeFileSync lets you set the sync mode to "mirror" (one-way, left to right), or &lt;a href="https://freefilesync.org/manual.php?topic=synchronization-settings"&gt;other sync modes&lt;/a&gt; such as "two-way", which in theory would enable you to pull changes from GDrive and share work across multiple devices. I didn't try two-way sync yet - comment if you do and find it useful!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Save configuration as a batch job
&lt;/h3&gt;

&lt;p&gt;Once you have your source and destination directories selected, click "Save as" in the upper left&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YGDi_-M3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwwv9xprp2wmy5oo6p1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YGDi_-M3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qwwv9xprp2wmy5oo6p1r.png" alt="Image description" width="291" height="153"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Accept the defaults and click Save as&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lFgyMMEr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fls58d87uluovkt5r3l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lFgyMMEr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fls58d87uluovkt5r3l.png" alt="Image description" width="656" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save the &lt;code&gt;.ffs_batch&lt;/code&gt; file inside your vault. For me that was  &lt;code&gt;~/Documents/claire-thinkpad&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Y6I5HRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nod9hgw475y9xz4qq71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Y6I5HRh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1nod9hgw475y9xz4qq71.png" alt="Image description" width="800" height="572"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Create the backup script
&lt;/h3&gt;

&lt;p&gt;First create a shell script file that will execute the sync.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;touch ~/cron/backup.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can call it something other than &lt;code&gt;backup.sh&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Paste the below script in the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;ping &lt;span class="nt"&gt;-c&lt;/span&gt; 1 google.com &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
  &lt;span class="c"&gt;# Internet is up, run batch job via FreeFileSync&lt;/span&gt;
  &lt;span class="nb"&gt;env &lt;/span&gt;&lt;span class="nv"&gt;DISPLAY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;:1.0 /usr/local/bin/FreeFileSync /home/claire/Documents/claire-thinkpad/SyncSettings.ffs_batch
&lt;span class="k"&gt;else&lt;/span&gt;
  &lt;span class="c"&gt;# Internet is down, do not run cron job&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Replace &lt;code&gt;/home/claire/Documents/claire-thinkpad/SyncSettings.ffs_batch&lt;/code&gt; with the path to your &lt;code&gt;.ffs_batch&lt;/code&gt; file&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The script checks whether you are connected to the internet by pinging google.com. If true, it will execute a headless run of your batch job via FreeFileSync. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;I was saved here by Joe Lotz's &lt;a href="https://www.joelotz.com/blog/2020/running-freefilesync-backup-from-crontab-on-ubuntu.html"&gt;post&lt;/a&gt; about running background jobs with FreeFileSync. The &lt;code&gt;DISPLAY=:1.0&lt;/code&gt; is the trick Joe found to run this headlessly, without opening the GUI.&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Test your script
&lt;/h4&gt;

&lt;p&gt;Run &lt;code&gt;~/cron/backup.sh&lt;/code&gt; and then check your GDrive destination folder and see that your files are there. Make sure your local vault is not empty first.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Create a cron job to execute your script
&lt;/h3&gt;

&lt;p&gt;In your terminal, run &lt;code&gt;crontab -e&lt;/code&gt; to enter the cron editor.&lt;/p&gt;

&lt;p&gt;Add this cron job at the bottom of the file :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt;/5 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /home/claire/cron/backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Replace &lt;code&gt;home/claire/cron/backup.sh&lt;/code&gt; with the path to your shell script from step 5&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This will run your backup script every 5 minutes. Feel free to change to a desired interval, with the help of a &lt;a href="https://crontab.guru/"&gt;cron editor tool&lt;/a&gt; or ChatGPT. &lt;/p&gt;

&lt;h2&gt;
  
  
  There you have it
&lt;/h2&gt;

&lt;p&gt;Your changed files should now sync every 5 minutes, so long as you have internet connection.&lt;/p&gt;

&lt;p&gt;Technically, instead of FreeFileSync you could code up your own diff calculator and Google Drive API calls to post changes directly to Google Drive. The benefit of using FreeFileSync is that it will calculate diffs for you out of the box and handle all the Google Drive API logic. Google APIs are not fun.&lt;/p&gt;

</description>
      <category>obsidian</category>
      <category>backup</category>
      <category>automation</category>
      <category>shell</category>
    </item>
    <item>
      <title>Quick HTML/CSS hack for prettier Japanese titles</title>
      <dc:creator>Claire Froelich</dc:creator>
      <pubDate>Tue, 23 Nov 2021 18:43:37 +0000</pubDate>
      <link>https://dev.to/clairefro/quick-htmlcss-hack-for-prettier-japanese-titles-3bnb</link>
      <guid>https://dev.to/clairefro/quick-htmlcss-hack-for-prettier-japanese-titles-3bnb</guid>
      <description>&lt;p&gt;As you read this article in English, look at the end of each line of text. You can thank the &lt;code&gt;&amp;lt;space&amp;gt;&lt;/code&gt; character for cleanly separating words into unbreakable chunks that aren't interrupted by newlines. &lt;strong&gt;English: words trump newlines&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Japanese does not use spaces, in general. Humans that read Japanese just have a 'spidey sense' of where words start and stop based on grammar and context.&lt;/p&gt;

&lt;p&gt;For large blocks of text like the body of articles, it is common for multi-character "words" to be split at newlines. This is OK:  characters are mono-spaced and paragraphs keep an aesthetically pleasing blockiness. &lt;strong&gt;Japanese: newlines trump words&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rxw6iEJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y196s8ad8mhvbej0vjva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rxw6iEJx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y196s8ad8mhvbej0vjva.png" alt="Image description" width="800" height="712"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;From Asahi Shimbun (text in bottom section is read top-to-bottom, right-to-left).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note above how each newline breaks in the same spot, regardless of position in the word. No hyphens necessary in Japanese! &lt;/p&gt;

&lt;p&gt;While “newlines trump words” looks nice in large blocks of text, it looks awkward on lonely one-line text like titles.&lt;/p&gt;

&lt;p&gt;For example, this text "Learn body parts":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;体の部分を学ぶ&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oewlsALY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfnqz2ebmi113lk1xha9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oewlsALY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfnqz2ebmi113lk1xha9.gif" alt="Image description" width="800" height="519"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Default "PEZ dispenser" behavior&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without a space character or hyphen telling the browser where to delimit words, the default behavior is to just pop characters off one-by-one like PEZ candies in a PEZ dispenser.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the English equivalent of what's happening on resize:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Learn body part
s
Learn body par
ts
Learn body pa
rts
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can we agree this is ugly and unreadable?&lt;/p&gt;

&lt;p&gt;To prevent PEZ dispensing and force compound characters to stick together in this Japanese title, you'll want to wrap the desired chunks in display: &lt;code&gt;inline-block&lt;/code&gt; style.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;体の&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;部分を&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"w"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;学ぶ&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- 

CSS style:

.w {
  display: inline-block;
}

--&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HhMDC8bx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8f4vdtcc6o4zynj69bhf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HhMDC8bx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8f4vdtcc6o4zynj69bhf.gif" alt="Image description" width="800" height="535"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Not PEZ dispensing&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Much better!&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate it!
&lt;/h2&gt;

&lt;p&gt;This solution is fine quick fix for the occasional eye-catching title, but requires knowledge of Japanese grammar to know where to put the &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;Fortunately there is a cool tool called &lt;a href="https://medium.com/r/?url=https%3A%2F%2Fgithub.com%2Fgoogle%2Fbudou"&gt;Budou&lt;/a&gt; that automates this formatting. You don't even have to know Japanese - it uses AI to semantically parse text into words and insert the spans for you (it works for Chinese and Korean too!).&lt;/p&gt;

&lt;p&gt;This has been the first of what will probably be many articles on "things I overlooked when translating my website into Japanese".&lt;/p&gt;




&lt;p&gt;See the pretty Japanese line-wrapping in action on my children's book website: &lt;a href="https://www.power-of-vegetables.com/ja"&gt;The Power of Vegetables&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Deer illustrations in GIFs by &lt;a href="https://www.instagram.com/Fbarbara.fomina"&gt;Varvara Fomina&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://medium.com/@clairefroelich/quick-html-css-hack-for-prettier-japanese-titles-fb4ce3d41309"&gt;Medium&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>html</category>
      <category>css</category>
      <category>typography</category>
      <category>japanese</category>
    </item>
    <item>
      <title>Automate daily Tweets with Postman and the Twitter API v2 🌞</title>
      <dc:creator>Claire Froelich</dc:creator>
      <pubDate>Sun, 14 Nov 2021 03:23:39 +0000</pubDate>
      <link>https://dev.to/clairefro/automate-daily-tweets-with-postman-and-the-twitter-api-v2-4gg9</link>
      <guid>https://dev.to/clairefro/automate-daily-tweets-with-postman-and-the-twitter-api-v2-4gg9</guid>
      <description>&lt;p&gt;Has your Twitter feed been blowing up with "gm's" lately?&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1459628182810857481-72" src="https://platform.twitter.com/embed/Tweet.html?id=1459628182810857481"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1459628182810857481-72');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1459628182810857481&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;If you're not in the know, this is &lt;a href="https://www.one37pm.com/nft/art/nft-twitter-meanings-definitions" rel="noopener noreferrer"&gt;crypto speak&lt;/a&gt; for "good morning", and is a customary way web3 and crypto nerds clock in for the day.&lt;/p&gt;

&lt;p&gt;Do you always forget to gm? Do you not care but want to give the illusion you're hip and GMI? Use &lt;a href="https://postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; monitors with the &lt;a href="https://developer.twitter.com/en/docs/twitter-api" rel="noopener noreferrer"&gt;Twitter API v2&lt;/a&gt; to automate posting your daily salute to Twitter. &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Get a Twitter Developer account
&lt;/h2&gt;

&lt;p&gt;On top of a normal Twitter account, you will need to set up a free Twitter developer account &lt;a href="https://developer.twitter.com/en/apply-for-access" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Make a hobbyist account and explain that you will use your account to post your own tweets. Part of your on-boarding will be to "create a project". &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Create an App
&lt;/h2&gt;

&lt;p&gt;Once you have your developer account and project set up in your &lt;a href="https://developer.twitter.com/en/portal/dashboard" rel="noopener noreferrer"&gt;Twitter developer dashboard&lt;/a&gt;, you need to add an App to your project in order to use the API. &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%2Fiki61m5ht3kz4jcs5vlh.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%2Fiki61m5ht3kz4jcs5vlh.png" alt="Adding an app to a project in the Twitter developer dashabord"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give your new app a name&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%2Fxvmnnu89f8jqfz8t2jxp.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%2Fxvmnnu89f8jqfz8t2jxp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Get your secrets
&lt;/h2&gt;

&lt;p&gt;Next you will be given some secrets. Treat these credentials like passwords and store them somewhere secure. The keys are hidden in this image, but you'll see 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%2Fkz1wam2ulgjmchn59aud.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%2Fkz1wam2ulgjmchn59aud.png" alt="Copy the API Key, API Key Secret, and Bearer token for your new app"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Give your app read and write permissions
&lt;/h2&gt;

&lt;p&gt;You need to enable your app to post tweets on your behalf. Go to your app's "Settings" tab and click the button to edit the App permissions.&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%2F8oamqh4oqqlzfcrpi4gv.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%2F8oamqh4oqqlzfcrpi4gv.png" alt="Edit app permissions in Twitter dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the app permissions from "Read" to "Read and write". Click save to apply the changes.&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%2Fz1qop8vys9fgr1ktf162.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%2Fz1qop8vys9fgr1ktf162.png" alt="Update app permissions from "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Generate additional credentials
&lt;/h2&gt;

&lt;p&gt;You will also need to securely jot down an &lt;strong&gt;Access Token&lt;/strong&gt; and &lt;strong&gt;Access Token Secret&lt;/strong&gt;, which can be generated in your app's "Keys and tokens" tab. &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%2Fykadtzpeectem4a57ymt.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%2Fykadtzpeectem4a57ymt.png" alt="Generate Access Token and Access Token Secret for your app in the Twitter dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the generated token and token secret with your other secrets. These are the final credentials we need to authorize requests to the Twitter API. &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%2Fs5nqb35nt6h7hgn0mybr.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%2Fs5nqb35nt6h7hgn0mybr.png" alt="Copy the generated Access Token and Access Token Secret"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Log in to Postman
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.postman.com/" rel="noopener noreferrer"&gt;Postman&lt;/a&gt; is a free tool for building, consuming, testing, documenting, and monitoring APIs. You can create a free account &lt;a href="https://postman.com" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Once you have an account you can access the tool from the browser without downloading anything, simply by  going to &lt;a href="https://postman.com" rel="noopener noreferrer"&gt;https://postman.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Create a personal workspace
&lt;/h2&gt;

&lt;p&gt;To make API requests in Postman, first you need a workspace. You can create a workspace from the "Workspaces" dropdown. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; The workspace visibility should be set to &lt;strong&gt;Personal&lt;/strong&gt;, since we will be storing our secret keys in a way that would make them visible if the workspace were public. &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%2Fc7puw8g7fsk1bwv1lmbt.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%2Fc7puw8g7fsk1bwv1lmbt.png" alt="Create a new workspace in Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Create a collection
&lt;/h2&gt;

&lt;p&gt;In Postman, API requests live inside &lt;strong&gt;Collections&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Create a collection either with the "Create a collection" button, or the plus "+" icon in the collections tab. Name your collection &lt;code&gt;Twitter API v2&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Add a request to post Tweets
&lt;/h2&gt;

&lt;p&gt;Now we can build a request to the Twitter API that will post a tweet on your behalf. First, "Add a request", and name it &lt;code&gt;post a tweet&lt;/code&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%2Fn2v63cxkhqlyrlxeuzox.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%2Fn2v63cxkhqlyrlxeuzox.png" alt="Add a request in Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the Twitter API v2
&lt;/h3&gt;

&lt;p&gt;We will use this endpoint in the Twitter API v2 to tweet: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;POST https://api.twitter.com/2/tweets&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can read more about it &lt;a href="https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets" rel="noopener noreferrer"&gt;here in the docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Paste this endpoint into the request URL in Postman, and set the request method to &lt;code&gt;POST&lt;/code&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%2Fwmlyk0dmyqj5c1rzifv3.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%2Fwmlyk0dmyqj5c1rzifv3.png" alt="Update the request method and URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a body to your request
&lt;/h3&gt;

&lt;p&gt;The Twitter API v2 expects a JSON body, where a &lt;code&gt;text&lt;/code&gt; property is the text content of your tweet. &lt;/p&gt;

&lt;p&gt;In the "Body" tab of your request in Postman, select "raw" &amp;gt; "JSON" as the datatype and paste this JSON data in the body:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gm"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fe55yhuyf64ursg1ztrao.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%2Fe55yhuyf64ursg1ztrao.png" alt="Build Tweet request in Postman"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Authorize your request
&lt;/h3&gt;

&lt;p&gt;You can't just go tweeting as anybody. In order to tweet you will need to authorize your request with your credentials. &lt;/p&gt;

&lt;p&gt;This endpoint accepts OAuth 1.0 authorization. We can use Postman's "Authorization" tab on the request to set this up. Select OAuth 1.0 as the Authorization type.  &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%2Fwmhrn9lvvjcip830d3bd.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%2Fwmhrn9lvvjcip830d3bd.png" alt="Select OAuth1 as the Authorization type for this request"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, make sure the request is set up to add the authorization data to the "Request Headers": &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%2Fi66vzsnkkf20w7ihxztc.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%2Fi66vzsnkkf20w7ihxztc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the right, we will enter our Twitter app credentials: &lt;strong&gt;API Key&lt;/strong&gt;, &lt;strong&gt;API Key Secret&lt;/strong&gt;, &lt;strong&gt;Access Token&lt;/strong&gt;, and &lt;strong&gt;Access Token Secret&lt;/strong&gt; for the fields &lt;strong&gt;Consumer Key&lt;/strong&gt;, &lt;strong&gt;Consumer Secret&lt;/strong&gt;, &lt;strong&gt;Access Token&lt;/strong&gt;, &lt;strong&gt;Token Secret&lt;/strong&gt;, respectively. Leave everything else as the default. &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%2Fga244qhslw2mjscyrgkp.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%2Fga244qhslw2mjscyrgkp.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: Usually you do not want to hard code sensitive data like this directly in the Authorization tab. &lt;/p&gt;

&lt;p&gt;Normally you should &lt;a href="https://learning.postman.com/docs/sending-requests/variables/" rel="noopener noreferrer"&gt;use variables&lt;/a&gt; to obscure your secrets. Variables defined only in the "Initial Value" column are local to your Postman app and won't be shared. &lt;/p&gt;

&lt;p&gt;However, in order to automate our tweets in a later step &lt;strong&gt;we need the secrets to be accessible by Postman servers in your workspace&lt;/strong&gt;. Be sure not to make your workspace public or people could steal your API credentials and tweet abuse your Twitter. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Save all your changes and send the request. In Postman you should get a status &lt;code&gt;201&lt;/code&gt; response from the Twitter API with the &lt;code&gt;id&lt;/code&gt; of your new Tweet. Go check out Twitter!&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%2F2ndcmklt67ssyr839nlj.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%2F2ndcmklt67ssyr839nlj.png" alt="Tweet from clairefroe with text "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Automate daily tweets in Postman
&lt;/h2&gt;

&lt;p&gt;Postman allows you to create &lt;a href="https://learning.postman.com/docs/monitoring-your-api/intro-monitors/" rel="noopener noreferrer"&gt;monitors&lt;/a&gt; that run your collections at specified intervals to alert you when your servers have caught on fire. &lt;/p&gt;

&lt;p&gt;This feature can double as a way to schedule cron jobs for running API calls, which is exactly what we'll do to run our &lt;code&gt;post a tweet&lt;/code&gt; request every morning. &lt;/p&gt;

&lt;h3&gt;
  
  
  Set up a Postman monitor
&lt;/h3&gt;

&lt;p&gt;In the same personal workspace you made, click the "Monitors" tab on the far left menu, then "Create a Monitor". &lt;/p&gt;

&lt;p&gt;Give your monitor a name. Select the collection you made and configure it to run every morning. Set it to a bright and early time to make yourself appear industrious ☕.  &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%2Fyyekfi8fkagd2keappyj.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%2Fyyekfi8fkagd2keappyj.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down and click the big orange "Create Monitor" button to set up the scheduled run. Give your monitor a test run by clicking the "Run" button manually - check your Twitter and make sure it works. &lt;/p&gt;

&lt;p&gt;Congratulations! Sit back and let the robots take over. &lt;/p&gt;

&lt;h2&gt;
  
  
  BONUS: Add random emojis for humanizing effect
&lt;/h2&gt;

&lt;p&gt;If you want to further hide the sham that you have a bot tweeting your gms, add a personalized random emoji to each tweet using scripts in Postman.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a pre-request script to get a random emoji
&lt;/h3&gt;

&lt;p&gt;Head back to the Collections tab in your workspace and click on the &lt;code&gt;post a tweet&lt;/code&gt; request. &lt;/p&gt;

&lt;p&gt;Open the "Pre-request Scripts" tab on the request. Any Node.js code we write in here will be executed right before our request is sent off. Paste in this code, but use any custom emojis that suit your personality:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emojis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🌞&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;💪&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🍠&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;🍵&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;emojiDeJour&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;emojis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;emojis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="nx"&gt;pm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;collectionVariables&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;emojiDeJour&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;emojiDeJour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To explain, first we are defining an array of emojis. Then we select a random emoji and assign it to the local variable &lt;code&gt;emojiDeJour&lt;/code&gt;. Finally we use Postman's &lt;a href="https://learning.postman.com/docs/writing-scripts/script-references/postman-sandbox-api-reference/#the-pm-object" rel="noopener noreferrer"&gt;&lt;code&gt;pm&lt;/code&gt; helper object&lt;/a&gt; to programmatically set our &lt;code&gt;emojiDeJour&lt;/code&gt; as a collection variable of the same name. This will allow us to access the &lt;code&gt;emojiDeJour&lt;/code&gt; in the body of our request. &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%2Frf9bih5ygecbp1kmccy2.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%2Frf9bih5ygecbp1kmccy2.png" alt="Postman pre-request script with code for selecting a random emoji from a list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add the emoji to our tweet in the request body
&lt;/h3&gt;

&lt;p&gt;Finally, interpolate the &lt;code&gt;emojiDeJour&lt;/code&gt; from the collection variables using Postman's &lt;code&gt;{{variable}}&lt;/code&gt; syntax with double curly braces. Update the request body to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gm {{emojiDeJour}}"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save your changes! Now each time request is sent you get a random emoji at the end of your tweet. I got sweet potato. &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%2Fvcinaxek45dth81exgzu.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%2Fvcinaxek45dth81exgzu.png" alt="Tweet with a sweet potato emoji sent using Postman and the Twitter API"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Postman monitors are a simple and free way to run scheduled API calls, making it easy to automate tweets using the Twitter API. Twitter has a fabulous API for interacting with the app, just take care your &lt;a href="https://developer.twitter.com/en/developer-terms/more-on-restricted-use-cases" rel="noopener noreferrer"&gt;use case is not prohibited&lt;/a&gt; before making automations. Also note that the Twitter API is &lt;a href="https://developer.twitter.com/en/docs/twitter-api/rate-limits" rel="noopener noreferrer"&gt;rate limited&lt;/a&gt; and you should make no more than 200 tweets via the API in a 15 minute window. But if you tweet that much you will have lost all your followers anyway.&lt;/p&gt;

&lt;p&gt;You can see a completed example of the Postman workspace &lt;a href="https://www.postman.com/claireman/workspace/automated-twitter-gms/overview" rel="noopener noreferrer"&gt;here&lt;/a&gt; (just make sure YOU make a personal workspace)&lt;/p&gt;

&lt;p&gt;gn 🌚&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I work for Postman, but the thoughts and promotion of gm culture in this article are my own.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postman</category>
      <category>twitter</category>
      <category>api</category>
      <category>web3</category>
    </item>
  </channel>
</rss>
