Skip to main content

Prerequisites

  • Go 1.16 or later (the minimum version declared in Telebot’s go.mod)
  • A Telegram account

Steps

1

Create a bot with BotFather

Open Telegram and start a conversation with @BotFather.Send the /newbot command and follow the prompts. BotFather will give you an API token that looks like:
123456789:AABBccDDeeFFggHHiiJJkkLLmmNNooP
Keep your token secret. Anyone with the token can control your bot.
2

Install Telebot

Create a new Go module and add the Telebot dependency:
mkdir mybot && cd mybot
go mod init mybot
go get -u gopkg.in/telebot.v4
3

Create main.go

Create a file named main.go with the following content:
package main

import (
	"log"
	"os"
	"time"

	tele "gopkg.in/telebot.v4"
)

func main() {
	pref := tele.Settings{
		Token:  os.Getenv("TOKEN"),
		Poller: &tele.LongPoller{Timeout: 10 * time.Second},
	}

	b, err := tele.NewBot(pref)
	if err != nil {
		log.Fatal(err)
		return
	}

	b.Handle("/start", func(c tele.Context) error {
		return c.Send("Hello, " + c.Sender().FirstName + "!")
	})

	b.Start()
}
The three key calls are:
  • tele.NewBot(pref) — creates the bot and calls getMe to verify the token.
  • b.Handle("/start", ...) — registers a handler for the /start command. The handler receives a tele.Context and returns an error.
  • b.Start() — begins long-polling for updates and blocks until the bot is stopped.
4

Run the bot

Export your token and start the bot:
export TOKEN="123456789:AABBccDDeeFFggHHiiJJkkLLmmNNooP"
go run main.go
Open Telegram, find your bot by the username BotFather assigned, and send /start. The bot replies with Hello, <your first name>!.
Press Ctrl+C to stop the bot. b.Start() returns cleanly on interrupt.

Complete example

Here is the full runnable program from the steps above, with error handling and the token read from the environment:
package main

import (
	"log"
	"os"
	"time"

	tele "gopkg.in/telebot.v4"
)

func main() {
	pref := tele.Settings{
		Token:  os.Getenv("TOKEN"),
		Poller: &tele.LongPoller{Timeout: 10 * time.Second},
	}

	b, err := tele.NewBot(pref)
	if err != nil {
		log.Fatal(err)
		return
	}

	// Reply to /start
	b.Handle("/start", func(c tele.Context) error {
		return c.Send("Hello, " + c.Sender().FirstName + "!")
	})

	// Echo all other text messages back to the sender
	b.Handle(tele.OnText, func(c tele.Context) error {
		return c.Send(c.Text())
	})

	b.Start()
}

How it works

NewBot and Settings

tele.NewBot accepts a tele.Settings struct:
type Settings struct {
	URL   string       // custom API server URL (optional)
	Token string       // bot token from BotFather
	Poller Poller      // update source
	Updates int        // updates channel capacity (default: 100)
	Synchronous bool   // run handlers sequentially (default: false)
	Verbose bool       // log all outgoing requests
	ParseMode ParseMode // default parse mode for all messages
	OnError func(error, Context) // global error handler
	Client *http.Client // custom HTTP client
	Offline bool       // skip getMe call (useful for tests)
}
If Poller is not set, a bare &LongPoller{} is used (no timeout). Always set a Timeout in production.

Handle

b.Handle(endpoint, handlerFunc, ...middleware) binds a HandlerFunc to an endpoint. The endpoint can be a command string, a telebot event constant, or a pointer to a button.

Context.Send

c.Send(what, ...options) sends a message to the current chat. what can be a string, a *Photo, a *Video, or any other type that implements Sendable. Options like tele.Silent and tele.NoPreview can be passed as variadic arguments.

Start

b.Start() blocks, polling for updates and dispatching them to handlers concurrently. Each handler runs in its own goroutine. To stop the bot programmatically, call b.Stop().

What’s next?

Introduction

Understand Telebot’s architecture: Bot, Context, Handlers, Middleware, and Poller.

Context

Learn every method available on tele.Context and how to use local storage within a handler.

Handlers & Routing

Explore all supported event constants, command payloads, and button routing.

Middleware

Add logging, access control, and other cross-cutting logic with the middleware chain.

Build docs developers (and LLMs) love