Telegram Bot Framework for Go

Overview

Build Status

Margelet

Telegram Bot Framework for Go is based on telegram-bot-api

It uses Redis to store it's states, configs and so on.

Any low-level interactions with Telegram Bot API(downloading files, keyboards and so on) should be performed through telegram-bot-api.

Margelet is just a thin layer, that allows you to solve basic bot tasks quickly and easy.

Installation

go get github.com/zhulik/margelet

Simple usage

package main

import (
	"github.com/zhulik/margelet"
)

func main() {
	bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)

	if err != nil {
		panic(err)
	}

	err = bot.Run()
	if err != nil {
		panic(err)
	}
}

Out of the box, margelet supports only /help command, it responds something like this

/help - Show bot help

Concept

Margelet is based on some concepts:

  • Message handlers
  • Command handlers
  • Session handlers
  • Chat configs
  • Inline handlers

Message handlers

Message handler is a struct that implements Handler interface. It receives all chat messages dependant on bot's Privacy mode. It doesn't receive commands.

Simple example:

package margelet_test

import (
	"../margelet"
)

// EchoHandler is simple handler example
type EchoHandler struct {
}

// Response send message back to author
func (handler EchoHandler) HandleMessage(m margelet.Message) error {
	_, err := m.QuickSend(m.Message().Text)
	return err
}

This handler will repeat any user's message back to chat.

Message helpers can be added to margelet with AddMessageHandler function:

bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)
bot.AddMessageHandler(EchoHandler{})
bot.Run()

Command handlers

Command handler is struct that implements CommandHandler interface. CommandHandler can be subscribed on any command you need and will receive all message messages with this command, only if there is no active session with this user in this chat

Simple example:

package margelet

import (
	"fmt"
	"strings"
)

// HelpHandler Default handler for /help command. Margelet will add this automatically
type HelpHandler struct {
	Margelet *Margelet
}

// HandleCommand sends default help message
func (handler HelpHandler) HandleCommand(message Message) error {
	lines := []string{}
	for command, h := range handler.Margelet.CommandHandlers {
		lines = append(lines, fmt.Sprintf("/%s - %s", command, h.handler.HelpMessage()))
	}

	for command, h := range handler.Margelet.SessionHandlers {
		lines = append(lines, fmt.Sprintf("/%s - %s", command, h.handler.HelpMessage()))
	}

	_, err := message.QuickSend(strings.Join(lines, "\n"))
	return err
}

// HelpMessage return help string for HelpHandler
func (handler HelpHandler) HelpMessage() string {
	return "Show bot help"
}

Command handlers can be added to margelet with AddCommandHandler function:

bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)
bot.AddCommandHandler("help", HelpHandler{bot})
bot.Run()

Session handlers

Session here is an interactive dialog with user, like @BotFather does. User runs session with a command and then response to bot's questions until bot collects all needed information. It can be used for bot configuration, for example.

Session handlers API is still developing

Session handler is struct that implements SessionHandler interface. Simple example:

package margelet_test

import (
	"fmt"
	"strconv"

	"../margelet"
	"gopkg.in/telegram-bot-api.v4"
)

// SumSession - simple example session, that can sum numbers
type SumSession struct {
}

// HandleResponse - Handlers user response
func (s SumSession) HandleSession(session margelet.Session) error {
	switch len(session.Responses()) {
	case 0:
		session.QuickReply("Hello, please, write one number per message, after some iterations write 'end'.")
	default:
		if session.Message().Text == "end" {
			var sum int
			for _, m := range session.Responses() {
				n, _ := strconv.Atoi(m.Text)
				sum += n
			}
			session.QuickReply(fmt.Sprintf("Your sum: %d", sum))
			session.Finish()
			return nil
		}

		_, err := strconv.Atoi(session.Message().Text)
		if err != nil {
			session.QuickReply("Sorry, not a number")
			return err
		}
	}

	return nil
}

// CancelResponse - Chance to clean up everything
func (s SumSession) CancelSession(session margelet.Session) {
	//Clean up all variables only used in the session

}

func (session SumSession) response(bot margelet.MargeletAPI, message *tgbotapi.Message, msg tgbotapi.MessageConfig) {
	msg.ChatID = message.Chat.ID
	msg.ReplyToMessageID = message.MessageID
	msg.ReplyMarkup = tgbotapi.ForceReply{ForceReply: true, Selective: true}
	bot.Send(msg)
}

// HelpMessage return help string for SumSession
func (session SumSession) HelpMessage() string {
	return "Sum your numbers and print result"
}

Session handlers can be added to margelet with AddSessionHandler function:

bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)
bot.AddSessionHandler("help", SumSession{})
bot.Run()

On each user response it receives all previous user responses, so you can restore session state. HandleResponse return values it important:

  • first(bool), means that margelet should finish session, so return true if you receive all needed info from user, false otherwise
  • second(err), means that bot cannot handle user's message. This message will not be added to session dialog history. Return any error if you can handle user's message and return nil if message is accepted.

Inline handlers

Inline handler is struct that implements InlineHandler interface. InlineHandler can be subscribed on any inline queries.

Simple example:

package margelet_test

import (
	"github.com/zhulik/margelet"
	"gopkg.in/telegram-bot-api.v4"
)

type InlineImage struct {
}

func (handler InlineImage) HandleInline(bot margelet.MargeletAPI, query *tgbotapi.InlineQuery) error {
	testPhotoQuery := tgbotapi.NewInlineQueryResultPhoto(query.ID, "https://telegram.org/img/t_logo.png")
	testPhotoQuery.ThumbURL = "https://telegram.org/img/t_logo.png"

	config := tgbotapi.InlineConfig{
		InlineQueryID: query.ID,
		CacheTime:     2,
		IsPersonal:    false,
		Results:       []interface{}{testPhotoQuery},
		NextOffset:    "",
	}

	bot.AnswerInlineQuery(config)
	return nil
}

Inline handler can be added to margelet by InlineHandler assignment:

bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)
m.InlineHandler = &InlineImage{}
bot.Run()

Callback handlers

Callback handler is struct that implements CallbackHandler interface. CallbackHandler can be subscribed on any callback queries.

Simple example:

package margelet_test

import (
	"../margelet"
	"gopkg.in/telegram-bot-api.v4"
)

type CallbackMessage struct {
}

func (handler CallbackMessage) HandleCallback(query margelet.CallbackQuery) error {
	config := tgbotapi.CallbackConfig{
		CallbackQueryID: query.Query().ID,
		Text:            "Done!",
		ShowAlert:       false,
	}

	query.Bot().AnswerCallbackQuery(config)
	return nil
}

Callback handler can be added to margelet by CallbackHandler assignment:

bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)
m.CallbackHandler = &CallbackMessage{}
bot.Run()

Chat configs

Bots can store any config string(you can use serialized JSON) for any chat. It can be used for storing user's configurations and other user-related information. Simple example:

bot, err := margelet.NewMargelet("<your awesome bot name>", "<redis addr>", "<redis password>", 0, "your bot token", false)
...
bot.GetConfigRepository().Set(<chatID>, "<info>")
...
info := bot.GetConfigRepository().Get(<chatID>)

OR

type userInfo struct{
  FavColor string // First character has to be Capital otherwise it wont be saved
}
...
user := userInfo{FavColor: "Green"}
bot.GetConfigRepository().SetWithStruct(<chatID>, user)
...
var user userInfo
bot.GetConfigRepository().GetWithStruct(<chatID>, &user)

Chat config repository can be accessed from session handlers.

Example project

Simple and clean example project can be found here. It provides command handling and session configuration.

Issues
  • message.Command() Changed?

    message.Command() Changed?

    margelet.AddCommandHandler("/cat", CatHandler{})
    margelet.AddSessionHandler("/start", ConfigSessionHandler{})
    

    Should be changed to

    margelet.AddCommandHandler("cat", CatHandler{})
    margelet.AddSessionHandler("start", ConfigSessionHandler{})
    

    because message.Command() seems to return just the command without "/"

    opened by Mrcrypt 3
  • May be use

    May be use ":" as redis namespace delimiter?

    Docs: http://redis.io/topics/data-types-intro#redis-keys

    Try to stick with a schema. For instance "object-type:id" is a good idea, as in "user:1000". Dots or dashes are often used for multi-word fields, as in "comment: 1234:reply.to" or "comment:1234:reply-to".

    https://github.com/resque/redis-namespace

    namespaced_redis.set('foo', 'bar') # redis_connection.set('ns:foo', 'bar')

    Example: 2016-04-21 01 07 50

    opened by xboston 1
  • Update tgbotapi to v3.

    Update tgbotapi to v3.

    Telegram Chat IDs for supergroups may overflow an int, as they can reach values from -1e13 to 1e13 according to the Telegram documentation.

    This PR updates margelet to use tgbotapi v3 which uses int64 Chat IDs instead.

    opened by Syfaro 1
  • Add callback query handler

    Add callback query handler

    Based on InlineHandler:

    type CallbackMessage struct {
    }
    
    func (handler CallbackMessage) HandleCallback(bot margelet.MargeletAPI, query *tgbotapi.CallbackQuery) error {
    
        config := tgbotapi.CallbackConfig{
            CallbackQueryID: query.ID,
            Text:            "Done!",
            ShowAlert:       false,
        }
    
        bot.AnswerCallbackQuery(config)
        return nil
    }
    
    opened by xboston 0
Owner
Gleb Sinyavskiy
Gleb Sinyavskiy
A bot based on Telegram Bot API written in Golang allows users to download public Instagram photos, videos, and albums without receiving the user's credentials.

InstagramRobot InstagramRobot is a bot based on Telegram Bot API written in Golang that allows users to download public Instagram photos, videos, and

FTC Team 8 Dec 16, 2021
Bot - Telegram Music Bot in Go

Telegram Music Bot in Go An example bot using gotgcalls. Setup Install the serve

null 9 Jun 28, 2022
Bot-template - A simple bot template for creating a bot which includes a config, postgresql database

bot-template This is a simple bot template for creating a bot which includes a c

Disgo 0 May 28, 2022
Telegram Bot Framework for Go

Margelet Telegram Bot Framework for Go is based on telegram-bot-api It uses Redis to store it's states, configs and so on. Any low-level interactions

Gleb Sinyavskiy 72 May 8, 2022
Telebot is a Telegram bot framework in Go.

Telebot "I never knew creating Telegram bots could be so sexy!" go get -u gopkg.in/tucnak/telebot.v2 Overview Getting Started Poller Commands Files Se

Ian P Badtrousers 2.6k Jun 28, 2022
Parr(B)ot is a Telegram bot framework based on top of Echotron

Parr(B)ot framework A just born Telegram bot framework in Go based on top of the echotron library. You can call it Parrot, Parr-Bot, Parrot Bot, is up

DazFather 4 May 31, 2022
The serverless OTP telegram service use telegram as OTP service, and send OTP through webhook

Setup OTP First thing, you need prepare API(webhook) with POST method, the payload format as below { "first_name": "Nolan", "last_name": "Nguyen",

Dong Nguyen 2 Jan 5, 2022
IRC, Slack, Telegram and RocketChat bot written in go

go-bot IRC, Slack & Telegram bot written in Go using go-ircevent for IRC connectivity, nlopes/slack for Slack and Syfaro/telegram-bot-api for Telegram

null 746 Jun 29, 2022
Golang telegram bot API wrapper, session-based router and middleware

go-tgbot Pure Golang telegram bot API wrapper generated from swagger definition, session-based routing and middlewares. Usage benefits No need to lear

Oleg Lebedev 112 Jun 13, 2022
Client lib for Telegram bot api

Micha Client lib for Telegram bot api. Supports Bot API v2.3.1 (of 4th Dec 2016). Simple echo bot example: package main import ( "log" "git

Andrey 18 Jun 13, 2022
Go library for Telegram Bot API

tbot - Telegram Bot Server Features Full Telegram Bot API 4.7 support Zero dependency Type-safe API client with functional options Capture messages by

Alexey Grachov 323 May 19, 2022
Golang bindings for the Telegram Bot API

Golang bindings for the Telegram Bot API All methods are fairly self explanatory, and reading the godoc page should explain everything. If something i

null 3.8k Jun 29, 2022
Golang Based Account Generator Telegram Bot

Account Generator Bot Account Generator Bot, written in GoLang via gotgbot library. Variables Env Vars - BOT_TOKEN - Get it from @BotFather CHANNEL_ID

Anonymous Indian 35 Jun 8, 2022
Bot that polls activity API for Github organisation and pushes updates to Telegram.

git-telegram-bot Telegram bot for notifying org events Requirements (for building) Go version 1.16.x Setup If you don't have a telegram bot token yet,

Skycoin 4 Apr 8, 2022
📱 Hentai bot for Telegram 📱

Random-Good-Hanime Hentai Telegram bot for educational purpose ?? Features ?? Random hentai Lot of different categories ?? Real time logs ?? Config fi

Patrick 7 Jun 20, 2022
A telegram bot that fetches multiple RSS cryptocurrency news feeds for sentiment analysis

Crypto News Telegram Bot A simple telegram bot that will help you stay updated on your latest crypto news This bot will help you keep track of the lat

Cha 4 Aug 22, 2021
A Telegram bot that will run code for you.

piston_bot A Telegram bot that will run code for you. Made using piston. Available as @iruncode_bot on telegram. Examples Basic example Input: /run py

Tushar Sadhwani 31 Jun 13, 2022
Telegram bot to get information on vaccine availabilities.

?? berlin-vaccine-alert Telegram bot to get information on vaccine availabilities. Get the latest appointments directly on telegram. The bot listen to

Erwan Leboucher 16 May 22, 2022
Flexible message router add-on for go-telegram-bot-api library.

telemux Flexible message router add-on for go-telegram-bot-api library. Table of contents Motivation Features Minimal example Documentation Changelog

Andrew Dunai 20 Jun 13, 2022