<?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: Deathvenom</title>
    <description>The latest articles on DEV Community by Deathvenom (@deathvenom54).</description>
    <link>https://dev.to/deathvenom54</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%2F809338%2F888ef98d-566d-48ba-bc7c-60f58fb3debf.jpeg</url>
      <title>DEV Community: Deathvenom</title>
      <link>https://dev.to/deathvenom54</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deathvenom54"/>
    <language>en</language>
    <item>
      <title>Remote deployment triggered by GitHub webhooks</title>
      <dc:creator>Deathvenom</dc:creator>
      <pubDate>Thu, 24 Mar 2022 04:48:18 +0000</pubDate>
      <link>https://dev.to/deathvenom54/remote-deployment-triggered-by-github-webhooks-5gm3</link>
      <guid>https://dev.to/deathvenom54/remote-deployment-triggered-by-github-webhooks-5gm3</guid>
      <description>&lt;p&gt;Do you have an application hosted on a VPS? In that case, every time you push your code to version control, you will have to somehow make the server pull it and restart the process. Now, you could do it the chimp way, which is SSH'ing in every time and running the necessary commands youself. Or, you can &lt;strong&gt;automate&lt;/strong&gt; it!&lt;/p&gt;

&lt;p&gt;A week or two ago, I had the realization that I don't necessarily need to SSH in and run the deploy script every time I push my changes to GitHub, if I could somehow automate it. That is when my search for a simple solution to this problem began.&lt;/p&gt;

&lt;p&gt;My first stop was the post-receieve git hook, but it never worked for me. I read a lot of articles on it and tried various times, but the script simply never ran.&lt;/p&gt;

&lt;p&gt;Next, I tried the git-hooks plugin for pm2 (the process manager I knew). That, however, also didn't work and mentioned non-existent file conflicts.&lt;/p&gt;

&lt;p&gt;At this juncture, I could have tried a CD service like Jenkins or Travis, but I decided to write my own solution instead. This aims to be easy to set up and run, and provide a lot of flexibility. Being my first proper project in Go, I also learnt a lot of things along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;github-deploy-inator starts a webserver on the specified path which listens for webhooks from GitHub. When a webhook (or any POST request in general) is received, it gets the required information and runs a command specified in a specified directory. You might wonder from where it gets the information? &lt;/p&gt;

&lt;h3&gt;
  
  
  Enter config.json
&lt;/h3&gt;

&lt;p&gt;All the required information is specified in a config.json file, which should be present alongside the executable. You can check out its format &lt;a href="https://github.com/DeathVenom54/github-deploy-inator/#format" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Basic structure:
&lt;/h4&gt;

&lt;p&gt;the config must contain fields for &lt;code&gt;port&lt;/code&gt;, &lt;code&gt;endpoint&lt;/code&gt; and &lt;code&gt;listeners&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;An example:&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;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;":80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/github/webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"listeners"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-listener"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DeathVenom54/github-deploy-inator"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"directory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/dv/projects/docs-website"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yarn deploy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"notifyDiscord"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"discord"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"webhook"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webhook-goes-here"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"notifyBeforeRun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendOutput"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;span class="p"&gt;}&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;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;h2&gt;
  
  
  Setting it up
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation and configuration
&lt;/h3&gt;

&lt;p&gt;To get started, grab a release from &lt;a href="https://github.com/DeathVenom54/github-deploy-inator/releases/tag/v1.0.0" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If you are on a VPS, you can download it using curl. Copy the link for your OS and architecture and run this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;release &lt;span class="nb"&gt;link&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; github-deploy-inator.zip &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; unzip github-deploy-inator.zip
&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%2F7iu7hi1iahinlhm8xp7x.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%2F7iu7hi1iahinlhm8xp7x.png" alt="Image description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This will unzip the executable, as well as an example config file. Edit the config as per your requirements, and test it by running the executable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./github_deploy-inator_linux_x64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will load and verify the config. If something is wrong, it will exit. If you see the message "Listening for Github webhooks on port :PORT", the config is valid.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that this does not verify if the provided Discord webhook url is valid or not, so take care of it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Run it
&lt;/h3&gt;

&lt;p&gt;You will need to use a process manager to run the executable, and restart if it fails. You could use &lt;a href="https://www.freedesktop.org/wiki/Software/systemd/" rel="noopener noreferrer"&gt;systemd&lt;/a&gt;, but I prefer use &lt;a href="https://pm2.keymetrics.io/docs/usage/quick-start/" rel="noopener noreferrer"&gt;pm2&lt;/a&gt; as I find it simpler to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  An Example
&lt;/h2&gt;

&lt;p&gt;Let's host a simple API using this!&lt;/p&gt;

&lt;p&gt;First of all, I cloned a &lt;a href="https://github.com/DeathVenom54/example-node-api" rel="noopener noreferrer"&gt;super simple express API&lt;/a&gt; (writted in Typescript).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/DeathVenom54/example-node-api.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I used &lt;a href="https://pm2.keymetrics.io/docs/usage/pm2-doc-single-page/" rel="noopener noreferrer"&gt;pm2&lt;/a&gt; to run this API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn build
pm2 start dist/main.js &lt;span class="nt"&gt;--name&lt;/span&gt; example-api
&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%2Fuws1ylp26y5mmnikkems.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%2Fuws1ylp26y5mmnikkems.png" alt="pm2 list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, to set up the deployer...&lt;/p&gt;

&lt;p&gt;Assuming that you have already downloaded the correct build, let's edit the config. Here is what I ended up with:&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;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"endpoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/webhook/github"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"listeners"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"my-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"repository"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"DeathVenom54/example-node-api"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"directory"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/home/dv/projects"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"curl localhost:80"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"notifyDiscord"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"discord"&lt;/span&gt;&lt;span class="p"&gt;:&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;span class="nl"&gt;"webhook"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://discord.com/api/webhooks/937660913748697088/wK8NGFKUT09ToiQRxMX83asMnaCxn47sagE7Hg1bcba7Nb7dEQm6zxag4K0S_3iLBLCw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"notifyBeforeRun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sendOutput"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;span class="p"&gt;}&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;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;blockquote&gt;
&lt;p&gt;Port 80 is a privileged port, which represents HTTP. To run this code, run this command first: &lt;code&gt;sudo setcap CAP_NET_BIND_SERVICE=+eip /path/to/binary&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To check if the config is valid, run the executable once.&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%2Fegxo3y4yjezxt4e6nxjq.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%2Fegxo3y4yjezxt4e6nxjq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oops, I forgot the colon before the port, let's fix it.&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="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;":80"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, it should succeed...&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%2Ffv2rjyf0700bz2uttfsl.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%2Ffv2rjyf0700bz2uttfsl.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Now let's set it up with pm2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 start ./github_deploy-inator_linux_x64 &lt;span class="nt"&gt;--name&lt;/span&gt; deployer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should have it running, let's check the logs to verify&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pm2 logs deployer
&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%2F3rznxyutm7wh2bg45gal.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%2F3rznxyutm7wh2bg45gal.png" alt="pm2 logs for deployer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect! The last step is to add a webhook on your repository. Make sure the Content-Type is &lt;code&gt;application/json&lt;/code&gt;. You should also set a secret, and specify it in the config.&lt;/p&gt;

&lt;p&gt;The deployer might throw an error when GitHub sends a ping webhook once you set it up. This is a known issue I haven't been able to fix. You should ignore the error.&lt;/p&gt;

&lt;p&gt;Now let's push something and try... It works!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2022/03/24 04:45:51 Successfully executed webhook from DeathVenom54/example-node-api
&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%2F4xrspo23tb830573mvzz.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%2F4xrspo23tb830573mvzz.png" alt="Discord notification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next steps
&lt;/h2&gt;

&lt;p&gt;If you face any bug or difficulty while using this program, or have a suggestion for it, feel free to &lt;a href="https://github.com/DeathVenom54/github-deploy-inator/issues" rel="noopener noreferrer"&gt;open an issue on Github&lt;/a&gt;, or let me know in my &lt;a href="https://discord.gg/qJnrRvt7wW" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Happy devving!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>github</category>
      <category>go</category>
    </item>
    <item>
      <title>Affiliate Magnet dev notes + Future plans</title>
      <dc:creator>Deathvenom</dc:creator>
      <pubDate>Fri, 11 Mar 2022 04:39:33 +0000</pubDate>
      <link>https://dev.to/deathvenom54/affiliate-magnet-dev-notes-future-plans-3b7n</link>
      <guid>https://dev.to/deathvenom54/affiliate-magnet-dev-notes-future-plans-3b7n</guid>
      <description>&lt;p&gt;Hello there, I am Deathvenom, the developer of &lt;a href="http://affiliate-magnet.deathvenom.me/"&gt;Affiliate Magnet&lt;/a&gt;. In this post, I wish to convey my plans for the future for the bot, and also do a little survey.&lt;/p&gt;

&lt;p&gt;I have not worked on Affiliate Magnet for a while, but I will begin active development on it soon. Before that, I would like to inform my active users, as well as collect some feedback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Future plans
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Whitelisted roles
&lt;/h3&gt;

&lt;p&gt;A highly requested feature is a whitelist. Once added, you will be able to whitelist some roles. This means that if someone posts a link and has a whitelisted role, the bot will not do anything to it. This can be useful to ensure that your moderators and trusted members are not annoyed by it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Better /set command
&lt;/h3&gt;

&lt;p&gt;Discord recently added modals, which allow bots to show dedicated "input screens". I plan to use these to to simplify the /set commands&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xwYzYiuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://preview.redd.it/mj8guz0pcsg81.png%3Fwidth%3D566%26format%3Dpng%26auto%3Dwebp%26s%3D6ecf895ea6c96bae67af5f502e07645537e9f5b1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xwYzYiuJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://preview.redd.it/mj8guz0pcsg81.png%3Fwidth%3D566%26format%3Dpng%26auto%3Dwebp%26s%3D6ecf895ea6c96bae67af5f502e07645537e9f5b1" alt="An example modal" width="566" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once &lt;a href="https://discord.js.org/#/"&gt;discord.js&lt;/a&gt; adds support for modals, I will combine separate commands like &lt;code&gt;/set amazon affiliate_tag&lt;/code&gt; and &lt;code&gt;/set amazon replace_mode&lt;/code&gt; into a simple single command &lt;code&gt;/set amazon&lt;/code&gt;, which would open a modal with all options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What will this achieve?&lt;/strong&gt; Moving to modals will tackle the current "command spam" situation we have right now, and make it convenient to add support for a lot of websites!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JC6o3qpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82lnbet80yd85gol0csw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JC6o3qpE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82lnbet80yd85gol0csw.png" alt="The current command spam situation" width="629" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Survey
&lt;/h2&gt;

&lt;p&gt;I would be glad if you could &lt;a href="https://forms.gle/7gQJHh53nnq421zc6"&gt;fill out this short survey&lt;/a&gt;, which would inform me of things that need to be improved and some problems to address.&lt;/p&gt;

&lt;p&gt;For updates, feel free to follow the #aff-mag-updates channel from the &lt;a href="https://discord.gg/qJnrRvt7wW"&gt;support server&lt;/a&gt; to your own server.&lt;/p&gt;

&lt;p&gt;Thanks for reading, and have a fantastic day!&lt;/p&gt;

</description>
      <category>discord</category>
    </item>
    <item>
      <title>v1.2.0 for djs-marshal is out!</title>
      <dc:creator>Deathvenom</dc:creator>
      <pubDate>Thu, 10 Mar 2022 15:47:59 +0000</pubDate>
      <link>https://dev.to/deathvenom54/v120-for-djs-marshal-is-out-34ce</link>
      <guid>https://dev.to/deathvenom54/v120-for-djs-marshal-is-out-34ce</guid>
      <description>&lt;p&gt;It has been a long time since I worked on my &lt;a href="https://www.npmjs.com/package/discord.js"&gt;discord.js&lt;/a&gt; command and interaction manager &lt;a href="https://www.npmjs.com/package/djs-marshal"&gt;djs-marshal&lt;/a&gt;. So here we are!&lt;/p&gt;

&lt;p&gt;v1.2.0 brings permission options like &lt;code&gt;allowRoles&lt;/code&gt;, &lt;code&gt;denyRoles&lt;/code&gt;, &lt;code&gt;allowUsers&lt;/code&gt; and &lt;code&gt;denyUsers&lt;/code&gt;, better error handling and deprecates &lt;code&gt;allowWithPermission&lt;/code&gt;, which was a terrible idea to even begin with. Check it out!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DeathVenom54"&gt;
        DeathVenom54
      &lt;/a&gt; / &lt;a href="https://github.com/DeathVenom54/djs-marshal"&gt;
        djs-marshal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A slash command handler for discord.js v13
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
djs-marshal&lt;/h1&gt;
&lt;p&gt;&lt;a href="https://www.npmjs.com/package/djs-marshal" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/0295953e1cf699e90fa4bf3f2ad120edeccecb99eee9b64ca12f5a469edbdb61/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f646a732d6d61727368616c3f7374796c653d666f722d7468652d6261646765" alt="npm"&gt;&lt;/a&gt;
&lt;a href="https://www.npmjs.com/package/djs-marshal" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/656afd577c353a7e2dfb6d307f1cc7dcd748de20c1101d49817b69b937fda578/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f646a732d6d61727368616c3f7374796c653d666f722d7468652d6261646765" alt="downloads"&gt;&lt;/a&gt;
&lt;a href="https://discord.gg/qJnrRvt7wW" rel="nofollow"&gt;&lt;img src="https://camo.githubusercontent.com/a680fa7dfe35ed412b9861321b5f96902a0bae2fd66fe3b45400934549a37a0a/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f3837333233323735373530383135373437303f636f6c6f723d353836354632266c6162656c3d646973636f7264267374796c653d666f722d7468652d6261646765" alt="discord"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A lightweight command handler for discord.js interactions&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This package requires discord.js v13 or higher to be installed&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
Installation&lt;/h2&gt;
&lt;div class="highlight highlight-source-shell position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; with npm&lt;/span&gt;
npm install djs-marshal --save
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; with yarn&lt;/span&gt;
yarn add djs-marshal
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; this package also requires discord.js&lt;/span&gt;
npm install discord.js --save&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
Documentation&lt;/h2&gt;
&lt;p&gt;You can find the full documentation &lt;a href="https://deathvenom54.github.io/djs-marshal" rel="nofollow"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
Setup&lt;/h2&gt;
&lt;p&gt;You can set up your bot to handle commands in 2 ways:&lt;/p&gt;
&lt;h3&gt;
initializeBot()&lt;/h3&gt;
&lt;p&gt;This is the recommended way to set up your bot. It sets up various things
like commands' directory, logging and handlers for various events required.&lt;/p&gt;
&lt;div class="highlight highlight-source-ts position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-smi"&gt;Marshal&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'djs-marshal'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;path&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;'path'&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;client&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-smi"&gt;Marshal&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;initializeBot&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-kos"&gt;{&lt;/span&gt;
  &lt;span class="pl-c"&gt;// the path where slash commands are stored&lt;/span&gt;
  &lt;span class="pl-c1"&gt;slashCommandsPath&lt;/span&gt;: &lt;span class="pl-s1"&gt;path&lt;/span&gt;&lt;span class="pl-kos"&gt;.&lt;/span&gt;&lt;span class="pl-en"&gt;join&lt;/span&gt;&lt;span class="pl-kos"&gt;(&lt;/span&gt;&lt;span class="pl-s1"&gt;__dirname&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt; &lt;span class="pl-s"&gt;'commands'&lt;/span&gt;&lt;span class="pl-kos"&gt;)&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-c"&gt;// (optional) message to log on ready event&lt;/span&gt;
  &lt;span class="pl-c1"&gt;readyMessage&lt;/span&gt;: &lt;span class="pl-s"&gt;'Logged in as {tag}'&lt;/span&gt;&lt;span class="pl-kos"&gt;,&lt;/span&gt;
  &lt;span class="pl-c"&gt;// (optional) bot's token, will login if provided&lt;/span&gt;
  &lt;span class="pl-c1"&gt;token&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DeathVenom54/djs-marshal"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>discord</category>
      <category>typescript</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I made a simple Typescript template</title>
      <dc:creator>Deathvenom</dc:creator>
      <pubDate>Sun, 06 Mar 2022 13:48:21 +0000</pubDate>
      <link>https://dev.to/deathvenom54/i-made-a-simple-typescript-template-246f</link>
      <guid>https://dev.to/deathvenom54/i-made-a-simple-typescript-template-246f</guid>
      <description>&lt;p&gt;Too many templates out there, another one wouldn't hurt 🙃.&lt;/p&gt;

&lt;p&gt;This one aims to provide minimal boilerplate to get cracking on with your node.js + Typescript project, without bothering about writing out the &lt;code&gt;tsconfig.json&lt;/code&gt;. It only contains &lt;a href="https://npmjs.com/package/typescript"&gt;typescript&lt;/a&gt;, &lt;a href="https://npmjs.com/package/prettier"&gt;prettier&lt;/a&gt; and &lt;a href="https://npmjs.com/package/@types/node"&gt;@types/node&lt;/a&gt; as dev dependencies.&lt;/p&gt;

&lt;p&gt;Check it out!&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/DeathVenom54"&gt;
        DeathVenom54
      &lt;/a&gt; / &lt;a href="https://github.com/DeathVenom54/typescript-minimal-starter"&gt;
        typescript-minimal-starter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A minimal starter template for a Typescript project
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
&lt;a href="https://github.com/DeathVenom54/typescript-minimal-starter"&gt;📔 Typescript minimal starter&lt;/a&gt;
&lt;/h1&gt;
&lt;p&gt;A minimal starter template for a Typescript node.js project&lt;/p&gt;
&lt;h2&gt;
Ingredients&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://npmjs.com/package/typescript" rel="nofollow"&gt;typescript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://npmjs.com/package/prettier" rel="nofollow"&gt;prettier&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://npmjs.com/package/@types/node" rel="nofollow"&gt;@types/node&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Getting started&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/DeathVenom54/typescript-minimal-starter/generate"&gt;Make a repository with this template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Edit the package.json with your desired stuff&lt;/li&gt;
&lt;li&gt;Get cracking with your project!&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
Included scripts&lt;/h2&gt;
&lt;p&gt;You can use the following utility scripts to make commands easier&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yarn build&lt;/code&gt; to transpile to Javascript&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yarn dev&lt;/code&gt; to run the Typescript transpiler in watch mode&lt;/li&gt;
&lt;li&gt;&lt;code&gt;yarn start to run your code&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/DeathVenom54/typescript-minimal-starter"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>typescript</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Tabs vs Spaces: I have been disillusioned 🤯</title>
      <dc:creator>Deathvenom</dc:creator>
      <pubDate>Thu, 03 Mar 2022 03:06:27 +0000</pubDate>
      <link>https://dev.to/deathvenom54/tabs-vs-spaces-i-have-been-disillusioned-4go</link>
      <guid>https://dev.to/deathvenom54/tabs-vs-spaces-i-have-been-disillusioned-4go</guid>
      <description>&lt;p&gt;I have been steering away from any tabs/spaces article or conversation, for I considered this subject to be too trivial to debate on. I have been a stickler for 2 spaces since a while, and I don't care much about others' preferences.&lt;/p&gt;

&lt;p&gt;So, I was under the impression that a tab is a character of a fixed size (6 or 8 spaces, perhaps). That's why I used 2 spaces, it fits more code on the screen.&lt;/p&gt;

&lt;p&gt;Yesterday, when I was trying to quickly edit some stuff using Sublime Text (I rarely ever use it), I noticed it says at the bottom: &lt;code&gt;Tab width: 4&lt;/code&gt;. I went to switch it to 2, I noticed another option, &lt;code&gt;Use spaces instead&lt;/code&gt;. What? Up until that point, I believed that tab width refers to the number of spaces to indent code. That is when realization hit me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FuU5ZWBk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.discordapp.net/attachments/948776154586816542/948776209955819540/unknown.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FuU5ZWBk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://media.discordapp.net/attachments/948776154586816542/948776209955819540/unknown.png" alt="" width="508" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your code editor can display tabs to be of any length you want, it's not fixed! If you are working with someone on a project, and let's say they prefer 4 spaces and you prefer 2, just use tabs instead! You can configure your editor/IDE to display it as 4 and 2 respectively.&lt;/p&gt;

&lt;p&gt;So that's it, I am a changed person now. I hope I cleared it out if a person who had the same stupid assumption I had read this post. Happy hacking!&lt;/p&gt;

</description>
      <category>programming</category>
    </item>
    <item>
      <title>How (and how not) to make better Discord bots</title>
      <dc:creator>Deathvenom</dc:creator>
      <pubDate>Thu, 10 Feb 2022 16:34:03 +0000</pubDate>
      <link>https://dev.to/deathvenom54/how-and-how-not-to-make-better-discord-bots-4172</link>
      <guid>https://dev.to/deathvenom54/how-and-how-not-to-make-better-discord-bots-4172</guid>
      <description>&lt;p&gt;You clicked on this post, which probably means you too make bots, like me. Or you want to. Before I get into this article, I want to clarify that this is not a guide, but a bunch of ways in which you can improve your bots.&lt;/p&gt;

&lt;h2&gt;
  
  
  Curb your prefix
&lt;/h2&gt;

&lt;p&gt;It is very common among bot developers to come up with complex and unique command prefixes for their bot, to perhaps stand out. While thinking of a prefix, keep mobile users in mind. &lt;/p&gt;

&lt;p&gt;A simple symbol like &lt;code&gt;.&lt;/code&gt;, &lt;code&gt;$&lt;/code&gt;, &lt;code&gt;!&lt;/code&gt; serves the purpose very well, and easy to locate on any keyboard. A short word prefix (2-4 letters) is also a good idea.&lt;/p&gt;

&lt;p&gt;Avoid having multiple symbols or a combination of letters and symbols. Some notable examples are: &lt;code&gt;$!help&lt;/code&gt;, &lt;code&gt;bot-name!help&lt;/code&gt;. Better yet, use slash commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use slash commands
&lt;/h2&gt;

&lt;p&gt;Slash commands are somewhat new to Discord and still evolving. I believe that they are the future of bot interaction in Discord. Unless you have been living under a rock, you must have seen or used slash commands. &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%2Fcf52fehv9t6inoy6ut4n.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%2Fcf52fehv9t6inoy6ut4n.png" alt="Slash command menu"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;By pressing &lt;code&gt;/&lt;/code&gt;, you can see all the available commands for a bot, along with its description. When you use a command, you can see all its parameters. And that's not all! You can even specify what type each parameter should be, so that oblivious users don't enter a string in an integer type parameter.&lt;/p&gt;

&lt;p&gt;However, every coin has two sides. slash commands need to be registered beforehand and handled according to their &lt;code&gt;custom_id&lt;/code&gt;, which makes it a tedious job to implement them. To solve this problem, I wrote &lt;a href="https://github.com/DeathVenom54/djs-marshal" rel="noopener noreferrer"&gt;djs-marshal&lt;/a&gt;, check it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Message Components
&lt;/h2&gt;

&lt;p&gt;Similar to the point above, message components such as Buttons and Select Menus are a much better way to take input from the user. Are you making the user send a particular reaction to make a choice or to proceed? Toss that out and use buttons or select menus!.&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%2Fvu41syo4fdd94jveueeq.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%2Fvu41syo4fdd94jveueeq.png" alt="using reaction"&gt;&lt;/a&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%2Fqpayn9a48a5bqmyr44r5.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%2Fqpayn9a48a5bqmyr44r5.png" alt="using message button"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Make a help command
&lt;/h2&gt;

&lt;p&gt;Unless your bot is meant to be used by a single person, you should try to add a help command to your bot. This should give a brief description of what the bot does, list all the available commands of your bot, as well as some related links like support server invite and bot invite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip #1:&lt;/strong&gt; Make the bot say something along the lines of &lt;code&gt;Use /help for help&lt;/code&gt; when the bot is pinged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip #2:&lt;/strong&gt; Set the bot's description and activity to a message that includes its help command. This way, no matter how a Discord user finds the bot, they will be able to get relevant information about the bot without having to search it up.&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%2F8ekevzsc4uy48rhrqn17.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%2F8ekevzsc4uy48rhrqn17.png" alt="Example"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Don't add vote-walls
&lt;/h2&gt;

&lt;p&gt;A lot of bots block their commands behind a vote-wall. This means that you must vote for the bot on some bot list in order to use it. Though it might bring you a lot of votes fast, it is not &lt;em&gt;the way&lt;/em&gt;. This may even trigger people to write negative reviews and use an alternative bot. By all means, promote your bot by requesting users to vote for it, but forcing them to do so is not a good idea.&lt;/p&gt;

</description>
      <category>discord</category>
      <category>bot</category>
      <category>programming</category>
      <category>node</category>
    </item>
  </channel>
</rss>
