<?xml version="1.0" encoding="UTF-8"?><rss 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" version="2.0"><channel><title><![CDATA[Pratik Thakare's Blogs]]></title><description><![CDATA[Software Chef  | Full-Stack (BE Heavy) | Cloud Infrastructure & Scalability]]></description><link>https://blog.pratikthakare.com</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1703512152771/_oPgJZfpd.png</url><title>Pratik Thakare&apos;s Blogs</title><link>https://blog.pratikthakare.com</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 01:46:58 GMT</lastBuildDate><atom:link href="https://blog.pratikthakare.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[A Simple Guide to Configuring Per-Branch Preview URLs for Cloudflare Workers with Wrangler]]></title><description><![CDATA[Must

Domain with Cloudflare

Empty GitHub repository

Node.js


The Essence
Step 1: DNS record
Create an A, AAAA, or CNAME record with a placeholder value. The value here doesn’t really matter, as Cloudflare will internally determine which Worker wi...]]></description><link>https://blog.pratikthakare.com/a-simple-guide-to-configuring-per-branch-preview-urls-for-cloudflare-workers-with-wrangler</link><guid isPermaLink="true">https://blog.pratikthakare.com/a-simple-guide-to-configuring-per-branch-preview-urls-for-cloudflare-workers-with-wrangler</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[cloudflare-worker]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[dns]]></category><category><![CDATA[Wrangler]]></category><dc:creator><![CDATA[Pratik Thakare]]></dc:creator><pubDate>Thu, 13 Nov 2025 16:20:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/_Z0JGI6FGlA/upload/72c2ac087972ca482757afb526d2573f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-must">Must</h2>
<ol>
<li><p>Domain with Cloudflare</p>
</li>
<li><p>Empty GitHub repository</p>
</li>
<li><p>Node.js</p>
</li>
</ol>
<h2 id="heading-the-essence">The Essence</h2>
<h3 id="heading-step-1-dns-record">Step 1: DNS record</h3>
<p>Create an A, AAAA, or CNAME record with a <em>placeholder value</em>. The value here doesn’t really matter, as Cloudflare will internally determine which Worker will process these requests using the Worker Routes configuration.</p>
<p>However, what is important is making sure the record is “Proxied”; otherwise, the Worker Routes configuration won’t work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762988987882/36bb5d9e-e156-4d8b-afe6-bf5de61e166c.png" alt class="image--center mx-auto" /></p>
<p><em>Note: To know more about the</em> <a target="_blank" href="https://developers.cloudflare.com/dns/proxy-status/"><em>Cloudflare DNS Proxy</em></a><em>.</em></p>
<h3 id="heading-step-2-wrangler">Step 2: Wrangler</h3>
<p><em>“Wrangler, the Cloudflare Developer Platform command-line interface (CLI), allows you to manage Worker projects.”</em> — <a target="_blank" href="https://developers.cloudflare.com/workers/wrangler/">this page</a></p>
<p>If you don’t have wrangler globally installed, try <a target="_blank" href="https://developers.cloudflare.com/workers/wrangler/install-and-update/">this</a> and then perform the following commands:</p>
<pre><code class="lang-bash">pnpm create cloudflare@latest wrangler-works --<span class="hljs-built_in">type</span> hello-world --git --lang ts --deploy
<span class="hljs-built_in">cd</span> wrangler-works
git remote add origin &lt;empty-github-repo-url&gt;
git push
</code></pre>
<p><em>Note: I’m using</em> <code>pnpm</code> <em>because I own the t-shirt. You can, of course, use whichever package manager’s merch you’re wearing,</em> <code>npm</code><em>,</em> <code>yarn</code><em>, or otherwise.</em></p>
<p>You should be able to access the worker through the free subdomain provided by Cloudflare, which might look like <code>https://&lt;worker-name&gt;-&lt;your-account-subdomain&gt;.workers.dev</code>. <a target="_blank" href="https://developers.cloudflare.com/workers/configuration/routing/workers-dev/#limitations">Be careful with the worker naming!</a></p>
<h3 id="heading-step-3-association">Step 3: <strong>Association</strong></h3>
<p>Even though we can access the worker through <code>worker.dev</code> It is not advised to use this domain in production.</p>
<p>Find the file named <code>wrangler.jsonc</code> or <code>wrangler.toml</code> and add the following:</p>
<pre><code class="lang-json"><span class="hljs-comment">/**
 * For more details on how to configure Wrangler, refer to:
 * https://developers.cloudflare.com/workers/wrangler/configuration/
 */</span>
{
    ...
    <span class="hljs-attr">"workers_dev"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"preview_urls"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"routes"</span>: [
        {
            <span class="hljs-attr">"pattern"</span>: <span class="hljs-string">"journeyly.co/*"</span>,
            <span class="hljs-attr">"zone_name"</span>: <span class="hljs-string">"journeyly.co"</span>
        }
    ]
}
</code></pre>
<p>Follow that change up with deploying the worker with the new configuration:</p>
<pre><code class="lang-bash">pnpm run deploy
</code></pre>
<h3 id="heading-step-4-devops">Step 4: <strong>DevOps</strong></h3>
<p>Go to the Worker settings and connect the GitHub Repository. Just make sure <code>Builds for non-production branches</code> is turned on.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762992705505/1657de33-c2c5-4151-9f8c-f3f1f0f9911c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-5-assessment">Step 5: Assessment</h3>
<p>Follow these steps to test your setup:</p>
<ol>
<li><p>Make some changes to the <code>src/index.ts</code></p>
</li>
<li><p>Create a new branch</p>
</li>
<li><p>Commit the changes</p>
</li>
<li><p>Push to remote</p>
</li>
</ol>
<p>You should be able to see the following result on GitHub Actions when you click on the <strong>✅</strong> symbol on the latest commit of the new branch:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762993428760/4b9a9cda-9d5e-4ed1-887d-f42f41bc40e9.png" alt class="image--center mx-auto" /></p>
<p>If we go one step further and open a pull request to merge into main, Cloudflare will automatically run deployment checks and display a message showing the status of your preview deployment.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762993520815/1d843e79-eaaf-4258-9d14-32a1e1c479c8.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-bonus">Bonus</h2>
<p>Now, what you do with this is up to you! Here’s what I am using it for:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
    <span class="hljs-keyword">async</span> fetch(request, _env, _ctx): <span class="hljs-built_in">Promise</span>&lt;Response&gt; {
        <span class="hljs-keyword">const</span> country = request.headers.get(<span class="hljs-string">'CF-IPCountry'</span>) || <span class="hljs-string">'XX'</span>;

        <span class="hljs-keyword">switch</span> (country) {
            <span class="hljs-keyword">case</span> <span class="hljs-string">'IN'</span>:
                <span class="hljs-keyword">return</span> Response.redirect(<span class="hljs-string">'&lt;redacted&gt;'</span>, <span class="hljs-number">302</span>);
            <span class="hljs-keyword">default</span>:
                <span class="hljs-keyword">return</span> Response.redirect(<span class="hljs-string">'&lt;redacted&gt;'</span>, <span class="hljs-number">302</span>);
        }
    },
} satisfies ExportedHandler&lt;Env&gt;;
</code></pre>
<p>Feeling generous with your good vibes today? Awesome! I’d be thrilled if you could take a minute to fill out this quick <a target="_blank" href="https://interest.journeyly.co">form</a> for a project I’m working on. It would help me out so much! 🙌</p>
<p><strong>Salutations!</strong></p>
]]></content:encoded></item><item><title><![CDATA[How to setup another language for your keyboard on Arch Linux]]></title><description><![CDATA[I am trying to learn Japanese so that I can watch those "stupid cartoons" of mine without needing to read those pesky subtitles.
What do you need?

Language Fonts

Input Method (IM) and Input Method Editor (IME)

Input Method Framework (IMF)


How to...]]></description><link>https://blog.pratikthakare.com/how-to-setup-another-language-for-your-keyboard-on-arch-linux</link><guid isPermaLink="true">https://blog.pratikthakare.com/how-to-setup-another-language-for-your-keyboard-on-arch-linux</guid><category><![CDATA[Input Method]]></category><category><![CDATA[ArchLinux]]></category><dc:creator><![CDATA[Pratik Thakare]]></dc:creator><pubDate>Thu, 28 Dec 2023 14:36:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/LjqARJaJotc/upload/a7a6d5f4d4993a1afb96a05005e49960.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I am trying to learn Japanese so that I can watch those "stupid cartoons" of mine without needing to read those pesky subtitles.</p>
<h1 id="heading-what-do-you-need">What do you need?</h1>
<ol>
<li><p>Language Fonts</p>
</li>
<li><p>Input Method (IM) and Input Method Editor (IME)</p>
</li>
<li><p>Input Method Framework (IMF)</p>
</li>
</ol>
<h1 id="heading-how-to-get-them">How to get them?</h1>
<h2 id="heading-language-fonts">Language Fonts</h2>
<p>Here are the list of fonts that you can use:</p>
<ul>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=adobe-source-han-sans-jp-fonts"><strong>adobe-source-han-sans-jp-fonts</strong></a> - Japanese OpenType/CFF fonts, style Gothic (sans-serif).</p>
</li>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=adobe-source-han-serif-jp-fonts"><strong>adobe-source-han-serif-jp-fonts</strong></a> - Japanese OpenType/CFF fonts, style Mincho (serif).</p>
</li>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=noto-fonts-cjk"><strong>noto-fonts-cjk</strong></a> - Google Noto CJK fonts.</p>
</li>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=otf-ipafont"><strong>otf-ipafont</strong></a> - Formal style Japanese Gothic (sans-serif) and Mincho (serif) fonts set; one of the highest quality open source font. Default of openSUSE-ja.</p>
</li>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=otf-ipaexfont"><strong>otf-ipaexfont</strong></a> - An updated version of ipafont.</p>
</li>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=ttf-hanazono"><strong>ttf-hanazono</strong></a> - A free Japanese kanji font, style Mincho (serif).</p>
</li>
<li><p><a target="_blank" href="https://archlinux.org/packages/?name=ttf-sazanami"><strong>ttf-sazanami</strong></a> - Japanese free TrueType font. This is outdated and not maintained any more, but may be defined as a fallback font on several environments.</p>
</li>
<li><p><a target="_blank" href="https://aur.archlinux.org/packages/ttf-koruri/"><strong>ttf-koruri</strong></a><sup>AUR</sup> - Japanese TrueType font obtained by mixing <a target="_blank" href="https://aur.archlinux.org/packages/ttf-mplus/"><strong>ttf-mplus</strong></a><sup>AUR</sup> and Open Sans</p>
</li>
<li><p><a target="_blank" href="https://aur.archlinux.org/packages/ttf-monapo/"><strong>ttf-monapo</strong></a><sup>AUR</sup> - Japanese fonts to show <a target="_blank" href="https://en.wikipedia.org/wiki/2channel_Shift_JIS_art"><strong>2channel Shift JIS art</strong></a> properly.</p>
</li>
<li><p><a target="_blank" href="https://aur.archlinux.org/packages/ttf-mplus-git/"><strong>ttf-mplus-git</strong></a><sup>AUR</sup> - Modern Gothic style Japanese outline fonts. It includes all of Japanese Hiragana/Katakana, Basic Latin, Latin-1 Supplement, Latin Extended-A, IPA Extensions and most of Japanese Kanji, Greek, Cyrillic, Vietnamese with 7 weights (proportional) or 5 weights (monospace).</p>
</li>
<li><p><a target="_blank" href="https://aur.archlinux.org/packages/ttf-vlgothic/"><strong>ttf-vlgothic</strong></a><sup>AUR</sup> - Japanese Gothic fonts. Default of Debian/Fedora/Vine Linux</p>
</li>
<li><p><a target="_blank" href="https://aur.archlinux.org/packages/ttf-kanjistrokeorders/"><strong>ttf-kanjistrokeorders</strong></a><sup>AUR</sup> - KanjiStrokeOrders font that indicates the stroke order of characters.</p>
</li>
</ul>
<p>Here I am gonna go with..</p>
<pre><code class="lang-bash">sudo pacman -S noto-fonts-cjk noto-fonts-emoji noto-fonts
</code></pre>
<p>The <strong>Noto Font Family</strong> has everything that you will ever need, here we are just installing <code>noto-fonts-cjk</code> for Chinese, Japanese, and Korean fonts, <code>noto-fonts-emoji</code> for emoji fonts and <code>noto-fonts</code> for Latin fonts.</p>
<p>You can check out the entire font family <a target="_blank" href="https://fonts.google.com/noto">here</a>.</p>
<p><strong>Note: It is not necessary to install noto-fonts and noto-fonts-emoji packages for our diverse keyboard.</strong></p>
<h2 id="heading-locale">Locale</h2>
<p>Locales are used to correctly display regional or language/locale-specific standards. To ensure the Japanese locale is enabled, confirm that <code>ja_JP.utf8</code> is in the output of:</p>
<pre><code class="lang-bash">$ locale -a
</code></pre>
<p>To enable the Japanese locale, uncomment <code>ja_JP.utf8</code> in <code>/etc/locale.gen</code>:</p>
<pre><code class="lang-bash">/etc/locale.gen
</code></pre>
<pre><code class="lang-bash">...
<span class="hljs-comment">#ja_JP.EUC-JP EUC-JP  </span>
ja_JP.UTF-8 UTF-8  
<span class="hljs-comment">#ka_GE.UTF-8 UTF-8  </span>
...
</code></pre>
<p>Afterwards, regenerate your locale:</p>
<pre><code class="lang-bash">$ locale-gen
</code></pre>
<h2 id="heading-input-method-framework-imf">Input Method Framework (IMF)</h2>
<p>An <strong>Input Method Framework (IMF)</strong> is a software framework that facilitates the input of characters not directly supported by a keyboard. This is particularly important for languages with large character sets, such as Chinese, Japanese, and Korean, which often require more than the standard keyboard layout to input characters efficiently.</p>
<p>There are two options of IMF for us: <code>ibus</code> or <code>fcitx5</code>. We are going to go with <code>fcitx5</code>.</p>
<pre><code class="lang-bash">sudo pacman -S fcitx5-im
</code></pre>
<p>The <code>fcitx5-im</code> installs <code>fcitx</code>, <a target="_blank" href="https://archlinux.org/packages/extra/x86_64/fcitx5-configtool/"><code>fcitx5-configtool</code></a>, <a target="_blank" href="https://archlinux.org/packages/extra/x86_64/fcitx5-gtk/"><code>fcitx5-gtk</code></a>, and <a target="_blank" href="https://archlinux.org/packages/extra/x86_64/fcitx5-qt/"><code>fcitx5-qt</code></a>. This usually covers everything that you might need.</p>
<p>Once you are done installing you also need to add these environment variables</p>
<pre><code class="lang-bash">GTK_IM_MODULE=fcitx
QT_IM_MODULE=fcitx
XMODIFIERS=@im=fcitx
</code></pre>
<h2 id="heading-input-method-im-or-input-method-editor-ime">Input Method (IM) or Input Method Editor (IME)</h2>
<p>The <strong>Input Method (IM)</strong> and <strong>Input Method Editor (IME)</strong> refer to the methodology and implementation respectively but nowadays they are used interchangeably. In short, the IM refers to a particular way to use the keyboard to input a particular language, for example, the <a target="_blank" href="https://en.wikipedia.org/wiki/Cangjie_method">Cangjie method</a>, the <a target="_blank" href="https://en.wikipedia.org/wiki/Pinyin_method">pinyin method</a>, or the use of <a target="_blank" href="https://en.wikipedia.org/wiki/Dead_key">dead keys</a>. On the other hand, IME refers to the actual program that allows the implementation to be used.</p>
<p>We are going to go with mozc for fcitx which is <a target="_blank" href="https://archlinux.org/packages/extra/x86_64/fcitx5-mozc/">fcitx5-mozc</a>.</p>
<pre><code class="lang-bash">sudo pacman -S fcitx5-mozc
</code></pre>
<h1 id="heading-just-a-bit-more">Just A Bit More</h1>
<p>We are almost there, open <code>fcitx5-configtool</code> and search for <code>mozc</code>. Once you find it add it as an input method. Press <code>Ctrl + Space</code> — 役に立たないブログでした</p>
<h1 id="heading-references">References</h1>
<p>[1] <a target="_blank" href="https://wiki.archlinux.org/title/Input_method">https://wiki.archlinux.org/title/Input_method</a></p>
<p>[2] <a target="_blank" href="https://en.wikipedia.org/wiki/Input_method">https://en.wikipedia.org/wiki/Input_method</a></p>
<p>[3] <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Input_method_editor">https://developer.mozilla.org/en-US/docs/Glossary/Input_method_editor</a></p>
<p>[4] <a target="_blank" href="https://wiki.archlinux.org/title/Localization/Japanese">https://wiki.archlinux.org/title/Localization/Japanese</a></p>
<p>[5] <a target="_blank" href="https://medium.com/@ourhopeforfreedom/why-i-switched-from-ibus-to-fcitx5-c6950eb3ba9e">https://medium.com/@ourhopeforfreedom/why-i-switched-from-ibus-to-fcitx5-c6950eb3ba9e</a></p>
]]></content:encoded></item><item><title><![CDATA[Optimizing Productivity: A Step-by-Step Guide to Setting Up a Build Bot with Slack and AWS CodeBuild for Seamless Workflow]]></title><description><![CDATA[Why?
Continuous Integration and Continuous Delivery/Continuous Deployment a.k.a CI/CD; this ain’t it.
…
CI/CDs are great - update a branch through merge, perform a commit or a PR and the build request is sent instantly. A build is made and sent to yo...]]></description><link>https://blog.pratikthakare.com/optimizing-productivity-a-step-by-step-guide-to-setting-up-a-build-bot-with-slack-and-aws-codebuild-for-seamless-workflow</link><guid isPermaLink="true">https://blog.pratikthakare.com/optimizing-productivity-a-step-by-step-guide-to-setting-up-a-build-bot-with-slack-and-aws-codebuild-for-seamless-workflow</guid><category><![CDATA[AWS]]></category><category><![CDATA[cicd]]></category><category><![CDATA[codebuild]]></category><category><![CDATA[software delivery]]></category><category><![CDATA[slack]]></category><category><![CDATA[lambda]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[sns]]></category><dc:creator><![CDATA[Pratik Thakare]]></dc:creator><pubDate>Tue, 26 Dec 2023 19:10:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/HpMihL323k0/upload/19fc2144f1ce9043947b0c0b695f6d6e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><img src="https://file.notion.so/f/f/f370e646-8657-43d5-9288-cf00f03fb9e4/0f0bdae9-496e-4ba9-a5f6-671479ad91b0/slack-bot-builder.png?id=f7e8d23c-0054-4f4d-8701-d52472da8fdd&amp;table=block&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;expirationTimestamp=1703707200000&amp;signature=7fjikz8NUVNAFAkXsVEV5u9i6ttIbBI8sD4Qwu3h8ZI&amp;downloadName=slack-bot-builder.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-why"><strong>Why?</strong></h2>
<p><strong><em>Continuous Integration and Continuous Delivery/Continuous Deployment a.k.a CI/CD; this ain’t it.</em></strong></p>
<p>…</p>
<p>CI/CDs are great - update a branch through merge, perform a commit or a PR and the build request is sent instantly. A build is made and sent to you without you having to do anything <em>out of the flow</em>.</p>
<p>But what if you need a particular build from a made through the source of a particular branch or at a specific commit and the ones that fall between a version change?</p>
<p>You cannot enable CI/CDs on every branch. It may as very well be a waste of resources. So, we have proposed a CLI tool using capabilities of Slack and AWS. A command that <strong>can get you what you want, when you want it.</strong></p>
<h2 id="heading-tldr"><strong>TL;DR</strong></h2>
<h3 id="heading-setup-slack">Setup Slack</h3>
<ul>
<li><p>Make a Slash Command</p>
</li>
<li><p>Make an Incoming Webhook</p>
</li>
</ul>
<h3 id="heading-setup-lambda">Setup Lambda</h3>
<ul>
<li><p>Create Lambda</p>
</li>
<li><p>Setup Trigger Lambda</p>
</li>
<li><p>Setup Notification Lambda</p>
</li>
</ul>
<h3 id="heading-setup-codebuild">Setup CodeBuild</h3>
<ul>
<li><p>Configure Source</p>
</li>
<li><p>Configure Artifacts</p>
</li>
<li><p>Configure Amazon Simple Notification Service (SNS)</p>
</li>
</ul>
<h2 id="heading-how"><strong>How?</strong></h2>
<p>According to our requirements, we needed a way to build an android app with different <strong>build variants,</strong> different <strong>branches,</strong> and due to a sub-module in flutter, a <strong>sub-module branch</strong> parameter was added.</p>
<p>You may add parameters according to your needs. These are just parameters that we required for our build.</p>
<h3 id="heading-setup-slack-1">Setup Slack</h3>
<ol>
<li><p>Make sure you are signed-in properly. Now go to <a target="_blank" href="https://api.slack.com/">https://api.slack.com/</a>.</p>
</li>
<li><p>Click on <strong>Create an app</strong> <em>(if you don't have one already)</em></p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fa5b2d15f-cc9d-44b8-92c2-2f0fa98bb17a%2FUntitled.png?table=block&amp;id=f173b576-5907-41d7-b6e3-f166b734df2b&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
</li>
<li><p>Click on <strong>From scratch</strong> and enter your app details</p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ff390af5e-688f-4ade-a8c3-4d749afba6a0%2FUntitled.png?table=block&amp;id=97381f06-107e-42bd-9efd-609084f0cf65&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
</li>
</ol>
<h3 id="heading-make-a-slash-command">Make a Slash Command</h3>
<ol>
<li><p>Click on <strong>Slash Command</strong> and <strong>Create New Command</strong></p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F4d5478d1-bf88-43ca-9105-43e4fc13cb50%2FUntitled.png?table=block&amp;id=fa59d9c5-92ac-41fa-a285-d9c5f20b595c&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
</li>
</ol>
<p>Add the required details and click on <strong>Save</strong></p>
<p><strong><em>Note: The request URL is a POST request so make sure the API Gateway is properly configured.</em></strong></p>
<h3 id="heading-make-an-incoming-webhook">Make an Incoming Webhook</h3>
<ol>
<li><p>Click on <strong>Slash Command</strong> and <strong>Create New Incoming Webhook</strong></p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F5ebabae3-084b-4536-8987-a1cee29c39d5%2FUntitled.png?table=block&amp;id=3346f461-6375-4617-a29a-2f42c4adc4e0&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
</li>
<li><p><strong>Activate Incoming Webhooks</strong></p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fc1e27313-b74a-4dd5-a6fd-6bfd28d9811e%2FUntitled.png?table=block&amp;id=5a26d73d-a642-4cab-ab44-e89dc6a0aa3e&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
</li>
<li><p><strong>Request to Add New Webhook</strong> at the bottom of the page. Send a request with a message that states the purpose of the Incoming Webhook and inform your admin.</p>
</li>
<li><p>Select the channel that you wish to make the Incoming Webhook of and voilà! You are done.</p>
</li>
</ol>
<h3 id="heading-setup-lambda-1">Setup Lambda</h3>
<h4 id="heading-create-lambda">Create Lambda</h4>
<p>Create two lambda functions:</p>
<ol>
<li><p><strong>Trigger lambda</strong> - Used to trigger CodeBuild build</p>
</li>
<li><p><strong>Notification lambda</strong> - Used to send a notification on Slack</p>
</li>
</ol>
<p><strong>Note:</strong> You may create the lambda function by referring to <a target="_blank" href="https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html#getting-started-create-function">this documentation</a>.</p>
<h4 id="heading-setup-trigger-lambda">Setup Trigger Lambda</h4>
<p>We will need an API Gateway as a trigger. You may refer to <a target="_blank" href="https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html">this</a> to build an API Gateway for lambda. The endpoint should be a <strong>POST request</strong> because that's what the <strong>Slack Slash Command</strong> will provide us.</p>
<p><strong>Request Schema</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"2.0"</span>,
  <span class="hljs-attr">"routeKey"</span>: <span class="hljs-string">"ANY /triggerAndroidBuild"</span>,
  <span class="hljs-attr">"rawPath"</span>: <span class="hljs-string">"/default/triggerAndroidBuild"</span>,
  <span class="hljs-attr">"rawQueryString"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"headers"</span>: {
    ...
  },
  <span class="hljs-attr">"requestContext"</span>: {
    <span class="hljs-attr">"accountId"</span>: <span class="hljs-string">"..."</span>,
    <span class="hljs-attr">"apiId"</span>: <span class="hljs-string">"..."</span>,
    <span class="hljs-attr">"domainName"</span>: <span class="hljs-string">"..."</span>,
    <span class="hljs-attr">"domainPrefix"</span>: <span class="hljs-string">"..."</span>,
    <span class="hljs-attr">"http"</span>: {
      <span class="hljs-attr">"method"</span>: <span class="hljs-string">"POST"</span>,
      <span class="hljs-attr">"path"</span>: <span class="hljs-string">"/default/triggerAndroidBuild"</span>,
      <span class="hljs-attr">"protocol"</span>: <span class="hljs-string">"HTTP/1.1"</span>,
      <span class="hljs-attr">"sourceIp"</span>: <span class="hljs-string">"..."</span>,
      <span class="hljs-attr">"userAgent"</span>: <span class="hljs-string">"Slackbot 1.0 (+https://api.slack.com/robots)"</span>
    },
    <span class="hljs-attr">"requestId"</span>: <span class="hljs-string">"..."</span>,
    <span class="hljs-attr">"routeKey"</span>: <span class="hljs-string">"ANY /triggerAndroidBuild"</span>,
    <span class="hljs-attr">"stage"</span>: <span class="hljs-string">"default"</span>,
    <span class="hljs-attr">"time"</span>: <span class="hljs-string">"07/Jun/2022:08:00:05 +0000"</span>,
    <span class="hljs-attr">"timeEpoch"</span>: <span class="hljs-number">1654588805616</span>
  },
  <span class="hljs-attr">"body"</span>: <span class="hljs-string">"dG9rZW49NTRQZ1Z0d2NYMFBad29JQnh5cGNxaHJJJnRlY...hZjBj"</span>,
  <span class="hljs-attr">"isBase64Encoded"</span>: <span class="hljs-literal">true</span>
}
</code></pre>
<p>We are mainly concerned with the <strong>body</strong> given to us. It will always be <strong>Encoded with Base64.</strong> All you need to do is decode the string and you will get all the information that you may require.</p>
<p>To understand what is stored in the body, refer to <a target="_blank" href="https://api.slack.com/interactivity/slash-commands#app_command_handling">this</a>.</p>
<p><strong>Source code</strong></p>
<ol>
<li><p>Import <em>aws-sdk</em> in the lambda to use it and setup the CodeBuild config according to your needs. Refer to <a target="_blank" href="https://docs.aws.amazon.com/codebuild/latest/APIReference/API_StartBuild.html">AWS CodeBuild Request Syntax</a>.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// index.js</span>
 <span class="hljs-keyword">const</span> AWS = <span class="hljs-built_in">require</span>(<span class="hljs-string">"aws-sdk"</span>);

 <span class="hljs-keyword">const</span> codebuild = <span class="hljs-keyword">new</span> AWS.CodeBuild();
   <span class="hljs-keyword">const</span> branch = data.hasOwnProperty(<span class="hljs-string">"branch"</span>) ? 
     data[<span class="hljs-string">"branch"</span>] : <span class="hljs-string">"develop"</span>;
   <span class="hljs-keyword">const</span> flutter_branch = data.hasOwnProperty(<span class="hljs-string">"flutter_branch"</span>)
     ? data[<span class="hljs-string">"flutter_branch"</span>]
     : <span class="hljs-string">"develop"</span>;
   <span class="hljs-keyword">const</span> build = {
     <span class="hljs-attr">projectName</span>: <span class="hljs-string">"android-app"</span>,
     <span class="hljs-attr">sourceVersion</span>: branch,
     <span class="hljs-attr">environmentVariablesOverride</span>: [
       {
         <span class="hljs-attr">name</span>: <span class="hljs-string">"VARIANT_TYPE"</span> <span class="hljs-comment">/* required */</span>,
         <span class="hljs-attr">value</span>: build_variant <span class="hljs-comment">/* required */</span>,
         <span class="hljs-attr">type</span>: <span class="hljs-string">"PLAINTEXT"</span>,
       },
       {
         <span class="hljs-attr">name</span>: <span class="hljs-string">"BRANCH"</span>,
         <span class="hljs-attr">value</span>: branch,
         <span class="hljs-attr">type</span>: <span class="hljs-string">"PLAINTEXT"</span>,
       },
       {
         <span class="hljs-attr">name</span>: <span class="hljs-string">"FLUTTER_BRANCH"</span>,
         <span class="hljs-attr">value</span>: flutter_branch,
         <span class="hljs-attr">type</span>: <span class="hljs-string">"PLAINTEXT"</span>,
       },
       {
         <span class="hljs-attr">name</span>: <span class="hljs-string">"TRIGGER_USER"</span>,
         <span class="hljs-attr">value</span>: url.searchParams.get(<span class="hljs-string">"user_id"</span>),
         <span class="hljs-attr">type</span>: <span class="hljs-string">"PLAINTEXT"</span>,
       },
       {
         <span class="hljs-attr">name</span>: <span class="hljs-string">"TRIGGER_USER_REF"</span>,
         <span class="hljs-attr">value</span>: url.searchParams.get(<span class="hljs-string">"user_name"</span>),
         <span class="hljs-attr">type</span>: <span class="hljs-string">"PLAINTEXT"</span>,
       },
     ],
     <span class="hljs-attr">cacheOverride</span>: {
       <span class="hljs-attr">type</span>: <span class="hljs-string">"LOCAL"</span>,
       <span class="hljs-attr">modes</span>: [
         <span class="hljs-string">"LOCAL_CUSTOM_CACHE"</span>,
         <span class="hljs-string">"LOCAL_DOCKER_LAYER_CACHE"</span>,
         <span class="hljs-string">"LOCAL_SOURCE_CACHE"</span>,
       ],
     },
     <span class="hljs-attr">gitSubmodulesConfigOverride</span>: {
       <span class="hljs-attr">fetchSubmodules</span>: <span class="hljs-literal">false</span> <span class="hljs-comment">/* required */</span>,
     },
     <span class="hljs-attr">buildspecOverride</span>: <span class="hljs-string">`{version: 0.2, ...`</span>,
   };
</code></pre>
<p> <strong>Note:</strong> We have added the buildspec required by the CodeBuild in this config itself. You may add it in the AWS console or in the source files as <a target="_blank" href="https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html"><strong>buildspec.yml</strong></a>.</p>
</li>
<li><p>Build the application using this small snippet. Once the build is successfully triggered, we can use the <strong>callback</strong> function to send a message back to Slack where the command was triggered from.</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// index.js</span>

 <span class="hljs-keyword">try</span> {
     <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> codebuild.startBuild(build).promise();
     callback(<span class="hljs-literal">undefined</span>, {
       statusCode,
       <span class="hljs-attr">body</span>: <span class="hljs-string">":white_check_mark: Success! triggering build for android-app."</span>,
       headers,
     });
   } <span class="hljs-keyword">catch</span> (err) {
     callback(<span class="hljs-literal">undefined</span>, {
       statusCode,
       <span class="hljs-attr">body</span>: <span class="hljs-string">`:warning: Error! <span class="hljs-subst">${err.message}</span>.`</span>,
       headers,
     });
   }
</code></pre>
<p> <strong>Note:</strong> You may use this <strong>callback</strong> function for command validation as well.</p>
</li>
</ol>
<h4 id="heading-setup-notification-lambda">Setup Notification Lambda</h4>
<p>We will need an Amazon Simple Notification Service (SNS) as the trigger. The SNS will be created later in the <a target="_blank" href="/3710776de76f47a0b0571245bb764771#bf6e94e80d4e446989d8405b79baf601"><strong>CodeBuild</strong></a> section.</p>
<p><strong>Request Schema</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"Records"</span>: [
    {
      <span class="hljs-attr">"EventSource"</span>: <span class="hljs-string">"aws:sns"</span>,
      <span class="hljs-attr">"EventVersion"</span>: <span class="hljs-string">"1.0"</span>,
      <span class="hljs-attr">"EventSubscriptionArn"</span>: <span class="hljs-string">"..."</span>,
      <span class="hljs-attr">"Sns"</span>: {
        <span class="hljs-attr">"Type"</span>: <span class="hljs-string">"Notification"</span>,
        <span class="hljs-attr">"MessageId"</span>: <span class="hljs-string">"fa556e61-3b73-5f7c-b93d-357acabcb9eb"</span>,
        <span class="hljs-attr">"TopicArn"</span>: <span class="hljs-string">"arn:aws:sns:ap-south-1:289014830182:codebuild-slack"</span>,
        <span class="hljs-attr">"Subject"</span>: <span class="hljs-string">"None"</span>,
        <span class="hljs-attr">"Message"</span>: <span class="hljs-string">"{\"account\":\"...\",\"detailType\":\"CodeBuild Build State Change\",\"region\":\"ap-south-1\",\"source\":\"aws.codebuild\",\"time\":\"2022-06-09T13:03:04Z\",...,\"additionalAttributes\":{}}"</span>,
        <span class="hljs-attr">"Timestamp"</span>: <span class="hljs-string">"2022-06-09T13:03:11.226Z"</span>,
        <span class="hljs-attr">"SignatureVersion"</span>: <span class="hljs-string">"1"</span>,
        <span class="hljs-attr">"Signature"</span>: <span class="hljs-string">"DcgduZ8N2tyXh1ioMQNpah4m3/dol2...tEQ=="</span>,
        <span class="hljs-attr">"SigningCertUrl"</span>: <span class="hljs-string">"https://sns.ap-south-1.amazonaws.com/....pem"</span>,
        <span class="hljs-attr">"UnsubscribeUrl"</span>: <span class="hljs-string">"https://sns.ap-south-1.amazonaws.com/..."</span>,
        <span class="hljs-attr">"MessageAttributes"</span>: {}
      }
    }
  ]
}
</code></pre>
<p>You will find all the CodeBuild Information in the <strong>“Message”</strong> section of the request. The Message section will be encoded in JSON string, so you will have to decode it before using any data.</p>
<p>The <strong>Message section</strong> will look like <a target="_blank" href="https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html#sample-build-notifications-ref">this</a>.</p>
<p><strong>Algorithm</strong></p>
<ol>
<li><p>Convert the <strong>Message</strong> from JSON string to Object</p>
</li>
<li><p>Format the message that you need to send to Slack using the details provided in the message. You may learn more about formatting from <a target="_blank" href="https://api.slack.com/reference/surfaces/formatting">here</a>.</p>
</li>
<li><p>Use the <strong>Incoming Webhook</strong> to send a <strong>POST</strong> request with the <em>formatted message as body</em>.</p>
</li>
</ol>
<h3 id="heading-setup-codebuild-1">Setup CodeBuild</h3>
<p>You will need a S3 bucket to store the artifacts produced by the CodeBuild. Refer to <a target="_blank" href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/creating-bucket.html">AWS user guide for creating bucket.</a></p>
<h4 id="heading-configure-source">Configure Source</h4>
<p>We used <strong>GitHub</strong> as our source. You may find other options such as:</p>
<ul>
<li><p>Amazon S3</p>
</li>
<li><p>CodeCommit</p>
</li>
<li><p>Bitbucket</p>
</li>
<li><p>GitHub Enterprise Server</p>
</li>
</ul>
<p>It’s very simple to authenticate - you just need to use the <strong>OAuth</strong> provided by the AWS console and login to GitHub. The cloning of the repository will be handled by CodeBuild <em>(to be more specific CodeStarSourceConnection)</em>.</p>
<h4 id="heading-configure-artifacts">Configure Artifacts</h4>
<p>Below is the simple configuration to achieve pushing the Build Artifacts on Amazon S3.</p>
<p><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F65379580-abcd-432f-829b-9f5709e10ae2%2FUntitled.png?table=block&amp;id=fc6fdcb2-61cd-47bc-a461-d20789fe1815&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
<p><strong>Note:</strong> Each config mentioned above matches with those of AWS CloudFormation and are all documented <a target="_blank" href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-artifacts.html">here</a> by AWS.</p>
<h3 id="heading-configure-amazon-simple-notification-service-sns">Configure Amazon Simple Notification Service (SNS)</h3>
<p><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F376eb022-26e3-4118-b0f3-368236f23064%2FUntitled.png?table=block&amp;id=580b56be-8be4-4e15-aa76-ba9e09c57fad&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
<ol>
<li><p><strong>Create a SNS topic</strong>. You may refer to this <a target="_blank" href="https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html#create-topic-aws-console">AWS Documentation</a>. Once you have created the SNS, you should add the <strong>Notifcation Lambda</strong> as a subscriber</p>
</li>
<li><p>Hover on <strong>Notify</strong> and click on <strong>Manage notification rule</strong></p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F0cfbe27f-4c0a-41b7-893a-5907d9001a5d%2FUntitled.png?table=block&amp;id=00963e71-70d0-4317-8a7a-5e2f822c47a1&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
<p> You will be redirected to this page. Here, we already have a notification rule setup but if you don’t, click on <strong>Create notification rule.</strong></p>
<p> <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fd02b2bc2-7f78-4090-bbb4-3e191c25569a%2FUntitled.png?table=block&amp;id=574db8b6-2897-45c8-951a-396241ffc948&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
</li>
<li><p>This will send you to the page below.</p>
<ol>
<li><p>Enter whatever name you may seem fit</p>
</li>
<li><p>Choose detail type Full or Basic according to your needs. You may learn more about the notifications <a target="_blank" href="https://docs.aws.amazon.com/codebuild/latest/userguide/sample-build-notifications.html">here</a>.</p>
</li>
<li><p>Choose a trigger according to your need. We have chosen <strong>Failed</strong> and <strong>Succeeded</strong> to get notifications when the build has failed or successfully finished building.</p>
</li>
<li><p>In the <strong>Targets</strong> section you may select the SNS that you just created</p>
</li>
</ol>
</li>
</ol>
<p>    <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fc3c5bd25-9f67-4eaf-9d26-19176c500b81%2FUntitled.png?table=block&amp;id=817db581-a93f-4303-a9cd-cf052b0b373a&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
<p>    <img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F3728a499-2b26-4e51-ae30-ca7a74f0c2c6%2FUntitled.png?table=block&amp;id=4d72e4a5-d6fc-43f2-a90f-836b1fad04a3&amp;spaceId=f370e646-8657-43d5-9288-cf00f03fb9e4&amp;width=2000&amp;userId=770b7e48-dc33-4b9a-854a-917ec260e8bd&amp;cache=v2" alt /></p>
<p>    <strong>Note:</strong> You may refer to any of the <a target="_blank" href="https://docs.aws.amazon.com/codebuild/latest/userguide/create-project.html">following</a> to create a CodeBuild build.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With this you can now add the bot to your slack workspace and experiment with the command that you just created.</p>
]]></content:encoded></item><item><title><![CDATA[How to install Codux - React IDE on Arch Linux]]></title><description><![CDATA[Codux is a visual IDE for building web frontends with React. It is built by Wix and is absolutely free to use. And I know... I know... with a visual IDE, aren't we past the days of dragging and dropping components while making a mess of code? But thi...]]></description><link>https://blog.pratikthakare.com/how-to-install-codux-react-ide-on-arch-linux</link><guid isPermaLink="true">https://blog.pratikthakare.com/how-to-install-codux-react-ide-on-arch-linux</guid><category><![CDATA[ArchLinux]]></category><category><![CDATA[React]]></category><category><![CDATA[wix]]></category><category><![CDATA[Installation]]></category><category><![CDATA[Frontend Development]]></category><dc:creator><![CDATA[Pratik Thakare]]></dc:creator><pubDate>Tue, 23 May 2023 12:40:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/UYsBCu9RP3Y/upload/d38ab3f03b5e75a5a02dcd8d7e7b0cc6.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Codux is a visual IDE for building web frontends with React. It is built by Wix and is absolutely free to use. And I know... I know... with a visual IDE, aren't we past the days of dragging and dropping components while making a mess of code? But this may surprise you. Maybe you should try it yourself or watch the video made by Fireship.</p>
<p>Well, if you want to try it yourself, let's get on to installing, shall we?</p>
<h2 id="heading-installation">Installation</h2>
<p>First, go to this <a target="_blank" href="https://www.codux.com/download">link</a>. You will be given download options for various operating systems. As shown below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1684844850544/e9febc61-3b91-4463-a1aa-a77e97760225.png" alt class="image--center mx-auto" /></p>
<p>Since we are working on ArchLinux, we will choose <code>.pacman_x64</code>. Now all you have to do is run a simple command using the <code>pacman</code> client</p>
<pre><code class="lang-bash">sudo pacman -U Codux-[version].x64.pacman
</code></pre>
<p>The above code will generate all the necessary dependencies and also create a <code>.desktop</code> file for launching with an application launcher.</p>
]]></content:encoded></item></channel></rss>