<?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: ZenDrx</title>
    <description>The latest articles on DEV Community by ZenDrx (@zendrx).</description>
    <link>https://dev.to/zendrx</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%2F3638290%2F8521d9b6-6d09-489f-b40f-98aeaa0426f7.jpeg</url>
      <title>DEV Community: ZenDrx</title>
      <link>https://dev.to/zendrx</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zendrx"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Wed, 06 May 2026 09:41:21 +0000</pubDate>
      <link>https://dev.to/zendrx/-57f3</link>
      <guid>https://dev.to/zendrx/-57f3</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/zendrx/telegem-v340-is-out-bot-api-96-redis-store-and-looking-back-at-45-months-of-building-4edj" class="crayons-story__hidden-navigation-link"&gt;Telegem v3.4.0 is out – Bot API 9.6, Redis store, and looking back at 4.5 months of building&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/zendrx" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3638290%2F8521d9b6-6d09-489f-b40f-98aeaa0426f7.jpeg" alt="zendrx profile" class="crayons-avatar__image" width="800" height="1062"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/zendrx" class="crayons-story__secondary fw-medium m:hidden"&gt;
              ZenDrx
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                ZenDrx
                
              
              &lt;div id="story-author-preview-content-3619776" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/zendrx" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3638290%2F8521d9b6-6d09-489f-b40f-98aeaa0426f7.jpeg" class="crayons-avatar__image" alt="" width="800" height="1062"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;ZenDrx&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/zendrx/telegem-v340-is-out-bot-api-96-redis-store-and-looking-back-at-45-months-of-building-4edj" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 6&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/zendrx/telegem-v340-is-out-bot-api-96-redis-store-and-looking-back-at-45-months-of-building-4edj" id="article-link-3619776"&gt;
          Telegem v3.4.0 is out – Bot API 9.6, Redis store, and looking back at 4.5 months of building
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag crayons-tag--filled  " href="/t/showdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;showdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ruby"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ruby&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/telegram"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;telegram&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/zendrx/telegem-v340-is-out-bot-api-96-redis-store-and-looking-back-at-45-months-of-building-4edj#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              &lt;span class="hidden s:inline"&gt;Add Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Telegem v3.4.0 is out – Bot API 9.6, Redis store, and looking back at 4.5 months of building</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Wed, 06 May 2026 09:07:46 +0000</pubDate>
      <link>https://dev.to/zendrx/telegem-v340-is-out-bot-api-96-redis-store-and-looking-back-at-45-months-of-building-4edj</link>
      <guid>https://dev.to/zendrx/telegem-v340-is-out-bot-api-96-redis-store-and-looking-back-at-45-months-of-building-4edj</guid>
      <description>&lt;p&gt;I started Telegem on December 20, 2025. I didn't plan to build a full Telegram framework. I just wanted something faster than &lt;code&gt;telegram-bot-ruby&lt;/code&gt;, something that didn't block, something that felt right in Ruby.&lt;/p&gt;

&lt;p&gt;Today, I'm releasing &lt;strong&gt;v3.4.0&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's New
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bot API 9.6 full support&lt;/strong&gt; – managed bots, polls overhaul, &lt;code&gt;sendMessageDraft&lt;/code&gt;, and all the new update types.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis session store&lt;/strong&gt; – for horizontal scaling across multiple webhook instances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Translate plugin&lt;/strong&gt; – built-in translation using the Lingva API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Removed concurrent-ruby&lt;/strong&gt; – lighter footprint, fewer dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better error messages&lt;/strong&gt; – improved feedback for invalid middleware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby 3.1+ support&lt;/strong&gt; – fully tested and verified.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why v3.4.0 Matters
&lt;/h2&gt;

&lt;p&gt;The Telegram Bot API changes fast. Most Ruby wrappers lag behind. With v3.4.0, Telegem is fully aligned with Telegram's April 2026 release – managed bots, polls with multiple correct answers, the works.&lt;/p&gt;

&lt;p&gt;The Redis store is the other big one. Until now, sessions lived in memory. That's fine for one process. For webhook mode with multiple workers? You needed shared storage. Now you have it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Back at 4.5 Months
&lt;/h2&gt;

&lt;p&gt;I pushed the first commit on December 20, 2025. Since then, Telegem has grown to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;46 versions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;~71,000 total downloads&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full async architecture&lt;/strong&gt; (built on &lt;a href="https://github.com/socketry/async" rel="noopener noreferrer"&gt;Async&lt;/a&gt;, not threads)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook server with SSL&lt;/strong&gt; (no Rack required)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scenes, sessions, rate limiting, middleware&lt;/strong&gt; – all the things you expect from a modern framework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not everyone found it. Not everyone stayed. But thousands of developers tried it, and that's more than I expected when I started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;I'm not adding features for the sake of features. Telegem is stable. The next work will be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lowering the Ruby requirement&lt;/strong&gt; back to 3.1 (v3.4.0 incorrectly bumped it to 3.4 – fixing it in the next patch).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;More docs&lt;/strong&gt; for advanced patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proper plugin system&lt;/strong&gt; – making it easier for the community to extend the core.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Get It
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
bash
gem install telegem

Or in your Gemfile:

gem 'telegem', '~&amp;gt; 3.4.0'

&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/slick-lab" rel="noopener noreferrer"&gt;
        slick-lab
      &lt;/a&gt; / &lt;a href="https://github.com/slick-lab/telegem" rel="noopener noreferrer"&gt;
        telegem
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A complete async first framework for building telegram bots in ruby 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Telegem Documentation&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Welcome to the comprehensive documentation for Telegem, a modern Ruby framework for building Telegram bots.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/slick-lab/telegem/actions/workflows/github-code-scanning/codeql" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/slick-lab/telegem/actions/workflows/github-code-scanning/codeql/badge.svg" alt="CodeQl"&gt;&lt;/a&gt;
&lt;a href="https://badge.fury.io/rb/telegem" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/edda1c9df18a1a896a2423479784c22a28f58611188528a3b10e4dd733051f79/68747470733a2f2f62616467652e667572792e696f2f72622f74656c6567656d2e737667" alt="Gem Version"&gt;&lt;/a&gt;
&lt;a href="https://t.me/r_telegem" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/4110983e24bffeafbbbf6d950123c213903528a40279d09fca79120278018cdf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f54656c656772616d2d4a6f696e25323047726f75702d3243413545303f7374796c653d666c61742d737175617265266c6f676f3d74656c656772616d266c6f676f436f6c6f723d7768697465" alt="Join Telegram Group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Getting Started&lt;/h3&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/README.md" rel="noopener noreferrer"&gt;README&lt;/a&gt; - Main project README&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/getting_started.md" rel="noopener noreferrer"&gt;Getting Started&lt;/a&gt; - Installation and basic setup&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/core_concepts.md" rel="noopener noreferrer"&gt;Core Concepts&lt;/a&gt; - Understanding Telegem architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Core Components&lt;/h3&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/bot.md" rel="noopener noreferrer"&gt;Bot&lt;/a&gt; - Main bot class and configuration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/context.md" rel="noopener noreferrer"&gt;Context&lt;/a&gt; - Update context and response methods&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/handlers.md" rel="noopener noreferrer"&gt;Handlers&lt;/a&gt; - Command, hears, and event handlers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/middleware.md" rel="noopener noreferrer"&gt;Middleware&lt;/a&gt; - Request processing pipeline&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/scenes.md" rel="noopener noreferrer"&gt;Scenes&lt;/a&gt; - Multi-step conversation flows&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/sessions.md" rel="noopener noreferrer"&gt;Sessions&lt;/a&gt; - Data persistence between updates&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;API &amp;amp; Types&lt;/h3&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/api.md" rel="noopener noreferrer"&gt;API&lt;/a&gt; - Telegram API client usage&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/types.md" rel="noopener noreferrer"&gt;Types&lt;/a&gt; - Type-safe API response handling&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/keyboards.md" rel="noopener noreferrer"&gt;Keyboards&lt;/a&gt; - Inline and reply keyboard DSL&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Advanced Features&lt;/h3&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/plugins.md" rel="noopener noreferrer"&gt;Plugins&lt;/a&gt; - Built-in and custom plugins&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/webhooks.md" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt; - Production webhook deployment&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/error_handling.md" rel="noopener noreferrer"&gt;Error Handling&lt;/a&gt; - Comprehensive error management&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/testing.md" rel="noopener noreferrer"&gt;Testing&lt;/a&gt; - Unit and integration testing&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/slick-lab/telegem/deployment.md" rel="noopener noreferrer"&gt;Deployment&lt;/a&gt; - Production deployment guides&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Examples &amp;amp; Guides&lt;/h3&gt;

&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;a href="https://github.com/slick-lab/telegem/examples.md" rel="noopener noreferrer"&gt;Examples&lt;/a&gt; - Complete bot examples&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/slick-lab/telegem/troubleshooting.md" rel="noopener noreferrer"&gt;Troubleshooting&lt;/a&gt; - Common issues and solutions&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/slick-lab/telegem/contributing.md" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt; - Development guidelines&lt;/li&gt;

&lt;li&gt;

&lt;a href="https://github.com/slick-lab/telegem/changelog.md" rel="noopener noreferrer"&gt;Changelog&lt;/a&gt;…&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/slick-lab/telegem" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;h3&gt;
  
  
  Community
&lt;/h3&gt;

&lt;p&gt;Join the conversation and get help in the official group:&lt;br&gt;
&lt;a href="https://t.me/r_telegem" class="crayons-btn crayons-btn--primary" rel="noopener noreferrer"&gt;Join the Telegram Group&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I don't know where Telegem will be a year from now. But I know it's already a better foundation than anything else in Ruby for building Telegram bots.&lt;/p&gt;

&lt;p&gt;I'm curious—for those building bots in Ruby, what's your biggest pain point with current libraries? I'd love to see if Telegem can solve it for you.&lt;/p&gt;

&lt;p&gt;– ZenDrx&lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>ruby</category>
      <category>showdev</category>
      <category>telegram</category>
      <category>opensource</category>
    </item>
    <item>
      <title>The Rumor That Coding Equals a Stable Income is False</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Tue, 28 Apr 2026 18:08:16 +0000</pubDate>
      <link>https://dev.to/zendrx/the-rumor-that-coding-equals-a-stable-income-is-false-ald</link>
      <guid>https://dev.to/zendrx/the-rumor-that-coding-equals-a-stable-income-is-false-ald</guid>
      <description>&lt;p&gt;I've been coding since I was 16. And I have never made a single dollar from it.&lt;/p&gt;

&lt;p&gt;Let that sink in.&lt;/p&gt;

&lt;p&gt;Not because I didn't try. Not because I didn't want to. I wanted it badly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Junior Struggle
&lt;/h2&gt;

&lt;p&gt;I remember submitting application after application to companies. Dozens. Maybe more. But that junior role? It feels like climbing Mount Everest with no gear.&lt;/p&gt;

&lt;p&gt;Most of them want at least 5 years of experience for an entry-level job. Make it make sense. It honestly feels like if you don't lie on your CV, you're not getting in the door.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Freelance Reality and the AI Shift
&lt;/h2&gt;

&lt;p&gt;Freelancing? Don't even get me started. It's harder than ever to land a client. Why would someone hire a junior dev when they can go to Claude, type a prompt, and have a working website in ten minutes?&lt;/p&gt;

&lt;p&gt;I'm not saying don't learn to code. I'm saying code because you love it. Code because it's fun. Code because it makes you feel like a creator. &lt;/p&gt;


&lt;div class="crayons-card c-embed"&gt;

  &lt;br&gt;
&lt;strong&gt;The Core Truth:&lt;/strong&gt;&lt;br&gt;
Don't code because someone told you it's a guaranteed paycheck. Because right now? It's not.&lt;br&gt;

&lt;/div&gt;


&lt;h2&gt;
  
  
  Why I'm Still Here
&lt;/h2&gt;

&lt;p&gt;Yeah, devs at big companies are making massive money. Good for them. But most of them started before the AI bubble. Before everyone and their mom got into tech. Before the market got this crowded.&lt;/p&gt;

&lt;p&gt;I'm still coding. I still love it. But I wish someone had told me the truth earlier.&lt;/p&gt;

&lt;p&gt;So here I am, telling you: &lt;strong&gt;Code for the joy of it. Not for the money. Because the money might never come.&lt;/strong&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Let's Discuss
&lt;/h3&gt;

&lt;p&gt;I’m curious to hear from others in the same boat. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are you currently applying for roles? How does the market feel from your perspective?&lt;/li&gt;
&lt;li&gt;For those who &lt;em&gt;did&lt;/em&gt; land a job recently, what was the "secret sauce" that got you through the door?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;I'll be in the comments to talk more about this.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>carrer</category>
      <category>discuss</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>From Ruby to Crystal: Why I ported telegem to telecr</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Wed, 15 Apr 2026 10:30:22 +0000</pubDate>
      <link>https://dev.to/zendrx/from-ruby-to-crystal-why-i-ported-telegem-to-telecr-29m</link>
      <guid>https://dev.to/zendrx/from-ruby-to-crystal-why-i-ported-telegem-to-telecr-29m</guid>
      <description>&lt;p&gt;After my work on &lt;strong&gt;telegem&lt;/strong&gt; (a Ruby gem for creating DSLs), I began to notice the stark differences between interpreted and compiled languages. &lt;/p&gt;

&lt;p&gt;Ruby is fast, but for high-concurrency needs like Telegram bots, I wanted to see what &lt;strong&gt;Crystal&lt;/strong&gt; could do. To my surprise, porting the logic worked beautifully. Today, I’m excited to announce &lt;strong&gt;telecr&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Telecr?
&lt;/h2&gt;

&lt;p&gt;Telecr is a fast, fiber-based library for creating Telegram bots in Crystal. Think of it as &lt;strong&gt;telegem&lt;/strong&gt; with superpowers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blazing Fast:&lt;/strong&gt; Leverages Crystal's performance and fiber-based concurrency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Type Safe:&lt;/strong&gt; Catch errors at compile time before they hit production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disk Backup:&lt;/strong&gt; Reliable data handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean DSL:&lt;/strong&gt; Designed for a great developer experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Look at the DSL
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight crystal"&gt;&lt;code&gt; &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt; 
   &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"welcome"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Join the Project
&lt;/h2&gt;

&lt;p&gt;I'm officially opening this up for contributions and improvements! You can find the source code and documentation here:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/slick-lab" rel="noopener noreferrer"&gt;
        slick-lab
      &lt;/a&gt; / &lt;a href="https://github.com/slick-lab/telecr" rel="noopener noreferrer"&gt;
        telecr
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A modern fiber based crystal framework for create telegram bots 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Telecr&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Telegram bot framework for Crystal. Inspired by telegem (Ruby).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.com/telegem-cr/telecr/-/pipelines" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/754a7117bacdd1bc0a1ec36ac12560458e29e4117277e7218bd76a4f61756511/68747470733a2f2f6769746c61622e636f6d2f74656c6567656d2d63722f74656c6563722f6261646765732f6d61696e2f706970656c696e652e737667" alt="Pipeline Status"&gt;&lt;/a&gt;
&lt;a href="https://gitlab.com/telegem-cr/telecr/-/jobs" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7048465af4c7cf561c9a8ea2c08c4ffc8d910e9dae556b4ccb46aabfae05028a/68747470733a2f2f6769746c61622e636f6d2f74656c6567656d2d63722f74656c6563722f6261646765732f6d61696e2f636f7665726167652e737667" alt="Coverage"&gt;&lt;/a&gt;
&lt;a href="https://gitlab.com/telegem-cr/telecr/-/releases" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/ffc6cad9864aa86680af6b5937defffa8ece46783321fa3aab567f52b4b88e09/68747470733a2f2f6769746c61622e636f6d2f74656c6567656d2d63722f74656c6563722f2d2f6261646765732f72656c656173652e737667" alt="Latest Release"&gt;&lt;/a&gt;
&lt;a href="https://crystal-lang.org" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/f46a981a992e98567768f42816efea994d39c1db57ea30625e53982476ac7f1b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6372797374616c2d312e302b2d626c61636b" alt="Crystal"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667" alt="License: MIT"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Documentation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Full API documentation is available at: &lt;a href="https://telecr-f83754.gitlab.io" rel="nofollow noopener noreferrer"&gt;https://telecr.gitlab.io&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Add to your &lt;code&gt;shard.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight highlight-source-yaml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-ent"&gt;dependencies&lt;/span&gt;:
  &lt;span class="pl-ent"&gt;telecr&lt;/span&gt;:
    &lt;span class="pl-ent"&gt;github&lt;/span&gt;: &lt;span class="pl-s"&gt;slick-lab/telecr&lt;/span&gt;
    &lt;span class="pl-ent"&gt;version&lt;/span&gt;: &lt;span class="pl-s"&gt;~&amp;gt; 1.0.0&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then run:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;shards install&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Quick Start&lt;/p&gt;
&lt;div class="highlight highlight-source-crystal notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;require&lt;/span&gt; &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;telecr&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;

bot &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-c1"&gt;Telecr&lt;/span&gt;.new(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;YOUR_BOT_TOKEN&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)

bot.command(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;start&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;) &lt;span class="pl-k"&gt;do&lt;/span&gt; |&lt;span class="pl-smi"&gt;ctx&lt;/span&gt;|
  ctx.reply(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Welcome to Telecr!&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)
&lt;span class="pl-k"&gt;end&lt;/span&gt;

bot.start_polling&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Features&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Full Telegram Bot API support&lt;/li&gt;
&lt;li&gt;Polling and webhook modes&lt;/li&gt;
&lt;li&gt;Middleware system (session, rate limiting, file upload)&lt;/li&gt;
&lt;li&gt;Reply and inline keyboards&lt;/li&gt;
&lt;li&gt;Type-safe context objects&lt;/li&gt;
&lt;li&gt;Session management with disk backup&lt;/li&gt;
&lt;li&gt;File upload to shrine storage&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage&lt;/p&gt;
&lt;p&gt;Basic Bot&lt;/p&gt;
&lt;div class="highlight highlight-source-crystal notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;bot &lt;span class="pl-k"&gt;=&lt;/span&gt; &lt;span class="pl-c1"&gt;Telecr&lt;/span&gt;.new(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;TOKEN&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)

bot.command(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;start&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;) &lt;span class="pl-k"&gt;do&lt;/span&gt; |&lt;span class="pl-smi"&gt;ctx&lt;/span&gt;|
  ctx.reply(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Hello! I'm a Telecr bot.&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)
&lt;span class="pl-k"&gt;end&lt;/span&gt;

bot.hears(&lt;span class="pl-sr"&gt;/hi/i&lt;/span&gt;) &lt;span class="pl-k"&gt;do&lt;/span&gt; |&lt;span class="pl-smi"&gt;ctx&lt;/span&gt;|
  ctx.reply(&lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;"&lt;/span&gt;Hi there!&lt;span class="pl-pds"&gt;"&lt;/span&gt;&lt;/span&gt;)
&lt;span class="pl-k"&gt;end&lt;/span&gt;

bot.start_polling&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/slick-lab/telecr" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;I'm curious—have any of you moved a project from Ruby to Crystal? What was your biggest "aha!" moment during the port?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>crystal</category>
      <category>telegram</category>
      <category>showdev</category>
    </item>
    <item>
      <title>From Ruby to Crystal a detailed guide</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Sun, 15 Mar 2026 12:04:08 +0000</pubDate>
      <link>https://dev.to/youngsoftwaredev/from-ruby-to-crystal-a-detailed-guide-3dde</link>
      <guid>https://dev.to/youngsoftwaredev/from-ruby-to-crystal-a-detailed-guide-3dde</guid>
      <description>&lt;p&gt;I love Ruby. I still maintain telegem, a Telegram bot framework used by real people. Ruby pays my bills and makes me happy.&lt;/p&gt;

&lt;p&gt;But I also wanted speed. I wanted binaries. I wanted to stop debugging "undefined method for nil" at 3 AM.&lt;/p&gt;

&lt;p&gt;So I tried Crystal.&lt;/p&gt;

&lt;p&gt;It looked just like Ruby. I was confident. Then the compiler yelled at me. For days. For weeks. For 64 failed pipelines.&lt;/p&gt;

&lt;p&gt;This guide is what I wish I had on day one.&lt;/p&gt;

&lt;p&gt;The Complete Guide: Ruby to Crystal&lt;/p&gt;

&lt;p&gt;I just published a comprehensive, free guide for Rubyists moving to Crystal. It covers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Quick Comparison - The "looks the same" trap&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Side-by-side code examples showing where Ruby and Crystal diverge. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &amp;amp;. Problem - Why your favorite operator will fight you&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;How safe navigation works (and doesn't work) in Crystal, and the reliable patterns that always compile. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type System - Friend, not foe&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Understanding union types, nil checking, and why the compiler is actually saving you. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hashes &amp;amp; Collections - NamedTuples will surprise you&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The three ways to store data in Crystal and when to use each. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Classes &amp;amp; Modules - Same but different&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instance variables, property shortcuts, and why self. sometimes saves the day. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Require Order - The dependency dance&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why order matters and how to structure your project to avoid headaches. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Common Errors Decoded - What the compiler is actually saying&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A translator for those scary error messages. Read →&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Why Crystal - The case for switching&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Performance, safety, and peace of mind. Read →&lt;/p&gt;

&lt;p&gt;🛠 Projects Built While Learning&lt;/p&gt;

&lt;p&gt;The guide is free, but if you want to see real Crystal code, check out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tg-auth - Telegram authentication for Crystal&lt;/li&gt;
&lt;li&gt;telecr - Telegram bot framework (the Crystal version of telegem)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📖 Read the Guide&lt;/p&gt;

&lt;p&gt;GitHub Repo: slick-phantom/ruby-crystal&lt;/p&gt;

&lt;p&gt;The guide is completely free, open source, and ready for contributions. If you find something confusing, open an issue. If you want to improve it, send a PR.&lt;/p&gt;




&lt;p&gt;Ruby gave me joy. Crystal gives me peace&lt;/p&gt;

</description>
      <category>learning</category>
      <category>performance</category>
      <category>ruby</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>I got tired or rewriting the same blog backend so I created a solution</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Sun, 01 Mar 2026 10:28:35 +0000</pubDate>
      <link>https://dev.to/zendrx/i-got-tired-or-rewriting-the-same-blog-backend-so-i-created-a-solution-55ga</link>
      <guid>https://dev.to/zendrx/i-got-tired-or-rewriting-the-same-blog-backend-so-i-created-a-solution-55ga</guid>
      <description>&lt;p&gt;Inkwell v0.1 — A lightweight, binary-compiled blog engine for developers who just want to ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;A client asked me to build a blog site. Cool. Built it.&lt;/p&gt;

&lt;p&gt;Another client asked. Same thing. Built it again.&lt;/p&gt;

&lt;p&gt;Third time? I caught myself writing the &lt;strong&gt;same create/post/delete/admin logic&lt;/strong&gt; from scratch. Again.&lt;/p&gt;

&lt;p&gt;I thought: &lt;em&gt;There has to be a better way.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Search
&lt;/h2&gt;

&lt;p&gt;I went looking. Surely someone has solved this.&lt;/p&gt;

&lt;p&gt;Found some stuff on GitHub. Looked promising until I dug deeper.&lt;/p&gt;

&lt;p&gt;Good features? Locked behind paywalls.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Blog engine shouldn't be paid for.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So I decided to build one myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Build
&lt;/h2&gt;

&lt;p&gt;I needed something:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compiled to binary&lt;/strong&gt; — runs anywhere, no dependencies&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast&lt;/strong&gt; — no slow interpreted stuff&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No bloat&lt;/strong&gt; — does one thing well&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Started with Go. Made sense. But I was still learning and progress was slow.&lt;/p&gt;

&lt;p&gt;Switched to Dart. Things clicked. Built the core logic. Struggled through some parts. Learned a ton. Kept going.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Inkwell v0.1
&lt;/h2&gt;

&lt;p&gt;It's basic. It's buggy. &lt;strong&gt;It works.&lt;/strong&gt;&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;-sSL&lt;/span&gt; &lt;span class="s2"&gt;"https://gitlab.com/dart.co/inkwell/-/raw/main/install.sh"&lt;/span&gt; | bash
./inkwell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First run generates an admin token. Save it. Use it for X-API-KEY headers.&lt;/p&gt;

&lt;p&gt;What It Does&lt;/p&gt;

&lt;p&gt;For readers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET /posts — list all blog posts (reads from posts/ folder)

&lt;ul&gt;
&lt;li&gt;GET /posts/:slug — get a single post as markdown&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;GET /search?q=query — search posts by filename and content&lt;/li&gt;

&lt;li&gt;GET /feed.xml — RSS feed&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;For you (admin):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;POST /admin/posts — create new post&lt;/li&gt;
&lt;li&gt;PUT /admin/posts/:slug — update post&lt;/li&gt;
&lt;li&gt;DELETE /admin/posts/:slug — delete post&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All admin endpoints need your X-API-KEY.&lt;/p&gt;

&lt;p&gt;How It Works&lt;/p&gt;

&lt;p&gt;send posts to the create endpoint or read the Readme&lt;/p&gt;

&lt;p&gt;The API reads them, serves them, searches them. No database. No config. No paywall.&lt;/p&gt;

&lt;p&gt;The Current State&lt;/p&gt;

&lt;p&gt;v0.1 is a prototype. I'll be honest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Core features work (create, read, search, RSS)&lt;/li&gt;
&lt;li&gt;⚠️ Storage is just files (not fully safe, but lightweight)
-🐛 It's buggy in places&lt;/li&gt;
&lt;li&gt;🔧 Better storage solution coming in future versions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for a solo dev who just wants to blog without the bloat? It gets the job done.&lt;/p&gt;

&lt;p&gt;What's Next&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix the bugs (help welcome!)&lt;/li&gt;
&lt;li&gt;Find a better storage solution (keeping it lightweight)&lt;/li&gt;
&lt;li&gt;Stable v1&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try It&lt;br&gt;
&lt;a href="https://gitlab.com/dart.co/inkwell" rel="noopener noreferrer"&gt;git&lt;/a&gt;&lt;br&gt;
Star it if you like the idea. Open issues if you find bugs. PRs if you want to help.&lt;/p&gt;

&lt;p&gt;Or just use it and tell me what sucks. I can take it.&lt;/p&gt;

&lt;p&gt;Built because rewriting the same code three times is two times too many.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>blog</category>
      <category>backend</category>
    </item>
    <item>
      <title>Ubuntu: From "Linux for Human Beings" to "Linux for People with Fiber Optics"</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Mon, 16 Feb 2026 11:12:57 +0000</pubDate>
      <link>https://dev.to/zendrx/ubuntu-from-linux-for-human-beings-to-linux-for-people-with-fiber-optics-2jkp</link>
      <guid>https://dev.to/zendrx/ubuntu-from-linux-for-human-beings-to-linux-for-people-with-fiber-optics-2jkp</guid>
      <description>&lt;p&gt;I've been using Ubuntu for a while now. It was my first Linux distro — the one everyone recommended. "It just works," they said.&lt;/p&gt;

&lt;p&gt;It doesn't anymore.&lt;/p&gt;




&lt;p&gt;What Used to Be Good&lt;/p&gt;

&lt;p&gt;Remember when installing software was simple?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;spotify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command. Done. No drama.&lt;/p&gt;

&lt;p&gt;Ubuntu was the gateway drug to Linux. It was intuitive. It respected that not everyone has Google Fiber.&lt;/p&gt;




&lt;p&gt;What Changed&lt;/p&gt;

&lt;p&gt;Now try installing Spotify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;snap &lt;span class="nb"&gt;install &lt;/span&gt;spotify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks simple. But behind the scenes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;core20 (20.04) 2024-05-07 from Canonical✓ downloaded
Wait... still downloading...
Error: Network failure
Retry? [y/N]:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your internet fails during download? Start over from scratch.&lt;/p&gt;




&lt;p&gt;The Runtime Nightmare&lt;/p&gt;

&lt;p&gt;Every Snap app brings its own runtime baggage:&lt;/p&gt;

&lt;p&gt;· Telegram needs core18&lt;br&gt;
· Spotify needs core20&lt;br&gt;
· VLC needs core22&lt;br&gt;
· Something else needs core24&lt;/p&gt;

&lt;p&gt;That's four copies of essentially the same thing. Hundreds of megabytes each. Duplicated. Wasted.&lt;/p&gt;

&lt;p&gt;My system now has multiple core runtimes taking up space. For what? So Canonical can push Snap?&lt;/p&gt;




&lt;p&gt;Who Is This For?&lt;/p&gt;

&lt;p&gt;The current Ubuntu experience assumes:&lt;/p&gt;

&lt;p&gt;· ✅ Fast, unlimited internet&lt;br&gt;
· ✅ New hardware with storage to waste&lt;br&gt;
· ✅ Time to troubleshoot failed downloads&lt;br&gt;
· ✅ No concern about data costs&lt;/p&gt;

&lt;p&gt;That's not "Linux for human beings." That's "Linux for privileged beings."&lt;/p&gt;




&lt;p&gt;What About the Rest of Us?&lt;/p&gt;

&lt;p&gt;· Students with old laptops&lt;br&gt;
· People in areas with bad internet&lt;br&gt;
· Anyone paying per megabyte&lt;br&gt;
· Users who just want things to work&lt;/p&gt;

&lt;p&gt;We exist. We're just not the target audience anymore.&lt;/p&gt;




&lt;p&gt;The Alternative&lt;/p&gt;

&lt;p&gt;Linux Mint Xfce.&lt;/p&gt;

&lt;p&gt;· No Snap by default&lt;br&gt;
· Normal apt packages&lt;br&gt;
· Flatpak if needed (one runtime for all)&lt;br&gt;
· Actually works offline&lt;br&gt;
· Runs well on older hardware&lt;/p&gt;

&lt;p&gt;One install. Apps install immediately. No core18/core20/core22 madness.&lt;/p&gt;

&lt;p&gt;It's what Ubuntu used to be.&lt;/p&gt;




&lt;p&gt;Bottom Line&lt;/p&gt;

&lt;p&gt;Ubuntu had a good run. But it's no longer for everyone.&lt;/p&gt;

&lt;p&gt;If you're struggling with forced Snap, duplicate runtimes, and offline installs that fail — you're not alone. And there are better options.&lt;/p&gt;

&lt;p&gt;Sometimes the most popular choice isn't the right choice anymore.&lt;/p&gt;

&lt;p&gt;Now am not criticizing Ubuntu it’s a great distro with gnome as default it’s cool with slick designs but the snap canonical is pushing is a terrible idea &lt;/p&gt;




</description>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>Telegem first public plugin</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Thu, 05 Feb 2026 11:33:11 +0000</pubDate>
      <link>https://dev.to/zendrx/telegem-first-public-plugin-e7j</link>
      <guid>https://dev.to/zendrx/telegem-first-public-plugin-e7j</guid>
      <description>&lt;h2&gt;
  
  
  Extract PDFs, JSON &amp;amp; HTML in Your Telegram Bot with Telegem's New Plugin
&lt;/h2&gt;

&lt;p&gt;Building a Telegram bot that processes documents? Stop wrestling with file parsing. Telegem's new &lt;code&gt;FileExtractor&lt;/code&gt; plugin lets you extract text from PDFs, parse JSON, and process HTML files in 3 lines of Ruby.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What This Solves
&lt;/h2&gt;

&lt;p&gt;Before: Your users send PDFs/JSON files → You write 50+ lines of parsing code + install dependencies + handle edge cases.&lt;/p&gt;

&lt;p&gt;After: Your users send files → You call one method → Get clean extracted text.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# In your Gemfile&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'telegem'&lt;/span&gt;

&lt;span class="c1"&gt;# Install the optional dependency for PDF support&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s1"&gt;'pdf-reader'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎯 Real-World Examples&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;PDF Invoice Processor
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'invoice'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mime_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'application/pdf'&lt;/span&gt;
    &lt;span class="n"&gt;extractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plugins&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FileExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:success&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="c1"&gt;# Find amounts in invoice text&lt;/span&gt;
      &lt;span class="n"&gt;amounts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;scan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\$\d+\.\d{2}/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"📊 Found &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;amounts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; payment amounts"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;JSON Config Validator
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;document: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end_with?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'.json'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;extractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plugins&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FileExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:success&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"✅ Valid JSON with &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; keys"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"❌ Invalid JSON: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;HTML to Markdown Converter
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'html'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mime_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'text/html'&lt;/span&gt;
    &lt;span class="n"&gt;extractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plugins&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FileExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;html&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:success&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="c1"&gt;# Convert HTML to plain text (simplified)&lt;/span&gt;
      &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:content&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"📝 Extracted &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; characters"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔧 How It Works Under the Hood&lt;/p&gt;

&lt;p&gt;The plugin handles the tedious parts for you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Downloads the file from Telegram's servers&lt;/li&gt;
&lt;li&gt;Auto detects file type&lt;/li&gt;
&lt;li&gt;Processes it with the appropriate library (PDF::Reader for PDFs, JSON.parse for JSON)&lt;/li&gt;
&lt;li&gt;Cleans up temp files automatically&lt;/li&gt;
&lt;li&gt;Returns a consistent hash format:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;success: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;content: &lt;/span&gt;&lt;span class="s2"&gt;"Extracted text here..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;pages: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;           &lt;span class="c1"&gt;# PDF only&lt;/span&gt;
  &lt;span class="ss"&gt;file_size: &lt;/span&gt;&lt;span class="mi"&gt;45210&lt;/span&gt;    &lt;span class="c1"&gt;# All file types&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Important Security Notes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ✅ SAFE - Use only Telegram-generated file_ids&lt;/span&gt;
&lt;span class="n"&gt;extractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plugins&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FileExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# From Telegram context&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# ❌ DANGEROUS - Never use user input&lt;/span&gt;
&lt;span class="n"&gt;extractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plugins&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FileExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:user_input&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="c1"&gt;# Malicious users could hack your server&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎨 Advanced: Processing Replies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Extract from replied-to PDFs&lt;/span&gt;
&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'extract'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply_to_message&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;
    &lt;span class="n"&gt;file_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply_to_message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file_id&lt;/span&gt;

    &lt;span class="n"&gt;extractor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Plugins&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FileExtractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;file_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;file_type: :pdf&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extractor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract_pdf&lt;/span&gt;

    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:success&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;"✅ Done"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"❌ Failed: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📈 Why This Matters&lt;/p&gt;

&lt;p&gt;Most bot frameworks make you handle file parsing manually. Telegem's approach:&lt;/p&gt;

&lt;p&gt;· Reduces boilerplate from 50+ lines to 3&lt;br&gt;
· Handles edge cases (encrypted PDFs, malformed JSON)&lt;br&gt;
· Auto-cleans temp files (no memory leaks)&lt;br&gt;
· Works seamlessly with Telegem's async architecture&lt;/p&gt;

&lt;p&gt;🚀 Get Started&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a new bot&lt;/span&gt;
gem &lt;span class="nb"&gt;install &lt;/span&gt;telegem

&lt;span class="c"&gt;# Check out the full example&lt;/span&gt;
git clone https://gitlab.com/ruby-telegem/telegem-examples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💬 Your Turn&lt;/p&gt;

&lt;p&gt;What document processing tasks are you building with Telegram bots? Have you tried Telegem's new plugin? Share your use cases below!&lt;/p&gt;




&lt;p&gt;Telegem is a modern, async-first Telegram Bot framework for Ruby. Built with ❤️ by @slick_phantom.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>opensource</category>
      <category>news</category>
    </item>
    <item>
      <title>Why should we choose telegem over telegram-bot-ruby a established gem</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Sun, 18 Jan 2026 19:42:38 +0000</pubDate>
      <link>https://dev.to/zendrx/why-should-we-choose-telegem-over-telegram-bot-ruby-a-established-gem-2kf6</link>
      <guid>https://dev.to/zendrx/why-should-we-choose-telegem-over-telegram-bot-ruby-a-established-gem-2kf6</guid>
      <description>&lt;h2&gt;
  
  
  In this post we are going to be two giants
&lt;/h2&gt;

&lt;p&gt;providing ways to create telegram bots &lt;/p&gt;

&lt;p&gt;Let’s take a deep dive into telegram-bot-ruby&lt;/p&gt;

&lt;h2&gt;
  
  
  telegram-bot-ruby
&lt;/h2&gt;

&lt;p&gt;telegram-bot-ruby as I will call it tbr is a very good gem for creating telegram bots &lt;br&gt;
it was quickly adopted by rubyist with many tutorials on sitepoint medium…&lt;br&gt;
example code of tbr&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;  &lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'telegram/bot'&lt;/span&gt;

&lt;span class="c1"&gt;# Get your token from @BotFather on Telegram&lt;/span&gt;
&lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_BOT_TOKEN_HERE'&lt;/span&gt;

&lt;span class="no"&gt;Telegram&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Bot&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Bot has been started...'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;
    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'/start'&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"Hello, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;! I'm a simple Ruby bot. Try /time or /roll"&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'/time'&lt;/span&gt;
      &lt;span class="n"&gt;current_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"%Y-%m-%d %H:%M:%S"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"Current time: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;current_time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'/roll'&lt;/span&gt;
      &lt;span class="c1"&gt;# Roll a random number between 1 and 100&lt;/span&gt;
      &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;rand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"🎲 You rolled: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="s1"&gt;'/photo'&lt;/span&gt;
      &lt;span class="c1"&gt;# Send a cat photo (using a placeholder service)&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_photo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;photo: &lt;/span&gt;&lt;span class="s1"&gt;'https://cataas.com/cat'&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="sr"&gt;/hello|hi|hey/i&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"👋 Hi there!"&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"I don't understand. Try /start to see commands."&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;what you notice &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;tbr is quite nice very nice it works out of the box but as you can see above it’s verbose Raw json raw api method nested arrays …&lt;/p&gt;

&lt;p&gt;handling state conversions is very verbose and explicit &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;let’s picture a bot that does many functions 
The developers will have to handle spaghetti codes hard for a contributor without reading tbr docs to contribute &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Then this is where telegem comes in&lt;/strong&gt;&lt;br&gt;
Telegem isn’t to replace tbr &lt;br&gt;
instead it offers what tbr doesn’t and offers a clean dsl &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no more verbose codes &lt;/li&gt;
&lt;li&gt;no more raw json &lt;/li&gt;
&lt;li&gt;no complexity or complex docs &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Telegem superpowers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;scene: one of Telegem great features &lt;br&gt;
&lt;strong&gt;what scenes&lt;/strong&gt; &lt;br&gt;
Let’s take it as a system that automatically gets the text moves to the next step handles multiple conversations &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;psuedo code&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;signup&lt;/em&gt; &lt;br&gt;
with scene it’s easy &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What’s your name &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your email &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;your password &lt;br&gt;
reply your account has been saved this is your api key &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;implementation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scene&lt;/span&gt; &lt;span class="ss"&gt;:signup&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:ask_name&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ask&lt;/span&gt; &lt;span class="s2"&gt;"👤 What's your full name?"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:ask_email&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_scene_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ask&lt;/span&gt; &lt;span class="s2"&gt;"📧 What's your email address?"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:ask_password&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_scene_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ask&lt;/span&gt; &lt;span class="s2"&gt;"🔐 Choose a password:"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;step&lt;/span&gt; &lt;span class="ss"&gt;:complete&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;with_scene_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;password: &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Generate fake token (in real app, use JWT or similar)&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SecureRandom&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Get all data&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scene_data&lt;/span&gt;

    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;~&lt;/span&gt;&lt;span class="no"&gt;TEXT&lt;/span&gt;&lt;span class="sh"&gt;
      ✅ Account Created!

      📋 Details:
      Name: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;
      Email: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:email&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;
      Password: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:password&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/./&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;

      🔑 Your Token: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;

      Save this token for future access!
&lt;/span&gt;&lt;span class="no"&gt;    TEXT&lt;/span&gt;

    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leave_scene&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;usage: &lt;code&gt;bot.command 'signup' do |ctx|&lt;br&gt;
  ctx.enter_scene(:signup)&lt;br&gt;
end&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;telegem scene just works out of the box automatically moves the next step &lt;/p&gt;

&lt;p&gt;Another method is &lt;strong&gt;ctx&lt;/strong&gt;&lt;br&gt;
ctx is an army you have different units and methods to use &lt;br&gt;
ctx.reply&lt;br&gt;
ctx.from.id&lt;br&gt;
ctx.from.full_name&lt;br&gt;
we won’t be talking about all this as it will take lot of time &lt;br&gt;
our main focus will be &lt;code&gt;ctx.reply&lt;/code&gt;&lt;br&gt;
I find this method very easy to use &lt;br&gt;
Basically let’s compare with tbr &lt;/p&gt;

&lt;p&gt;telegem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; 
&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"welcome to the world"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this is very easy unlike &lt;br&gt;
tbr:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;bot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send_message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="ss"&gt;chat_id: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;text: &lt;/span&gt;&lt;span class="s2"&gt;"welcome to the world"&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;digging up for chat.id &lt;br&gt;
you just write ctx.reply&lt;/p&gt;

&lt;p&gt;what’s more cool &lt;br&gt;
you can use ctx.reply with options&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;keyboard&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Telegem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keyboard&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
&lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="s2"&gt;"dev.to"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"hashnode"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt; 
&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"welcome to the world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;parse_mode: &lt;/span&gt;&lt;span class="s1"&gt;'Markdown'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;reply_markup: &lt;/span&gt;&lt;span class="n"&gt;keyboard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am trying to keep this as short as possible &lt;/p&gt;

&lt;p&gt;TL;DR &lt;br&gt;
 tbr is an old battle-tested gem with lots of tutorials and answers to most questions &lt;br&gt;
telegem is a new async first gem focus on non thread and modern features such as auto ssl using a one line command &lt;code&gt;telegem-ssl&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  use
&lt;/h2&gt;

&lt;p&gt;use tbr if you want answers to most questions you could possible get &lt;br&gt;
use telegem if you want a modern day gem with cool features that remove complex api methods &lt;/p&gt;

</description>
      <category>telegram</category>
      <category>bot</category>
      <category>api</category>
      <category>ruby</category>
    </item>
    <item>
      <title>Telegem v3.1.0 is here</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Sun, 18 Jan 2026 14:07:09 +0000</pubDate>
      <link>https://dev.to/zendrx/telegem-v310-is-here-3nad</link>
      <guid>https://dev.to/zendrx/telegem-v310-is-here-3nad</guid>
      <description>&lt;p&gt;Telegem now has a stable version release and also some improvements &lt;/p&gt;

&lt;h2&gt;
  
  
  fixes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;fixed the critical httpx bug preventing your bots from sending messages &lt;/li&gt;
&lt;li&gt;fixed hanging scene system &lt;/li&gt;
&lt;li&gt;fixed auto ssl detection method &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  New features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;file extraction(file to text) plugins 
&lt;strong&gt;docs coming soon&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;new improvised scene system &amp;amp; middleware &lt;/li&gt;
&lt;li&gt; Rate limit added can be used as a method also &lt;/li&gt;
&lt;li&gt;Added cli for ssl
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;telegem-ssl your-domain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;telegem-ssl 
&lt;span class="c"&gt;#then enter domain when promted  &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; telegem doesn’t create a ssl it uses certbot &lt;br&gt;
And should be only be used when using webhook mode &lt;/p&gt;

&lt;h2&gt;
  
  
  upcoming features
&lt;/h2&gt;

&lt;p&gt;Oops 😬 won’t spill the tea 👍&lt;/p&gt;

</description>
      <category>telegem</category>
      <category>telegram</category>
      <category>ruby</category>
      <category>gem</category>
    </item>
    <item>
      <title>Telegem v3.0.4 users : critical bug alert &amp; call for help</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Sat, 17 Jan 2026 18:50:19 +0000</pubDate>
      <link>https://dev.to/zendrx/telegem-v304-users-critical-bug-alert-call-for-help-2cp9</link>
      <guid>https://dev.to/zendrx/telegem-v304-users-critical-bug-alert-call-for-help-2cp9</guid>
      <description>&lt;p&gt;If you are using v3.0.4 you might be experiencing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ERROR &lt;span class="nt"&gt;--&lt;/span&gt; : ❌ Unhandled error: NoMethodError: undefined method &lt;span class="sb"&gt;`&lt;/span&gt;await&lt;span class="s1"&gt;' for an instance of HTTPX::Response(plugin)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This bug prevents your bot from sending responses or overall functionality &lt;/p&gt;

&lt;p&gt;The issue is compatibility with httpx async api &lt;/p&gt;

&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;p&gt;Telegem v3.0.4 used an async pattern (response.await) that worked with old httpx versions but newer httpx release probably changed their async Api. This caused all api calls to fail when trying to send responses &lt;br&gt;
especially the &lt;code&gt;ctx.reply&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Temporary solution
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gem uninstall httpx
gem &lt;span class="nb"&gt;install &lt;/span&gt;httpx &lt;span class="nt"&gt;-v&lt;/span&gt; 0.22.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;we could use your help&lt;/strong&gt;&lt;br&gt;
Httpx is a fantastic library/gem with incredible performance. But it’s async api changes rapidly.As a solo maintainer &lt;br&gt;
I could use some help from the community &lt;/p&gt;

&lt;h2&gt;
  
  
  Ways to contribute
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;TEST different httpx async patterns and share what works &lt;/li&gt;
&lt;li&gt;Help document httpx compatibility across different versions &lt;/li&gt;
&lt;li&gt;Submit MR(pr for github-ish) for more robust httpx handling &lt;/li&gt;
&lt;li&gt;Share your use case &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s make Telegem rock-solid together  &lt;/p&gt;

</description>
      <category>help</category>
      <category>telegram</category>
      <category>telegem</category>
      <category>ruby</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>ZenDrx</dc:creator>
      <pubDate>Sat, 17 Jan 2026 09:26:56 +0000</pubDate>
      <link>https://dev.to/zendrx/-e7h</link>
      <guid>https://dev.to/zendrx/-e7h</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/alexandrecalaca/ruby-one-of-the-top-5-highest-paying-technologies-according-to-stack-overflow-5dc7" class="crayons-story__hidden-navigation-link"&gt;Ruby: One of the top 5 highest-paying technologies, according to Stack overflow&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/alexandrecalaca" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F795109%2F9bf23429-1053-4890-909d-96e25f3a7327.jpeg" alt="alexandrecalaca profile" class="crayons-avatar__image" width="800" height="800"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/alexandrecalaca" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Alexandre Calaça
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Alexandre Calaça
                
              
              &lt;div id="story-author-preview-content-2106645" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/alexandrecalaca" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F795109%2F9bf23429-1053-4890-909d-96e25f3a7327.jpeg" class="crayons-avatar__image" alt="" width="800" height="800"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Alexandre Calaça&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/alexandrecalaca/ruby-one-of-the-top-5-highest-paying-technologies-according-to-stack-overflow-5dc7" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Nov 16 '24&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/alexandrecalaca/ruby-one-of-the-top-5-highest-paying-technologies-according-to-stack-overflow-5dc7" id="article-link-2106645"&gt;
          Ruby: One of the top 5 highest-paying technologies, according to Stack overflow
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ruby"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ruby&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/rails"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;rails&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/alexandrecalaca/ruby-one-of-the-top-5-highest-paying-technologies-according-to-stack-overflow-5dc7" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;7&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/alexandrecalaca/ruby-one-of-the-top-5-highest-paying-technologies-according-to-stack-overflow-5dc7#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ruby</category>
      <category>webdev</category>
      <category>rails</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
