Authentication

Bot login

Bots authenticate with a single string from BotFather. One call, no interaction, no 2FA. The simplest auth flow Telegram offers.

The call

client.Connect()
if err := client.LoginBot("123456:ABC-DEF1234ghIkl"); err != nil {
	log.Fatal(err)
}
client.Connect()
if err := client.LoginBot("123456:ABC-DEF1234ghIkl"); err != nil {
	log.Fatal(err)
}

LoginBot takes the bot token from BotFather, runs auth.importBotAuthorization against the current DC, and either succeeds or returns an error. On success the auth key is bound to the bot account, the session file gets written, and every subsequent run reuses the same key without re-logging-in.

Comparison with the other login flavours — same client, same session, three different starting calls:

client.Connect()
if err := client.LoginBot(os.Getenv("BOT_TOKEN")); err != nil {
	log.Fatal(err)
}
client.Connect()
if err := client.LoginBot(os.Getenv("BOT_TOKEN")); err != nil {
	log.Fatal(err)
}

A complete bot program:

main.go
package main

import (
	"log"
	"os"

	"github.com/amarnathcjd/gogram/telegram"
)

func main() {
	client, err := telegram.NewClient(telegram.ClientConfig{
		AppID:   12345,
		AppHash: os.Getenv("API_HASH"),
		Session: "bot.session",
	})
	if err != nil {
		log.Fatal(err)
	}

	if err := client.Connect(); err != nil {
		log.Fatal(err)
	}
	if err := client.LoginBot(os.Getenv("BOT_TOKEN")); err != nil {
		log.Fatal(err)
	}

	me, _ := client.GetMe()
	log.Printf("running as @%s (id %d)", me.Username, me.ID)
}
package main

import (
	"log"
	"os"

	"github.com/amarnathcjd/gogram/telegram"
)

func main() {
	client, err := telegram.NewClient(telegram.ClientConfig{
		AppID:   12345,
		AppHash: os.Getenv("API_HASH"),
		Session: "bot.session",
	})
	if err != nil {
		log.Fatal(err)
	}

	if err := client.Connect(); err != nil {
		log.Fatal(err)
	}
	if err := client.LoginBot(os.Getenv("BOT_TOKEN")); err != nil {
		log.Fatal(err)
	}

	me, _ := client.GetMe()
	log.Printf("running as @%s (id %d)", me.Username, me.ID)
}

Getting a bot token

  1. Open @BotFather in any Telegram client.
  2. /newbot and answer the two prompts (display name and username).
  3. BotFather replies with an HTTP API token of the form 123456789:ABC-.... That is the string you pass to LoginBot.

What happens behind the scenes

Inside LoginBot:

  1. Connect if neededstep 1
    If the client is not connected yet, Connect runs first, opening the MTProto TCP socket and doing the initial auth-key handshake.
  2. Session checkstep 2
    If the session already contains a valid auth key for this bot, the function returns immediately. Repeated calls are cheap no-ops.
  3. auth.importBotAuthorizationstep 3
    The client calls auth.importBotAuthorization with the parsed api id, hash, and bot token.
  4. Handle DC migrationstep 4
    If the bot lives on a different DC, the server returns USER_MIGRATE_X; the client migrates and retries the call automatically.
  5. Cache and persiststep 5
    On success, the bot's User object is cached and the session is saved to disk (or string).

Privacy mode

Bots in groups only see messages that mention them, reply to them, or look like commands (start with /). To make a bot see every message in a group, turn off privacy mode in BotFather: /mybots → choose your bot → Bot Settings → Group Privacy → Turn off. The setting takes effect after the bot is removed and re-added to existing groups.

Direct messages and channels are unaffected by privacy mode.

What bots cannot do

Bot accounts are restricted by the server. The client will happily call any TL method, but the server returns BOT_METHOD_INVALID for things bots are not allowed to do.

Bot capability matrix
  • Reply to incoming messages
  • Send messages to a user who has started the bot
  • Post to a channel the bot admins
  • Initiate a conversation with a user
    The user must message the bot first (open a private chat, tap /start).
  • Read old message history
    Bots see roughly the last hundred messages in a group and only new messages after being added.
  • Join groups on their own
    Must be added by a user.
  • Contact lookup and phone-based calls
    User-only surface.
  • Fetch dialogs / full participant lists / arbitrary user info
    Returns BOT_METHOD_INVALID.
  • Inline queries
    Enable in BotFather first.
  • Payments, Web Apps, Stars, Business Bots

If you hit a wall, the question is usually "is this a thing a bot account can do?" not "is gogram missing it?". For anything outside the bot box you want a user account.