Imagine for a second, right that you are just relaxing on a gorgeous, sun drenched beach.
Oh I'm already there, right.
You have a cold drink in your hand, the waves are gently crashing, and you don't have a single care in the world.
Sounds perfect. Why am I so relaxed?
Exactly because back in the real world, you have a digital double Oh wow. Yeah, like a tireless, invisible assistant who is currently handling all of your mundane daily tasks. It's checking your schedules, filtering your messages, and basically doing all the heavy lifting of your life while you just sit back and listen to the ocean.
I mean that sounds like pure science fiction.
Honestly, he surely does, right, But today we're going to show you exactly how close that reality actually is. Welcome to the deep dive.
Glad to be here for this one.
Yeah, Today we are opening up a really fascinating piece of source material. It's a book called Building Telegram Bots Develop Bots in twelve programming languages by Nicholas Maudzik. And well, we are going to expor how you can build these digital assistance yourself.
Yeah, And what stands out immediately about mad ROC's approach. And I love this is that he didn't write this to show off like abstract theoretical coding.
Tricks, right, it's not a text put exactly.
He built these bots to solve highly relatable everyday problems he was actually facing while living in Tokyo.
The examples are incredibly grounded. I mean, anyone who has lived in a massive metropolis knows the absolute panic of like missing the last train home.
Oh yeah, and having to pay for a ridiculously expensive taxi.
It's the worst. So instead of constantly checking an app, he just wrote a bot that automatically tracks the last train schedules and drops his optimal transit options right into a.
Chat window, which is brilliant. Yeah.
He also built an IoT webcam bot that snaps a picture and sends it to his phone whenever someone rings his doorbell. And oh, my favorite party bot, ah, the party bot. Yeah, it uses a mini projector to display random incoming chat messages onto his life living room wall during get togethers.
It's so cool because it illustrates a fundamental shift in how we should view automation. You know how so well, a bot isn't just a corporate customer service gimmick anymore. It is a highly customizable personal tool to reduce friction in your daily life.
Right.
But the structure of this text is what makes it a masterclass. He doesn't just teach you how to build a bot. He teaches you how to build the exact same bot using twelve different programming languages.
Which naturally brings up the big question, right, and really the entire mission of our deep dive today for you, Why in the world would you solve the exact same problem in twelve different programming languages when you could just learn one and stick to it.
Yeah, sounds like a lot of extra work.
It does. The best way I can think to describe it is like cooking. Imagine cooking your absolute favorite go to recipe. Okay, I'm with you, but instead of just making it in your own familiar kitchen, you cook it in a massive commercial restaurant, pitchin when you cook it over a campfire in the woods, and then I don't know, you cook it in a tiny, high tech kitchen on
a submarine. That is a great analogy, right, You're making the exact same food, but the process teaches you just as much about the constraints the tooling and the environment as it does about the meal.
Itself, and that environmental constraint is precisely the point of the exercise. By holding the output constant the BOD, we get to clearly see the variables in the languages themselves, right.
It strips away the distraction of what you're building.
Exactly. It is about deeply understanding how different programming languages approach the very nature of problem solving at a systemic level.
Like how they handle memory yes.
How do they handle memory management? How do they structure their syntax to prioritize human readability versus raw machine level performance. When you build the same tool repeatedly, the philosophy of the language just kind of reveals itself.
Okay, let's unpack this Before we can start touring these different programming kitchens. We actually need some groceries, or in this case, we need a bot identity.
You can't code a bot if it doesn't exist yet.
Exactly, we have to start with the absolute foundation of the telegram platform, and to do that, we are going to look at one of the most famously readable, user friendly languages out there. Ruby.
Ruby serves as an excellent gateway because of its design philosophy. It explicitly prioritizes developer happiness.
Developer happiness, I love that.
Yeah, it reads almost like plain English. Yeah. Architecturally it's an interpreted scripting language, and that means that means you don't have to run it through a compiler to translate it into machine code before executing it. An interpreter simply reads your code line by line at runtime, which makes spinning up a prototype incredibly fast.
But before we write a single line of Ruby, we have to meet the boss.
Ah, yes, the Botfather.
To create a bot on Telegram, you don't just fill out a web form. You actually have to chat with a bot. To create a bot, you talk to prafana Agat bot Father, who is the literal old godfather of all telegrambots.
The book highlights some hilarious details here too.
Oh my gosh. Yes, Botfather is available twenty four to seven. Never sleeps, but according to his bio, he quote takes showers and always looks fresh. I mean, you gotta appreciate the lore, right his profile picture isn't.
Yeah.
The author makes a great joke about this, actually warning you not to leave this token hanging around on a public GitHub repository quote. Especially now that Microsoft.
Owns it, we'll developer humor there.
Right, so you keep it haydden in an environment variable. Now diving into the Ruby environment, setting this up is incredibly smooth. You use Ruby's package manager, which is called JEM to install the telegrambot library yep standard setup, and you create a simple file like step zero dot rb. But how does the code actually know when someone sends a message? Like?
Mechanically, the mechanics rely on what we call a polling loop. Specifically, the script calls a dot get updates method. Okay, Conceptually, think of it like a kid in the backseat of a car constantly asking are we there yet? How about now are we there yet?
Oh man?
Right? The Ruby script is in a continuous loop, constantly knocking on Telegram server door asking if any new data.
Has arrived, and when a message finally does arrive, it's not just the text the user typed. The book shows how if you use Ruby's toyomal function, which formats data into a really readable structured list, you can actually see the full anatomy of a Telegram payload.
It's surprisingly dense.
It's a massive package of data. You get a message you get the from field detailing the user, the chat channel info, the exact timestamp, and of course the actual text itself.
And this is where Ruby's high level abstractions really shine. To make the bot reply, you don't have to manually construct some complex httppost requests from scratch.
Thank goodness.
Right, you use string interpolation instead of clunky commands to concatenate or glue text together. Ruby lets you seamlessly evaluate variables right inside a string. You just write hello, followed directly by a hashtag message up from dot first name.
Which instantly grabs that specific piece of data from the payload. So the bot replies, hello Nico exactly. It completely abstracts away the complex network requests and the dense data parsing. You get a fully functioning, responsive bot in under ten lines of code.
It's beautiful.
But and here's where we hit a wall. Ruby is brilliant for a personal bot. Well, what happens if your bot goes viral?
Uh? The scaling problem?
Yeah? If that interpreter is reading code line by line and suddenly ten thousand people are messaging your bot at the exact same second, that are we there yet? Polling loop is going to become a massive bottleneck.
Precisely, the interpreter becomes a huge liability under heavy load. If you want raw speed and if you want a standalone executable file that runs directly on the machine's hardware without needing a Ruby environment installed on the server at all, which is a hassle it is, so if you want to avoid that, you have to leave scripting languages behind entirely.
Here's where it gets really interesting. We want the readability of a script, but we need the heavy duty performance of a compiled binary, and that architectural shift brings us to a completely different.
Language, NIM. NIM is a fascinating piece of technology. If you look at NIM code on a screen, it visually looks and feels very much like Python.
Oh really yeah.
It uses indentation and really clean readable syntax. But under the hood, NIM doesn't interpret. It compiles, meaning it translates your code down into clus plus U or JavaScript and then uses a C compiler to turn it into a highly optimized bare metal machine binary.
Okay, I have to play the skeptic for you here though, because reading the NIM section of the text, the developer experience felt incredibly jarring after how smooth Ruby.
Was, Well, yeah, that's a different beast.
With NIM, we need the NIM compiler, we need the Nimble package manager, and we have to install a specific vs code extension by constantin Zeitzev just to get syntax highlighting right. And even then I can't just click run. The author outlines how you have to configure custom tasks. Do Jason build tasks. You have to use terminal commands like nimcar to compile and run.
It's definitely more involved.
And to make a simple secure web request to get HUBSAPI, the code straight up fails unless you manually add a just dossl flag to the compile command. With Ruby, the web request just worked. Why take on all this extra friction?
If we connect this to the bigger picture, you have to understand the fundamental trade off of compiled systems. The friction you're describing is the literal price of optimization. When you manually add that digdssl flag, you are making a conscious architectural decision through a process called dead code elimination. Dead code elimination, Yes, NIM gives you the ultimate power
to exclude massive libraries you just don't need. If your specific bot doesn't need to make secure external web requests. Nim won't include that heavy SSL cryptographic code in your final binary.
Oh I see.
The result is a final program that is astonishingly tiny and lightning fast because the processor executes it directly.
So you trade a little upfront convenience for a massive back end performance boost.
Exactly.
So, when we build the nimbot, we use the telebot library, but we also have to import something called async dispatch, and this introduces a completely different paradigm than that Ruby polling loop we discussed earlier.
Yes, the text introduces the async pragma, which is vital for concurrency.
Right.
Think about synchronous programming. Like a single barista at a coffee shop. They take an order, make the coffee, and hand it over before even making eye contact with the next customer in line. That sounds infuriating, It is if the coffee takes five minutes, the line stops moving. That
is a synchronous bottleneck. Right. A synchronous programming is like a head barista taking an order, handing the ticket to the espresso machine, and immediately turning to take the next customer's order while the first coffee is brewing in the background.
But traditionally, writing that asynchronous logic leads to what developers call callback hell right where the code becomes this deeply nested, unreadable mess of functions waiting on other functions.
Exactly, and that is where NIM shines. The ACYNC feature allows you to write asynchronous code as though it were simple top down synchronous code.
Wow.
Yeah. It yields control back to the event loop without deeply nesking functions, keeping the logic clean while maintaining massive concurrency.
The author also uses a brilliant security trick in NIM that you simply can't do in Ruby, going back to that golden rule of hiding the token. In NIM, he uses a built in function called slurp secret dot key.
I love the name of that function, slurp.
It's great mechanically. What this does is reach out, grab the token from a local hidden text file on your hard drive, and bake it directly into the binary during the compilation step.
It's an elegant demonstration of compiler power. Because NIM compiles down to machine code. That token gets embedded into a binary format.
So it's not just sitting in plaintex. No.
A malicious actor can't just open a text file and read it on your server. They would have to reverse engineer and decompile a machine binary to extract that string, which raises the security barrier exponentially.
And the bot we build a NIM is super fun. It's a Cats and Dogs blot classic. The compiled code listens to the chat and if a user types the word cat or dog, it triggers a new photo function. It pulls a local image file, attaches a custom caption, and fires it back to the user. It proves that even though NIM compiles down to raw c it handles media and chat interactions effortlessly.
It does, but it also highlights the eternal programmers dilemma. You love the fast write elegant syntax of Ruby, but you also want the raw, compiled speed and type safety of NIM. The friction of compilation versus the joy of scripting. It's natural to ask if a language exists that bridges that gap.
Which brings us to a language that genuinely feels like the best of both worlds.
Crystal Crystal is fascinating because it was explicitly heavily influenced by Ruby.
Yeah, if you glance at a Crystal file, you would swear you're looking at Ruby code.
But just like NIM, it compiles directly. To see the author provides a benchmark to prove this speed. Actually, he runs a script to calculate the Fibonacci sequence up to one billion a billion. Yes, and in Crystal, this massive calculation takes fewer than five seconds.
That is insane.
That is a level of CPU performance that a dynamically typed interpreted scripting language could never dream of achieving.
How does it do that?
Crystal achieves this through advanced type inference. It looks dynamically types like Ruby, but the compiler figures out the data types of compile time, enduring memory safety and raw speed.
I have to challenge this premise, though, go for it. Calculating the Fibonacci sequence to a billion in five seconds is an incredible feed of engineering. Sure, but we are building a telegram bot to tell us when the next train leaves or to reply with the picture of a dog. Isn't optimizing for that level of intense CPU performance? Total overkill for what is his essentially just a text messaging assistant for.
A single user checking a train schedule. Absolutely, it's overkill, But think about scalability and infrastructure costs. Okay, if your bot is adopted by one hundred thousand users, an inefficient scripting language will require you to rent expensive, heavy duty cloud servers just to keep up with the memory overhead and the interpreter lag.
That gets pricey fast.
Because Crystal compiles to such highly optimized, lightweight C code, you could theoretically run that massive one hundred thousand user bot on a cheap five dollars a month virtual private server. You aren't just optimizing for speed, you are optimizing for server resources.
Oh. That puts it in perspective. The efficiency pays off at scale, and Crystal doesn't sacrifice developer experience to get there either, not at all. It has an amazing built in sandbox feature called Crystal Play. You type that into your terminal and it instantly launched the web server on port eighty eighty, where you can test your code live in a browser.
It's so user friendly.
But what really blew me away was the standard library. The author shows an example where the code queries the GitHub api to search for repositories. In most languages, you're hunting down third party libraries for network requests.
Crystal, however, has eahttp client and Jason Parsing built right into its core standard library that is so convenient you don't have to import external packages just to perform basic modern web functions. The language is fundamentally designed for the Internet age out of the box, and.
When you are ready to build a larger project, Crystal's tooling treats you like a professional. From second one. You take Crystal init app my bot, and it instantly builds out an entire, scalable project skeleton, testing folders, get ignore files, license, and your shard dot EML dependency file.
And that Shard dot eml file represents a massive philosophical shift in how Crystal handles packages compared to traditional ecosystems. How so well, Crystal's package managers called shards. Instead of relying on a centralized package repository which acts as a single point of failure that can go offline or be compromised by supply chain attacks, Crystal allows direct Git access for dependencies.
Meaning you simply point your code directly to the source code repository on GitHub. You completely bypass the middleman centralized server.
Exactly which inherently makes your build process significantly more resilient.
So we've explored the developer happiness of Ruby, the bare metal optimization of NIM, and the scalable hybrid power of Crystal. So if Crystal writes like beautiful Ruby and runs with the blistering speed of c is Crystal the ultimate programming language for building our personal digital assistance?
This raises an important question about the nature of tool optimization. There is really no six thing as an ultimate language, ah, the classic developer answer, Well, it's true. The best language depends entirely on your specific ecosystem and constraints. For instance,
Crystal currently relies heavily on a Unix like environment. If your native development machine is running Windows, you have to use the Windows subsystem for Linux or WSL, which adds a layer of virtualized complexity that might defeat the purpose of a fast setup. Furthermore, the best language is often simply the one that aligns best with your own mental models of logic.
So what does this all mean? We started this journey imagining a digital double handling your life while you relax on a beach, and what Nicholas Muljik's book shows us is that getting there isn't about finding one magical, perfect piece of syntax. It's about learning how to translate your
physical problems into computational solutions. Whether you choose the interpreted ease of Ruby to whip up a quick script to check your doorbell, or you embrace the compile time friction of NIM to build a tiny standalone binary, or you leverage Crystal to build a massive, highly scalable architecture for thousands of users. The real takeaway here is empowerment.
Yes, absolutely, building a.
Personal bot is a gateway to upgrading your own life. You truly can stop worrying about checking the train schedules at midnight and let your code do the heavy lifting for you.
It democratizes automation. You don't need an enterprise grades server, rack or a whole team of engineers to have a personal assistant. You just need an understanding of your own constraints, a few lines of code, and a chat app.
And that leaves us with one final slightly wild thought to Mullover.
Oh boy, we've.
Seen today just how easy it is to spin up a digital double to fetch images, parse Jason data, or monitor trans at times using surprisingly little code. The barriers to entry are practically gone. They really are, But as these programming languages become increasingly abstracted, as the compilers get smarter, and standard libraries do more of the heavy lifting for us right out of the box. How far are we from a future where our personal bots become smart enough to write code for other bots?
Oh wow?
Imagine relaxing on that beach not just because your bot is checking your emails, but because your bart noticed a repeated inefficiency in your daily routine, automatically generated a brand new, compiled robotic assistant, deployed it, and solved an inconvenience you hadn't even consciously noticed yet until next time. Keep dye moving deep
