It’s been a long time since I wrote about the bot I’m building. Life happened. A lot of it. Now, when things are settling down, I might have again the time and the energy to program the bot some more and write about it in the process.
Last time the bot learned some text commands. Now it’s time to draw some pretty pictures. Today I’d like to add a couple of chart commands.
Using Telegram API it possible to send an image (as well as a video or any other document), it’s not limited to just text messages. All I need is a way to generate an image and push it down the wire. After a quick search, I stumbled upon go-chart.
go-chart renders charts into in-memory PNG and SVG files and this is exactly what I need. …
Last time I taught my bot to speak human. This time I’m gonna teach it to speak robot. I’m going to add a few bot commands. In Telegram the bots receive text exactly as you send it. By convention though, when the first word starts with a backslash (
/) it's interpreted as a command. Commands are used to tell the bot what to do. It's a bit like shell, where you spend, I assume, most of your time.
go-telegram-bot-api/telegram-bot-api package provides some functions to check whether there's a command in the received message and lets you extract it and its arguments. …
Last time I was bulletproofing my SQLite access foundation. Let’s see if it holds in production. Too bad I’m never gonna get that high load that is supposed to break things. Oh well, let’s wait and see. Maybe I get lucky and two sad concurrent requests would eventually make my Go binary panic.
Today, I’m going to focus on features. I’d like to make my bot intelligent. Not really AI like, rather just sounding a bit better than
cmd.exe when you type in a wrong command. …
Last time I added SQLite to my bot and at the same time I moved the request processing into a goroutine. Which means I introduced concurrent database access to my codebase.
Normally one should think, then do. Though not ideal, it’s also possible to do it the other way around when you use
git. But it's important not to forget to think at some point. Like I almost did and almost moved on to pile on more bugs on top of what I just introduced.
I remembered reading or watching something about SQLite the other day and they made it clear that I’d have to make sure not to access the database from multiple places at the same time. Go is made for concurrency, so I’m sure go-sqlite3 I was using has it under control. …
Today I’m gonna add a database to my bot. As I mentioned in the previous post, I’m going to use SQLite to keep it simple and because the management turned down my budget request for Oracle on this project.
I quickly shopped around for an SQLite package for Go and found go-sqlite3. This seems to be a very popular package. It allows me to use the standard
database/sql package and it acts as a driver, which allows the Go database engine to talk to SQLite databases. So far so good. I'll use that then.
Since I’m writing everything in Go, I desperately need to use goroutines somewhere. So the first thing I did was to move the reply functionality into a goroutine. …
This is my fourth or fifth attempt to like Go. Kinda didn’t work all the previous times. I blame myself, though. I believe I chose Go for the wrong types of projects. This time it’s what’s it was made to do. It’s a backend application, it’s deployed to a remote server, it’s using concurrency and not too complex. It’s a Telegram bot that helps me track random things.
I want to be able to send simple commands to the chat and let the bot remember what happened and when. It’s a bit like a log file. I want to be able to ask the bot when or how often something happened. …
In the previous post I wrote about how I find the patterns in the code that I would like to refactor using simple C# syntax. Basically, I write the exact expression I would like to find with some wildcards that match the varying parts and the rest is matched as is. A bit like a regexp or a shell file glob. Like this:
if you’d like to go extreme and match every member function call with two parameters.
What I would like to be able to do, though, is to transform the code, not just match. I’d like to specify how to convert the patterns to the form I’m after. …
In the previous post I described how to use the Roslyn API to find code patterns in the C# AST and how to change the AST to rewrite the original code to something else. The goal was to automate the conversion of NUnit tests to xUnit. The approach I used was quite tedious, as I had to write a very long chain or ifs and typecasts to get the job done. Let’s try to do better this time. Let’s start with just the search part in our search-and-replace tool.
What would be great is to be able to specify structural patterns like…
I’m currently working on a major refactoring of a C# library which has many NUnit tests. I decided, without having any good reason, it would be a good idea to migrate them to xUnit. I did a few by hand and it turns out to be tedious. Like really tedious. The most common pattern is the following:
The test in NUnit
becomes the test in xUnit:
To convert each by hand requires a lot of patience and stamina. Since I don’t have either, after doing a few dozens manually I decided to automate the whole thing. …