This bot server is written in Go, and runs on a dedicated server from Ionos.


The server is a set of nested loops.

The main loop is a UDP server, accepting and maintaining UDP clients, and sending them regular UDP pings to keep NAT traversal from going stale. This ‘connection’ is what happens when you send it a MOPP packet with either “qrl?” or “hi” in it. There are currently as many ‘slots’ as there are bot personalities, so that each bot personality can only be talking to one person at a time. This loop also checks for stale connections, sends them a goodbye message, and returns the connection slot to the pool.

The next loop in happens when the user starts a QSO with a “cq” call. This loop continues until the QSO ends by user request, or by timeout. The bot never (currently) terminates the QSO itself, as it isn’t obvious how long a real beginner might take to try and complete their QSO.

The next loop in handles incoming MOPP packets, and builds up a full transmission line, waiting for a terminating prosign. When it sees this, it sends this new transmission to a line processing routine.

The line processing routine parses the received line and updates the QSO state, and forms an answer based on line and the QSO state.

This line gets sent back to the user, at the speed of the user’s last MOPP packet. Sending “hello from qsobot” back to the user at 20 wpm, means chopping the line up into words (that will each be a MOPP packet), sending each word with the right encoded speed for the M-32 to play it to the user at 20 wpm, and sending those MOPP packets to the user at the right times to ensure the inter-word spaces are correct.

The line parsing and response code is where the hard bit happens, of course, and this is currently fairly basic. The QSO state keeps track of what info has been sent and received during this QSO. The formality of the response (starting callsign, ending callsigns, both, neither) is based on the formality of the last transmission from the user, so the user can practice formal callsign use, or not, as they choose.

There are currently 35 different bot personalities (vHams), each with a callsign, name, and QTH.

One of my proudest bits: the vHams look up local weather, regularly, so when Sky from Caracas says it’s raining and 10C, it actually is that weather. She can’t tell if it’s cloudy after sunset, of course :-)


What features will I add next?

  1. better parsing of the user’s input (this will probably be a continuing stream of improvement forever)
  2. more variance in the bot’s responses, maybe based on their personalities
  3. more bot personalities; 50 or a 100 would be a nice round number :-)