<?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Xyhtac Substack]]></title><description><![CDATA[Developer, Engineer, Solopreneur, Blogger, Toaster. 🦥]]></description><link>https://xyhtac.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!Ep5c!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F12614beb-72d9-4ab5-84f2-606b4a276fc4_1213x1213.jpeg</url><title>Xyhtac Substack</title><link>https://xyhtac.substack.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 16 Apr 2026 06:41:46 GMT</lastBuildDate><atom:link href="https://xyhtac.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Max Fischer]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[xyhtac@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[xyhtac@substack.com]]></itunes:email><itunes:name><![CDATA[Xyhtac]]></itunes:name></itunes:owner><itunes:author><![CDATA[Xyhtac]]></itunes:author><googleplay:owner><![CDATA[xyhtac@substack.com]]></googleplay:owner><googleplay:email><![CDATA[xyhtac@substack.com]]></googleplay:email><googleplay:author><![CDATA[Xyhtac]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Interactive Telegram Bot as password-free monitoring frontend for Icinga.]]></title><description><![CDATA[Asking for credentials, we reduce the usage of non-essential services by half. What if we could leverage Telegram as a security provider for Icinga?]]></description><link>https://xyhtac.substack.com/p/interactive-telegram-bot-as-password</link><guid isPermaLink="false">https://xyhtac.substack.com/p/interactive-telegram-bot-as-password</guid><dc:creator><![CDATA[Xyhtac]]></dc:creator><pubDate>Wed, 08 Jan 2025 22:53:51 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_nph!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_nph!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_nph!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_nph!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_nph!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_nph!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg" width="1456" height="913" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:913,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:373846,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_nph!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 424w, https://substackcdn.com/image/fetch/$s_!_nph!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 848w, https://substackcdn.com/image/fetch/$s_!_nph!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!_nph!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F64c2a4af-b015-4fad-887e-03f73fed52ae_1857x1164.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p><a href="https://icinga.com/">Icinga</a> stands tall in the realm of monitoring ecosystems, and it&#8217;s not just powerful &#8212; it&#8217;s a community-driven marvel, backed by the invaluable legacy of Nagios modules. It is the go-to solution for keeping tabs on the heartbeat of intricate infrastructures.</p><p>Imagine it as the vigilant guardian of critical systems, like the watchful eye over the detectors of the awe-inspiring Large Hadron Collider. However, navigating its bundled front-end rather complex for inexperienced users.</p><p>The <em>icingaweb </em>front-end might be powerful, but let&#8217;s face it &#8212; it&#8217;s not exactly user-friendly. In our quest for a simpler solution, we explored various approaches to deliver system statuses seamlessly to both web and mobile applications. But here&#8217;s the catch: access management was the thorn in our side. Who wants to install yet another app and remember additional login details just to check if everything is running smoothly? Our customers weren&#8217;t thrilled about the prospect either. They wanted a bridge between their devices and our treasure trove of monitoring data &#8212; something that didn&#8217;t involve app installations and password juggling.</p><h4>Notifications with Telegram Groups.</h4><p>At the same time Telegram notifications have always worked well because of the popularity of the messenger. Making icinga notification bot of your own is rather simple: go to <a href="https://web.telegram.org/k/#@BotFather">BotFather</a>, set name and description, grab a bot token then put <a href="https://github.com/xyhtac/icingatelegram/tree/prod/scripts">bash scripts</a> and <a href="https://github.com/xyhtac/icingatelegram/blob/prod/conf.d/telegram-notifications.conf">add notifications</a> from our repo to your icinga configuration:</p><pre><code>conf.d/telegram-notifications.conf &gt; /etc/icinga2/conf.d/
scripts/telegram-host-notification.sh &gt; /etc/icinga2/scripts/
scripts/telegram-service-notification.sh &gt; /etc/icinga2/scripts/</code></pre><p>And here&#8217;s the gem of wisdom: when attaching notification groups, opt for the Telegram supergroup IDs instead of individual user IDs. Why, you ask? Well, it&#8217;s a brilliant strategy to maintain control while involving your customers and overseeing message delivery.</p><p>By associating notifications with the supergroup IDs, you can invite clients to relevant Telegram groups without relinquishing administrative privileges. It&#8217;s a power move that transforms access management from tedious icinga configurations to the visually intuitive process of Telegram group administration, so you can delegate these tasks outside of DevOps access scope.</p><p>Go to your Telegram web or app, create new group, go to group settings, click on &#8216;add user&#8217;, find your new bot and check it. Now write something to your group and check if bot is actually getting updates:</p><pre><code>https://api.telegram.org/[TELEGRAM_BOT_TOKEN]/getUpdates</code></pre><p>Find your message in the update list and copy ID of the supergroup. Now, edit <em>telegram-notifications.conf</em> and replace <em>TELEGRAM_BOT_TOKEN</em> with your bot token and <em>TELEGRAM_GROUP_ID</em> with the ID of your supergroup.</p><h4>Interactive requests.</h4><p>After completing these steps, we&#8217;ve successfully established a solid foundation for an interactive monitoring front-end based on Telegram. The next step involves updating our notifications bot to make it interactive.</p><p>To achieve this, we&#8217;ll use <em>icingatelegram</em>, a Nodejs application that serves as a clickable Telegram bot interface. This application connects with the Telegram API, acting as a webhook server, and interfaces with your icinga API to fetch monitoring data.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/xyhtac/icingatelegram&quot;,&quot;text&quot;:&quot;Icingatelegram&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/xyhtac/icingatelegram"><span>Icingatelegram</span></a></p><p></p><p>The bot interacts with your users directly through private chats. However, to initiate a conversation, users must first send a <strong>/sitrep</strong> request from the corresponding group to which they belong. The underlying assumption is that all group members have access to a specific set of Icinga services that you define in your configuration file. The group ID obtained from the initial request is utilized by the bot to determine the available dataset for the user and generate a session token. Now, your focus can shift to delivering targeted monitoring data upon user request to specific group IDs and Telegram will handle access control seamlessly.</p><h4>Deployment as <em>tgbot_swarm</em> node.</h4><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://github.com/xyhtac/tgbot-swarm&quot;,&quot;text&quot;:&quot;tgbot-swarm&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://github.com/xyhtac/tgbot-swarm"><span>tgbot-swarm</span></a></p><p><em>icingatelegram</em> is designed to be deployed as Docker app with <em>tgbot_swarm </em>controller. To make it happen, follow these steps:</p><ol><li><p>Prepare you <em>tgbot_swarm</em> node according to the <a href="https://github.com/xyhtac/tgbot-swarm/blob/prod/README.md">manual</a>.</p></li><li><p>Create <a href="https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/">API user</a> on your icinga master host:</p></li></ol><pre><code># /etc/icinga2/conf.d/api-users.conf

object ApiUser "icingatelegram" {
  password = "icinga-api-secret-password"
}</code></pre><ol start="3"><li><p>Make your own fork of <em>icingatelegram </em>repository.</p></li><li><p>Edit <em>pipeline/deploy-icingatelegram.jenkinsfile</em> according with you environment:</p></li></ol><pre><code>environment {
        // General application Configuration
        VERBOSE = "1"
        DEPLOY = "dev"
        RETURN_BUTTON = "1"
        LANGUAGE = "ru"

        // Application-specific deploy configuration
        APP_NAME = "icingatelegram-bot"
        APP_DESCRIPTION = "IcingaTelegram_monitoring_interactive_service"
        APP_HOME = "icingatelegram"
        // Telegram bot token from Jenkins secret store
        TG_TOKEN = credentials("icingatelegram-tgtoken-${DEPLOY}")
        // Monitoring API password from Jenkins secret store
        MONITORING_PASS = credentials("icingatelegram-monitoring-${DEPLOY}") 
        MONITORING_USER = "icingatelegram"
        MONITORING_API = "https://icingaweb.yourmonitoringmaster.org:5665/v1/objects/services/"

        // Swarm host-specific deploy configuration
        API_PORT = "8443"
        API_PATH = "controller"
        API_HOST = "0.0.0.0"
        API_KEY = credentials("swarm-apikey-${DEPLOY}")
        // Swarm node hostname Jenkins secret store
        SWARM_HOSTNAME = credentials("swarm-hostname-${DEPLOY}")
        // SSH Passwords for Swarm node from Jenkins secret store
        SWARM_SSH_CRED = credentials("swarm-sshcred-${DEPLOY}")

}</code></pre><pre><code>"service": {
    "-1234567891234": {
        "_alias": "Administrative Tech Group",
        "routers": {
            "name": {
                "en": "&#9881;&#65039;  Network Routers ",
                "ru": "&#9881;&#65039;  &#1057;&#1077;&#1090;&#1077;&#1074;&#1099;&#1077; &#1052;&#1072;&#1088;&#1096;&#1088;&#1091;&#1090;&#1080;&#1079;&#1072;&#1090;&#1086;&#1088;&#1099;"
            },
            "type": "text",
            "endpoint": "SampleProject!services-network-routers"
        },
        "wifi": {
            "name": {
                "en": "&#127898;&#65039;  WiFi Hotspots",
                "ru": "&#127898;&#65039;  WiFi &#1058;&#1086;&#1095;&#1082;&#1080; &#1076;&#1086;&#1089;&#1090;&#1091;&#1087;&#1072;"
            },
            "type": "text",
            "endpoint": "SampleProject!services-wifi-hotspots"
        },
        "servers": {
            "name": {
                "en": "&#9881;&#65039;  Servers - Hardware",
                "ru": "&#9881;&#65039;  &#1057;&#1077;&#1088;&#1074;&#1077;&#1088;&#1099; - &#1054;&#1073;&#1086;&#1088;&#1091;&#1076;&#1086;&#1074;&#1072;&#1085;&#1080;&#1077;"
            },
            "type": "text",
            "endpoint": "SampleProject!project-servers-hardware"
        },
        "power": {
            "name": {
                "en": "&#128268;  Power Supply",
                "ru": "&#128268;  &#1069;&#1083;&#1077;&#1082;&#1090;&#1088;&#1086;&#1087;&#1080;&#1090;&#1072;&#1085;&#1080;&#1077;"
            },
            "type": "text",
            "endpoint": "SampleProject!services-project-ups-all"
        },
        "printers": {
            "name": {
                "en": "&#128424;&#65039;  Printers",
                "ru": "&#128424;&#65039;  &#1055;&#1088;&#1080;&#1085;&#1090;&#1077;&#1088;&#1099;"
            },
            "type": "text",
            "endpoint": "SampleProject!services-office-printers-toner"
        },
        "cpuload": {
            "name": {
                "en": "&#129482;  CPU Load",
                "ru": "&#129482;  &#1047;&#1072;&#1075;&#1088;&#1091;&#1079;&#1082;&#1072; &#1062;&#1055;"
            },
            "type": "image",
            "endpoint": "http://graph.yourmonitoringmaster.org/S/a"
        },
        "memory": {
            "name": {
                "en": "&#129482;  RAM Usage",
                "ru": "&#129482;  &#1048;&#1089;&#1087;&#1086;&#1083;&#1100;&#1079;&#1086;&#1074;&#1072;&#1085;&#1080;&#1077; &#1054;&#1047;&#1059;"
            },
            "type": "image",
            "endpoint": "http://graph.yourmonitoringmaster.org/S/b"
        }
    },
    "-3210987654327": {
        "_alias": "Private Tech Group",
        "server": {
            "name": {
                "en": "&#9881;&#65039;  Server summary",
                "ru": "&#9881;&#65039;  &#1054;&#1073;&#1079;&#1086;&#1088; &#1089;&#1077;&#1088;&#1074;&#1077;&#1088;&#1072;"
            },
            "type": "text",
            "endpoint": "SampleServer!host-all"
        },
        "health": {
            "name": {
                "en": "&#9881;&#65039;  Health",
                "ru": "&#9881;&#65039;  &#1047;&#1076;&#1086;&#1088;&#1086;&#1074;&#1100;&#1077;"
            },
            "type": "text",
            "endpoint": "SampleServer!host-nrpe"
        }
    }
}</code></pre><ol start="5"><li><p>Add Telegram bot token and icinga API login and password to Jenkins secrets storage:</p></li></ol><pre><code>icingatelegram-monitoring-dev: icinga-api-secret-password
icingatelegram-tgtoken-dev:  telegram-bot-token</code></pre><ol start="6"><li><p>Create new <a href="https://www.jenkins.io/doc/pipeline/tour/hello-world/">Jenkins pipeline</a> and point it to <em>deploy-icingatelegram.jenkinsfile</em> in your repo.</p></li><li><p>Run the pipeline.</p></li></ol><p><em>Note: icingatelegram stores session ID in the state memory, so your users will need to ask for access from the notification group after each time you run the build pipeline.</em></p><p></p><h4>Installation as systemd service (CentOS).</h4><p>If you wish to avoid using Docker and you are generally okay to dedicate port 443 of the host, you may set up <em>icingatelegram </em>as a systemd service on your host:</p><ol><li><p>Install prerequisites:</p></li></ol><pre><code><code>yum install openssl git nodejs npm nano -y</code></code></pre><ol start="2"><li><p>Choose directory:</p></li></ol><pre><code>cd /opt</code></pre><ol start="3"><li><p>Clone repository:</p></li></ol><pre><code>git clone https://github.com/xyhtac/icingatelegram.git</code></pre><ol start="4"><li><p>Install Nodejs dependencies:</p></li></ol><pre><code>cd /opt/icingatelegram/icingatelegram
npm install</code></pre><ol start="5"><li><p>Create SSL key and certificate:</p></li></ol><pre><code>openssl req -newkey rsa:2048 -sha256 -nodes -keyout icingatelegram.key -x509 -days 3650 -out icingatelegram.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Icinga /CN=icingatelegram-host-01.ydns.eu"</code></pre><ol start="6"><li><p>Create and edit bot configuration:</p></li></ol><pre><code>cp /opt/icingatelegram/icingatelegram/config/default.json /opt/icingatelegram/icingatelegram/config/local-dev.json
nano /opt/icingatelegram/icingatelegram/config/local-dev.json</code></pre><pre><code>{
    "defaults": {
        "verbose": "1",
        "return-button": "1",
        "defaultLang": "ru"
    },
    "telegram": {
        "host": "0.0.0.0",
        "port": "443",
        "token": "telegram_bot_token",
        "url": "https://icingatelegram-host-01.ydns.eu:443/",
        "key": "icingatelegram.key",
        "cert": "icingatelegram.pem"
    },
    "monitoring": {
        "api_url": "https://icingaweb.yourmonitoringmaster.org:5665/v1/objects/services/",
        "username": "icingatelegram",
        "password": "icinga-api-secret-password",
        "service": {
            "-1234567891234": {
                "_alias": "Administrative Tech Group",
                "routers": {
                    "name": {
                        "en": "&#9881;&#65039;  Network Routers ",
                        "ru": "&#9881;&#65039;  &#1057;&#1077;&#1090;&#1077;&#1074;&#1099;&#1077; &#1052;&#1072;&#1088;&#1096;&#1088;&#1091;&#1090;&#1080;&#1079;&#1072;&#1090;&#1086;&#1088;&#1099;"
                    },
                    "type": "text",
                    "endpoint": "SampleProject!services-network-routers"
                },
                "wifi": {
                    "name": {
                        "en": "&#127898;&#65039;  WiFi Hotspots",
                        "ru": "&#127898;&#65039;  WiFi &#1058;&#1086;&#1095;&#1082;&#1080; &#1076;&#1086;&#1089;&#1090;&#1091;&#1087;&#1072;"
                    },
                    "type": "text",
                    "endpoint": "SampleProject!services-wifi-hotspots"
                },
                "servers": {
                    "name": {
                        "en": "&#9881;&#65039;  Servers - Hardware",
                        "ru": "&#9881;&#65039;  &#1057;&#1077;&#1088;&#1074;&#1077;&#1088;&#1099; - &#1054;&#1073;&#1086;&#1088;&#1091;&#1076;&#1086;&#1074;&#1072;&#1085;&#1080;&#1077;"
                    },
                    "type": "text",
                    "endpoint": "SampleProject!project-servers-hardware"
                },
                "power": {
                    "name": {
                        "en": "&#128268;  Power Supply",
                        "ru": "&#128268;  &#1069;&#1083;&#1077;&#1082;&#1090;&#1088;&#1086;&#1087;&#1080;&#1090;&#1072;&#1085;&#1080;&#1077;"
                    },
                    "type": "text",
                    "endpoint": "SampleProject!services-project-ups-all"
                },
                "printers": {
                    "name": {
                        "en": "&#128424;&#65039;  Printers",
                        "ru": "&#128424;&#65039;  &#1055;&#1088;&#1080;&#1085;&#1090;&#1077;&#1088;&#1099;"
                    },
                    "type": "text",
                    "endpoint": "SampleProject!services-office-printers-toner"
                },
                "cpuload": {
                    "name": {
                        "en": "&#129482;  CPU Load",
                        "ru": "&#129482;  &#1047;&#1072;&#1075;&#1088;&#1091;&#1079;&#1082;&#1072; &#1062;&#1055;"
                    },
                    "type": "image",
                    "endpoint": "http://graph.yourmonitoringmaster.org/S/a"
                },
                "memory": {
                    "name": {
                        "en": "&#129482;  RAM Usage",
                        "ru": "&#129482;  &#1048;&#1089;&#1087;&#1086;&#1083;&#1100;&#1079;&#1086;&#1074;&#1072;&#1085;&#1080;&#1077; &#1054;&#1047;&#1059;"
                    },
                    "type": "image",
                    "endpoint": "http://graph.yourmonitoringmaster.org/S/b"
                }
            },
            "-3210987654327": {
                "_alias": "Private Tech Group",
                "server": {
                    "name": {
                        "en": "&#9881;&#65039;  Server summary",
                        "ru": "&#9881;&#65039;  &#1054;&#1073;&#1079;&#1086;&#1088; &#1089;&#1077;&#1088;&#1074;&#1077;&#1088;&#1072;"
                    },
                    "type": "text",
                    "endpoint": "SampleServer!host-all"
                },
                "health": {
                    "name": {
                        "en": "&#9881;&#65039;  Health",
                        "ru": "&#9881;&#65039;  &#1047;&#1076;&#1086;&#1088;&#1086;&#1074;&#1100;&#1077;"
                    },
                    "type": "text",
                    "endpoint": "SampleServer!host-nrpe"
                }
            }
        }
    },
    "interface": {
        
    }
}</code></pre><ol start="7"><li><p>Try starting bot service manually:</p></li></ol><pre><code>npm start dev</code></pre><p><em>Check console for errors and use Ctrl+C to stop nodejs instance.</em></p><ol start="8"><li><p>Copy systemd service template:</p></li></ol><pre><code>cp /opt/icingatelegram/scripts/icingatelegram.service /lib/systemd/system/icingatelegram.service</code></pre><ol start="9"><li><p>Enable and run service:</p></li></ol><pre><code>systemctl daemon-reload
systemctl enable icingatelegram
systemctl start icingatelegram</code></pre><ol start="10"><li><p>Finally, create an <a href="https://icinga.com/docs/icinga-2/latest/doc/12-icinga2-api/">API user</a> on your icinga master host:</p></li></ol><pre><code># /etc/icinga2/conf.d/api-users.conf

object ApiUser "icingatelegram" {
  password = "icinga-api-secret-password"
}</code></pre><div><hr></div><h3>Icinga Aggregation Services.</h3><p>Configuring your Telegram bot with individual buttons for each monitoring service might not be the most efficient approach, as your infrastructure is likely to comprise numerous services. The rule of thumb is to limit the amount of buttons to a maximum of ten to fit an average device screen.</p><p>The only effective workaround is to introduce aggregated services into your icinga configuration. <em>Icingatelegram </em>comes with a set of predefined aggregation services that help you to combine check results of hosts and services into one concatenated output, just like this:</p><pre><code><strong>PLUGIN OUTPUT</strong>

 OK: SERVICE DETAILS:
 * C_&#8203;BAK (snmp)&#8203;:
&#9989; snmp_&#8203;Disk C: Usage percent OK - 23 % 
&#9989; snmp_&#8203;Disk E - BACKUP: Usage percent OK - 76 % 
&#9989; snmp_&#8203;Physical Memory: Usage percent OK - 20 % 
&#9989; snmp_&#8203;cpu_&#8203;load: CPU Load percent OK - 0 % 

 * C_&#8203;FS (snmp)&#8203;:
&#9989; snmp_&#8203;Disk C: Usage percent OK - 75 % 
&#9989; snmp_&#8203;Disk E - STORAGE: Usage percent OK - 94 % 
&#9989; snmp_&#8203;Physical Memory: Usage percent OK - 18 % 
&#9989; snmp_&#8203;cpu_&#8203;load: CPU Load percent OK - 0 % 

 * C_&#8203;RDP (snmp)&#8203;:
&#9989; snmp_&#8203;Disk C: Usage percent OK - 88 % 
&#9989; snmp_&#8203;Physical Memory: Usage percent OK - 60 % 
&#9989; snmp_&#8203;cpu_&#8203;load: CPU Load percent OK - 3 % 

 * C_&#8203;DEV (snmp)&#8203;:
&#9989; snmp_&#8203;Disk C: Usage percent OK - 90 % 
&#9989; snmp_&#8203;Physical Memory: Usage percent OK - 49 % 
&#9989; snmp_&#8203;SAS_&#8203;E: Usage percent OK - 84 % 
&#9989; snmp_&#8203;cpu_&#8203;load: CPU Load percent OK - 1 % 

 * C_&#8203;PROD (snmp)&#8203;:
&#9989; snmp_&#8203;Disk C: Usage percent OK - 68 % 
&#9989; snmp_&#8203;Physical Memory: Usage percent OK - 41 % 
&#9989; snmp_&#8203;SAS_&#8203;R6_&#8203;F: Usage percent OK - 81 % 
&#9989; snmp_&#8203;SSD_&#8203;R1_&#8203;E: Usage percent OK - 82 % 
&#9989; snmp_&#8203;cpu_&#8203;load: CPU Load percent OK - 0 %</code></pre><h4>Set up aggregation services.</h4><ol><li><p>Add aggregation services to your icinga configuration. Service definitions are universal and should work well by default, no tweaks required:</p></li></ol><pre><code>conf.d/aggregation-services.conf &gt; /etc/icinga2/conf.d/</code></pre><blockquote><p>Note: <em>By default the aggregated service always return &#8216;Ok&#8217; status ignoring all statuses of listed services. This is done to avoid notifications generation by the dummy host. If you prefer the listed service state to be propagated to the dummy host, uncomment state calculation blocks.</em></p></blockquote><p></p><ol start="2"><li><p>Add <em>sample-project.conf</em> to your Icinga configuration. Change project name, rename hostgroups according to your environment.</p></li></ol><pre><code>conf.d/sample-project.conf &gt; /etc/icinga2/conf.d/</code></pre><ol start="3"><li><p>Add <em>vars.type</em> and <em>vars.project</em> to your host definitions to add them into aggregation hostgroups.</p></li><li><p>Restart icinga service for the changes to take effect.</p></li></ol><pre><code>systemctl restart icinga2</code></pre><p>Now you can add aggregated services to the configuration of your bot, i.e. <em>&#8216;SampleProject!services-office-printers-toner&#8217;</em> &#8212; you may copy this string from the URL field of your <em>icingaweb</em> on the service page.</p><p><em>Icingatelegram </em>can also deliver images, so you can send graphite diagrams on request &#8212; just put graph URL to the &#8216;endpoint&#8217; field and set &#8216;type&#8217; : &#8216;image&#8217;.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ewzt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ewzt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ewzt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ewzt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ewzt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ewzt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg" width="1456" height="364" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:364,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:196370,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ewzt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!ewzt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!ewzt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!ewzt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55c0cbce-c17a-44c1-b013-48df6a6878e3_1600x400.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a></figure></div><p></p>]]></content:encoded></item><item><title><![CDATA[Well, Github. We need to talk about it.]]></title><description><![CDATA[Do you remember those good old days when your contribution calendar was just a gimmick for us nerds? Now, HRs are known to use it as a dedication and consistency metric for their decisions.]]></description><link>https://xyhtac.substack.com/p/well-github-we-need-to-talk-about</link><guid isPermaLink="false">https://xyhtac.substack.com/p/well-github-we-need-to-talk-about</guid><dc:creator><![CDATA[Xyhtac]]></dc:creator><pubDate>Thu, 09 May 2024 13:21:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/caf4a13a-a6e3-48d3-aebd-1d725fd40ea0_240x240.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3>Takeaway keynotes.</h3><ul><li><p>My main goal of building Commitcat was to convince HR-experts to refrain from assessing developer&#8217;s Github page as a performance metric. People who don&#8217;t know how to code should not evaluate a coder's discipline with a green calendar.&nbsp;</p></li><li><p>Now you can simply throw this link <a href="https://commitcat.webflow.io/">https://commitcat.webflow.io</a> into anyone who brags about his commitment or questions yours.&nbsp;</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Tg5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Tg5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8Tg5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8Tg5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8Tg5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Tg5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg" width="1456" height="728" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:728,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77961,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8Tg5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 424w, https://substackcdn.com/image/fetch/$s_!8Tg5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 848w, https://substackcdn.com/image/fetch/$s_!8Tg5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!8Tg5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4d83b5c8-21f1-40d5-a690-b44b13cd9988_1800x900.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><h3>Bear at the party.</h3><p>I love the Github commit widget, I find it a wonderful source of motivation and just a good example of an infographic. All these everyday-commit challenges and hackathons are just a holiday, hugging everyone, you are awesome. </p><p>The bad news is, folks, that the HR-people have come to our party. It all began with cute recruiter-girls, but now a bearded personnel officer with an onion fume and evaluation checklist in his hands is shaking his dandruff in the front door of your cozy GitHub.</p><p>We all know what they&#8217;re looking for out there. They are looking for a track record of your activity as a developer. They seem to already get that it is impossible to build up a solid GitHub history in an hour, unlike a good CV. But, of course, they don&#8217;t go beyond infographics, and according to an age-old HR tradition, they don&#8217;t spend more than 10 seconds on a candidate.</p><p>This news has been coming from the wilderness for, perhaps, more than a year, from different ends of geography. Being frustrated, I sketched out a code generator scheduler and made <strong>Commitcat</strong>. But I&#8217;m not here to sell you just another SaaS, It&#8217;s about our vision.</p><p>I don&#8217;t urge you to subscribe and use this thing, but I suggest you starting a flash-mob in the spirit of postmodernism: let&#8217;s post a link to this angry cat with a description wherever possible, so that the most junior HR person in every corporation would know for sure that the Github data is polluted. There is no point in looking at the applicant&#8217;s commit calendar, there is zero happiness in it.</p><p>In case of success, we will forget about this destructive practice of technical recruiting and regain inner peace. Why wouldn&#8217;t we give it a try?</p><p></p><h3>Autocommit bot.</h3><p>Speaking of <a href="https://commitcat.webflow.io">CommitCat</a>, it's not a mobile app or a web app &#8212; it's a bot on Telegram. If you don't have Telegram, just get <a href="https://telegram.org/apps">on-boarded</a>. Now, you have a bot that handles all your settings. It works with inputs and buttons as if it were a standalone application, and gives you a really good UX. User manual has only two simple steps:</p><ol><li><p>Prepare new repository:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!nw_j!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!nw_j!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 424w, https://substackcdn.com/image/fetch/$s_!nw_j!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 848w, https://substackcdn.com/image/fetch/$s_!nw_j!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 1272w, https://substackcdn.com/image/fetch/$s_!nw_j!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!nw_j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png" width="800" height="511" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:511,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:48924,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!nw_j!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 424w, https://substackcdn.com/image/fetch/$s_!nw_j!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 848w, https://substackcdn.com/image/fetch/$s_!nw_j!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 1272w, https://substackcdn.com/image/fetch/$s_!nw_j!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F91fba739-38f1-4664-9628-fd8d7f5a2639_800x511.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p></li></ol><blockquote><p>Go to your Github and create a new private repository. It will be generating a code-like rubbish, so it's better to keep it private. Don't forget to enable <strong>Include private contributions on my profile</strong> option on <strong>Settings / Public profile.</strong></p><p>Next, go to <strong>Settings / Developer Settings / Personal access tokens</strong> and generate a <strong>fine-grained personal access token</strong>: set <strong>Expiration </strong>to a maximum of 1 year, choose <strong>Only select repositories</strong> in the <strong>Repository access</strong> section and select your newly created repo. In the <strong>Permissions </strong>section add <strong>Read and Write access</strong> for the <strong>Contents</strong> option.</p><p>Click <strong>Generate token</strong> and copy your new token.</p></blockquote><p></p><ol start="2"><li><p>Set up the bot:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!W4PZ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!W4PZ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 424w, https://substackcdn.com/image/fetch/$s_!W4PZ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 848w, https://substackcdn.com/image/fetch/$s_!W4PZ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 1272w, https://substackcdn.com/image/fetch/$s_!W4PZ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!W4PZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png" width="800" height="389" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:389,&quot;width&quot;:800,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:85164,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!W4PZ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 424w, https://substackcdn.com/image/fetch/$s_!W4PZ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 848w, https://substackcdn.com/image/fetch/$s_!W4PZ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 1272w, https://substackcdn.com/image/fetch/$s_!W4PZ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F67ace53f-13ff-4a67-9b9e-9e505b2ebfe2_800x389.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p></li></ol><blockquote><p>No registration or account activation required, no applications to install and no password to remember.</p><p>Just go to &#128100; <strong>Account </strong>/ &#9881;&#65039; <strong>Settings&nbsp; </strong>/ &#129418; <strong>Connection </strong>section of <a href="https://t.me/commitcat_bot">the bot</a> and set your Github username, repository name, your fine-grained token from Step 1 and your email.</p><p><em>Note that the email address will be used to sign your commits and it should match exactly with your Github user email.</em></p><p>If your configuration was accepted by my git client, you will see the &#128994; <strong>Activated</strong> status on the &#128100; <strong>Account </strong>frame within next 3-5 minutes.</p></blockquote><p></p><h3>Under the hood.</h3><p>Generator of <a href="https://commitcat.webflow.io/">Commitcat </a>is rather simple. It imitates syntax of the language, makes random names for vars, classes and functions. It disregards logic, so the result rubbish can't be validated as a proper code. But as long as you put it in a private repo, who cares.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!zpHk!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!zpHk!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zpHk!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zpHk!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zpHk!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!zpHk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg" width="1280" height="515" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:515,&quot;width&quot;:1280,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:73169,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!zpHk!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 424w, https://substackcdn.com/image/fetch/$s_!zpHk!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 848w, https://substackcdn.com/image/fetch/$s_!zpHk!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!zpHk!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb94517b1-489c-4dd9-97f2-2101bc2811bf_1280x515.jpeg 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p></p><p>Meanwhile, I'm testing an LLM-driven code authoring module and it creates quite promising results. It can even produce some sane-looking stuff that could be released publicly if you&#8217;d need to.</p><p>The only downside is that it puts a significant stress on my infra. I decided to release it when the project hits at least 200 recurrent subscriptions, so I could reliably spread the expenses.</p><p>Alt gen module is based on <a href="https://twitter.com/hashtag/llama3?src=hashtag_click">llama3</a>-70b with <a href="https://twitter.com/hashtag/groq?src=hashtag_click">groq</a>. Well running on my test rig, but its scaling price is considerably higher than conventional codegen.</p><h3>Alternatives and ethics.</h3><p>After the release I got comments on X with ethic concerns and descriptions for easier workarounds. Some addressed auto commit generation as spam, some noted that you don't need to do it every day &#8212; instead, you could run the script making commits with changed timestamps and have the whole chart filled overnight.</p><p>First and foremost, I am convinced that commits to your personal private repository cannot be considered a spam under any circumstance. The ideal solution, in my opinion, would be having an option on Github to silently randomize your chart. I think we will come there at some point.</p><p>Secondly, you can generate history for the past with a single transaction, true. But you will have to re-run this script every day if you want to keep up, and this is exactly what Commitcat is built for. </p><p><em>The whole point is not in actually <strong>running</strong> this kind of script and flooding your chart with unrelated data, rather in <strong>making everyone know</strong> that you can do it in a matter of single click.</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://xyhtac.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption"></p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Dockerization of Telegram bots.]]></title><description><![CDATA[Telegram offers JSON-based, accessible via a RESTful control webhook API updates to push data to the handler application running as a publicly available https server on one of valid ports (80, 443, 88 or 8443) with self-signed or CA-signed certificate.]]></description><link>https://xyhtac.substack.com/p/dockerization-of-telegram-bots</link><guid isPermaLink="false">https://xyhtac.substack.com/p/dockerization-of-telegram-bots</guid><dc:creator><![CDATA[Xyhtac]]></dc:creator><pubDate>Sat, 04 May 2024 23:49:03 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!FDMD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!FDMD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!FDMD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FDMD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FDMD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FDMD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!FDMD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg" width="1456" height="364" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:364,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:168526,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/jpeg&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!FDMD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 424w, https://substackcdn.com/image/fetch/$s_!FDMD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 848w, https://substackcdn.com/image/fetch/$s_!FDMD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 1272w, https://substackcdn.com/image/fetch/$s_!FDMD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F823491cc-406b-4ccb-ae6a-ff81c7335cb8_1600x400.jpeg 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>Telegram offers JSON-based, accessible via a RESTful control webhook API updates to push data to the handler application running as a publicly available https server on one of valid ports (80, 443, 88 or 8443) with self-signed or CA-signed certificate.</p><p>A frugal build-and-forget methodology is oftentimes preferred to avoid the costs of using fancy off-site CI/CD platforms and no-code services. Popular and well-maintained open source bot libraries widely used by developers (<a href="https://github.com/python-telegram-bot/python-telegram-bot">python-telegram-bot</a>, <a href="https://github.com/telegraf">telegraf</a>, etc) may serve several bot tokens per process, but it comes with a cost of combining multiple bot logic into one source repo.</p><p>So, here is the problem. Running multiple instances of dockerized bot applications on a single host considering a limited number of allowed ports requires nginx reverse proxy to take care of connection dispatch. Configuration of nginx has to be carefully tailored in regard with actual port settings of docker containers; nginx SSL-certificates also have to be consistent with all deployed bot applications. No external container orchestration (<a href="https://docs.docker.com/engine/swarm/">Docker Swarm</a>, etc.) and no nginx control API (i.e. <a href="https://www.nginx.com/products/nginx-unit/">Unit</a>) are allowed by the conditions of our task since we are about to fit one standalone host. Therefore, the amount of man work required to set-up and maintain single-host multi-bot dockerized infrastructure is significantly higher than the development process of the application itself.</p><p>One of the automated solutions comes with my <strong><a href="https://github.com/xyhtac/tgbot-swarm">tgbot-swarm</a></strong> CI toolkit.</p><p>To minimize efforts in bot deployment it solves two scopes of tasks:</p><ol><li><p>Provide a built-in API that employs port, path and SSL-certificate assignment mechanism and a relevant proxy config generation. In a nutshell it is a node.js/express controller application that runs in the same docker container with nginx, serves RESTful JSON-based API and sends system control signals to the local nginx process.</p></li><li><p>Provide Jenkins groovy pipelines to automate build and remote deployment (using ssh in this example) of a controller/proxy container and an arbitrary bot container based on response from the controller.</p></li></ol><p>And, as always, I would be more than happy to meet co-maintainers for this <a href="https://github.com/xyhtac/tgbot-swarm">project</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://xyhtac.substack.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Get notified on updates of tgbot-swarm.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item></channel></rss>