Skip to content

Instantly share code, notes, and snippets.

@icedream
Last active January 14, 2021 22:37
Show Gist options
  • Save icedream/d72f338977d64cba458e85bb7f29fd14 to your computer and use it in GitHub Desktop.
Save icedream/d72f338977d64cba458e85bb7f29fd14 to your computer and use it in GitHub Desktop.
Quick sound posting bot for Telegram

This is just a Golang bot quickly thrown together which connects to the Telegram Bot API, waits for messages with specific words to be sent as messages and replies to them with the corresponding audio file.

Building

Make sure you have a standard Go building environment set up (GOPATH should be set up etc.).

Download main.go, make sure dependencies are available (go get -v -d) and then build with go build -v.

Usage

Create a config file config.yml like this one in the working directory:

telegram:
    # Insert your bot token here
    token: 012345678:ABCDEFG...

triggers:
    # This will make the bot respond to the word "pew" by posting the audio file at sounds/pew.ogg
    pew: sounds/pew.ogg
    
    # You can append other triggers similarly here.

Dependencies

  • Viper is used for configuration management (will theoretically load configuration from environment variables or system directories as well)
  • telegram-bot-api for communication with the Telegram Bot API.
package main
import (
"log"
"strings"
"github.com/spf13/viper"
"gopkg.in/telegram-bot-api.v4"
)
// Configuration value paths
const (
Config_Separator = "."
Config_Telegram = "telegram"
Config_Telegram_Token = Config_Telegram + Config_Separator + "token"
Config_Triggers = "triggers"
)
// Temporary in-memory storage for already uploaded files (Telegram will return IDs for these).
// This can be optimized to be stored permanently so the bot won't have to upload the file again even after restarts.
var (
audioShareIDs = map[string]string{}
)
// Quick and dirty error handling method.
func must(err error) {
if err == nil {
return
}
log.Fatal(err)
}
func main() {
// Add configuration paths
viper.AddConfigPath("/etc/pew-pew-bot/")
viper.AddConfigPath("$XDG_CONFIG_DIRS/pew-pew-bot")
viper.AddConfigPath("$HOME/.pew-pew-bot")
viper.AddConfigPath(".")
// Make `pew` trigger a default
viper.SetDefault(Config_Triggers, map[string]string{
"pew": "sounds/pew.ogg",
})
// Read in config
must(viper.ReadInConfig())
// Decode triggers table
triggers := map[string]string{}
viper.Sub(Config_Triggers).Unmarshal(&triggers)
// Set up the Telegram bot
bot, err := tgbotapi.NewBotAPI(viper.GetString(Config_Telegram_Token))
must(err)
//bot.Debug = true
log.Printf("Authorized on account %s", bot.Self.UserName)
u := tgbotapi.NewUpdate(0)
u.Timeout = 60
updates, err := bot.GetUpdatesChan(u)
must(err)
// Listen for incoming updates
for update := range updates {
if update.Message == nil {
continue
}
//log.Printf("[%s] %s", update.Message.From.UserName, update.Message.Text)
// Go through trigger table and check if any of the words there are contained in the message
for triggerWord, filePath := range triggers {
if strings.Contains(update.Message.Text, triggerWord) {
var msg tgbotapi.AudioConfig
// Check whether we need to upload the audio file or we can just reference by ID
if id, ok := audioShareIDs[filePath]; ok {
msg = tgbotapi.NewAudioShare(update.Message.Chat.ID, id)
} else {
msg = tgbotapi.NewAudioUpload(update.Message.Chat.ID, filePath)
}
// Mark as reply to the currently parsed message
msg.ReplyToMessageID = update.Message.MessageID
// Send message to Telegram API
bot.Send(msg)
// Prevent bot from sending more than one audio file as a reply by leaving the loop
break
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment