Skip to content

inspirasiprogrammer/telego

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Telego • Go Telegram Bot API

Go Reference Telegram Bot API Version
Mentioned in Awesome Go Dis Telegram Chat

CI Status Quality Gate Status Go Report
Coverage Code Smells Lines of Code

Telego logo

Telego is Telegram Bot API library for Golang with full API implementation (one-to-one)

The goal of this library was to create API with same types and methods as actual telegram bot API. Every type and method have been represented in types.go and methods.go files with mostly all documentation from telegram.

Note: Telego uses fasthttp instead of net/http and go-json instead of encoding/json.

📋 Table Of Content

Click to show • hide

⚡ Getting Started

How to get the library:

go get -u github.com/mymmrac/telego

Make sure you get the latest version to have all new features & fixes.

More examples can be seen here:

Click to show • hide

Note: Error handling may be missing in examples, but I strongly recommend handling all errors.

🧩 Basic setup

▲ Go Up ▲

For start, you need to create instance of your bot and specify token.

package main

import (
	"fmt"
	"os"

	"github.com/mymmrac/telego"
)

func main() {
	// Get Bot token from environment variables
	botToken := os.Getenv("TOKEN")

	// Create bot and enable debugging info
	// (more on configuration at /examples/configuration/main.go)
	// Note: Please keep in mind that default logger exposes your bot token, use in development only
	bot, err := telego.NewBot(botToken, telego.WithDefaultLogger(true, true))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Call method getMe (https://core.telegram.org/bots/api#getme)
	botUser, err := bot.GetMe()
	if err != nil {
		fmt.Println("Error:", err)
	}

	// Print Bot information
	fmt.Printf("Bot user: %#v\n", botUser)
}

📩 Getting updates

▲ Go Up ▲

In order to receive updates you can use two methods:

  • using long polling (bot.UpdatesViaLongPulling)
  • using webhook (bot.UpdatesViaWebhook)

Let's start from long pulling (easier for local testing):

package main

import (
	"fmt"
	"os"
	"time"

	"github.com/mymmrac/telego"
)

func main() {
	botToken := os.Getenv("TOKEN")

	// Note: Please keep in mind that default logger exposes your bot token, use in development only
	bot, err := telego.NewBot(botToken, telego.WithDefaultLogger(true, true))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Optional. Set interval of getting updates (default: 0.5s).
	// If you want to get updates as fast as possible set to 0,
	// but webhook method is recommended for this.
	bot.SetUpdateInterval(time.Second / 2)

	// Get updates channel
	updates, _ := bot.UpdatesViaLongPulling(nil)

	// Stop reviving updates from updates channel
	defer bot.StopLongPulling()

	// Loop through all updates when they came
	for update := range updates {
		fmt.Printf("Update: %#v\n", update)
	}
}

Webhook example (recommended way):

package main

import (
	"fmt"
	"os"

	"github.com/mymmrac/telego"
)

func main() {
	botToken := os.Getenv("TOKEN")

	// Note: Please keep in mind that default logger exposes your bot token, use in development only
	bot, err := telego.NewBot(botToken, telego.WithDefaultLogger(true, true))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Set up a webhook on Telegram side
	_ = bot.SetWebhook(&telego.SetWebhookParams{
		URL: "https://example.com/bot" + bot.Token(),
	})

	// Receive information about webhook
	info, _ := bot.GetWebhookInfo()
	fmt.Printf("Webhook Info: %#v\n", info)

	// Get updates channel from webhook.
	// Note: For one bot only one webhook allowed.
	updates, _ := bot.UpdatesViaWebhook("/bot" + bot.Token())

	// Start server for receiving requests from Telegram
	bot.StartListeningForWebhook("localhost:443")

	// Stop reviving updates from updates channel and shutdown webhook server
	defer func() {
		_ = bot.StopWebhook()
	}()

	// Loop through all updates when they came
	for update := range updates {
		fmt.Printf("Update: %#v\n", update)
	}
}

Note: You may wish to use Let's Encrypt in order to generate your free TLS certificate.

🪁 Using Telegram methods

▲ Go Up ▲

All Telegram Bot API methods described in documentation can be used by the library. They have same names and same parameters, parameters represented by struct with name: <methodName> + Params. If method don't have required parameters nil value can be used as a parameter.

Note: types.go and methods.go was automatically generated from documentation, and it's possible that they have errors or missing parts both in comments and actual code. Feel free to report such things.

package main

import (
	"fmt"
	"os"

	"github.com/mymmrac/telego"
	tu "github.com/mymmrac/telego/telegoutil"
)

func main() {
	botToken := os.Getenv("TOKEN")

	// Note: Please keep in mind that default logger exposes your bot token, use in development only
	bot, err := telego.NewBot(botToken, telego.WithDefaultLogger(true, true))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Call method getMe
	botUser, _ := bot.GetMe()
	fmt.Printf("Bot User: %#v\n", botUser)

	updates, _ := bot.UpdatesViaLongPulling(nil)
	defer bot.StopLongPulling()

	for update := range updates {
		if update.Message != nil {
			// Retrieve chat ID
			chatID := update.Message.Chat.ID

			// Call method sendMessage (https://core.telegram.org/bots/api#sendmessage).
			// Sends message to sender with same text (echo bot).
			sentMessage, _ := bot.SendMessage(
				tu.Message(
					tu.ID(chatID),
					update.Message.Text,
				),
			)

			fmt.Printf("Sent Message: %v\n", sentMessage)
		}
	}
}

🧼 Utility methods

▲ Go Up ▲

In Telego even though you have all types and methods available, it's often not so convenient to use them directly. To solve this issues telegoutil package was created. It contains utility-helper function that will make your life a bit easier.

I suggest including it with alias to get cleaner code:

import tu "github.com/mymmrac/telego/telegoutil"

Package contains couple methods for creating send parameters with all required parameters like:

  • Message(chatID, text) => SendMessageParams
  • Photo(chatID, photoFile) => SendPhotoParams
  • Location(chatID, latitude, longitude) => SendLocationParams
  • ...

Or other useful methods like:

  • ID(intID) => ChatID
  • File(namedReader) => InputFile
  • ...

Utils related to methods can be found in telegoutil/methods, for types in telegoutil/types, for handlers in telegoutil/handler, for api in telegoutil/api.

Note: If you think that something can be added to telegoutil package fill free to create an issue or pull request with desired changes.

🦾 Helper With... methods

▲ Go Up ▲

Creating method parameters is sometimes bulky and not convenient, so you can use with methods in combination with utility methods.

Here is a simple example of creating a message with a keyboard that has 4 buttons with different parameters.

package main

import (
	"github.com/mymmrac/telego"
	tu "github.com/mymmrac/telego/telegoutil"
)

func main() {
	// ... initializing bot

	// Creating keyboard
	keyboard := tu.Keyboard(
		tu.KeyboardRow( // Row 1
			tu.KeyboardButton("Button"), // Column 1
			tu.KeyboardButton("Poll Regular"). // Column 2
				WithRequestPoll(tu.PollTypeRegular()), // <- `with` method
		),
		tu.KeyboardRow( // Row 2
			tu.KeyboardButton("Contact").WithRequestContact(),   // Column 1, <- `with` method 
			tu.KeyboardButton("Location").WithRequestLocation(), // Column 2, <- `with` method 
		),
	).WithResizeKeyboard().WithInputFieldPlaceholder("Select something") // <- multiple `with` methods 

	// Creating message
	msg := tu.Message(
		tu.ID(123),
		"Hello World",
	).WithReplyMarkup(keyboard).WithProtectContent() // <- multiple `with` method 

	bot.SendMessage(msg)
}

Those methods allow you to modify values without directly accessing them, also as you saw with methods can be staked one to another in order to update multiple values.

🌥️ Bot handlers

▲ Go Up ▲

Processing updates just in for loop is not the most pleasing thing to do, so Telego provides net/http like handlers, but instead of the path, you provide predicates.

One update will only match to the first handler whose predicates are satisfied, predicates checked in order of handler registration (it's useful to first specify most specific predicates and then more general).

Also, all handlers (but not their predicates) are processed in parallel.

I suggest including it with alias to get cleaner code:

import th "github.com/mymmrac/telego/telegohandler"

Here is example of using handlers with long pulling updates. You can see full list of available predicates in telegohandler/pradicates, or define your own.

package main

import (
	"fmt"
	"os"

	"github.com/mymmrac/telego"
	th "github.com/mymmrac/telego/telegohandler"
	tu "github.com/mymmrac/telego/telegoutil"
)

func main() {
	botToken := os.Getenv("TOKEN")

	// Note: Please keep in mind that default logger exposes your bot token, use in development only
	bot, err := telego.NewBot(botToken, telego.WithDefaultLogger(true, true))
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Get updates channel
	updates, _ := bot.UpdatesViaLongPulling(nil)
	defer bot.StopLongPulling()

	// Create bot handler and specify from where to get updates
	bh, _ := th.NewBotHandler(bot, updates)

	// Register new handler with match on command `/start`
	bh.Handle(func(bot *telego.Bot, update telego.Update) {
		// Send message
		_, _ = bot.SendMessage(tu.Message(
			tu.ID(update.Message.Chat.ID),
			fmt.Sprintf("Hello %s!", update.Message.From.FirstName),
		))
	}, th.CommandEqual("start"))

	// Register new handler with match on any command
	// Handlers will match only once and in order of registration, so this handler will be called on any command except
	// `/start` command
	bh.Handle(func(bot *telego.Bot, update telego.Update) {
		// Send message
		_, _ = bot.SendMessage(tu.Message(
			tu.ID(update.Message.Chat.ID),
			"Unknown command, use /start",
		))
	}, th.AnyCommand())

	// Start handling updates
	bh.Start()

	// Stop handling updates
	defer bh.Stop()
}

🎨 Contribution

Contribution guidelines listed here.

🔐 License

Telego is distributed under MIT licence.

About

Telegram Bot API library for Golang

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 99.8%
  • Makefile 0.2%