REPOSITORY / ScuroNeko/Laniakea

Wiki

KNOWLEDGE REPOSITORY
3
Auto Generated Commands
ScuroNeko edited this page 2026-05-20 13:22:27 +03:00

Auto-Generated Commands

Russian version: Auto-Generated-Commands-RU

This page explains how Laniakea derives Telegram command metadata from registered plugins and publishes it through the Bot API. It covers AutoGenerateCommands(...), scope-specific registration, skip controls, and the command-name rules Telegram enforces.

What auto-generation does

Laniakea can scan registered plugins, collect eligible commands, and publish them through Telegram's setMyCommands API.

This is useful when you want Telegram clients to show:

  • command lists;
  • slash-command suggestions;
  • per-scope command metadata.

The feature works from command definitions you already registered in plugins, so you do not need to maintain a second separate command list by hand.

Entry points

There are two main methods:

  • AutoGenerateCommands()
  • AutoGenerateCommandsForScope(scope)

Use AutoGenerateCommands() when you want the same generated commands across the default built-in scopes used by the library.

Use AutoGenerateCommandsForScope(...) when you want to manage one explicit scope yourself.

What AutoGenerateCommands() publishes

AutoGenerateCommands():

  • gathers eligible commands from registered plugins;
  • validates the total command count;
  • deletes existing Telegram commands;
  • registers the new command set for three scopes:
    • private chats;
    • group chats;
    • all chat administrators.

This gives you a simple one-call setup for common bots.

What AutoGenerateCommandsForScope(...) publishes

AutoGenerateCommandsForScope(scope) does the same gathering and validation, but only for the specific scope you pass in.

Use it when:

  • you want different commands for different audiences;
  • you want to manage scopes one by one;
  • you are integrating command registration into a custom deployment or setup flow.

Example:

scope := &tgapi.BotCommandScope{Type: tgapi.BotCommandScopePrivateType}
if err := bot.AutoGenerateCommandsForScope(scope); err != nil {
	return err
}

Where generated commands come from

The generator walks registered plugins and collects commands from them.

A command is included only if:

  • the plugin itself is not marked with SkipCommandAutoGen();
  • the command itself is not marked with SkipCommandAutoGen();
  • the command name matches Telegram's allowed format.

Payload handlers are not part of auto-generated slash commands. This feature only targets actual command registrations.

Command descriptions

Generated command descriptions are built from:

  • the command description, if one is set;
  • the command arguments, rendered into usage text.

If a command has a description and arguments, the generated result looks like:

Short description. Usage: /command <required> [optional]

If no description is set, the generated text still includes a usage line.

That means commands are more useful in Telegram menus when you provide:

  • SetDescription(...);
  • meaningful CommandArg names.

Telegram command name rules

Laniakea validates command names against Telegram's command-registration rules before publishing.

The allowed pattern is:

  • lowercase letters a-z
  • digits 0-9
  • underscore _
  • length 1..32

Commands that do not match that pattern are skipped during auto-generation.

Important nuance:

  • a command can still exist in your internal routing logic with a name that is not suitable for Telegram command menus;
  • it just will not be exported through auto-generation.

Command count limit

Telegram limits the number of published bot commands to 100.

Laniakea checks this before making API calls. If the generated command set is larger than 100, auto-generation returns ErrTooManyCommands.

This early validation is helpful because it fails before any delete or set command request is sent.

Skip controls

There are two skip levels:

Skip a single command

plugin.Command("internal", exec).
	SetDescription("Internal only").
	SkipCommandAutoGen()

Use this when a command should remain callable but should not appear in Telegram's published menu.

Skip an entire plugin

plugin.SkipCommandAutoGen()

Use this when all commands in the plugin are internal, temporary, admin-only, or otherwise not meant for global command publication.

Ordering behavior

Within a plugin, commands are gathered in sorted order by command name.

This makes published command lists deterministic, which is useful for:

  • predictable diffs and tests;
  • stable behavior across runs;
  • easier reasoning when command sets grow.

Typical usage

Call auto-generation after:

  • creating the bot;
  • registering all plugins;
  • finalizing command descriptions and argument definitions.

Example:

bot.AddPlugins(mainPlugin, adminPlugin)

if err := bot.AutoGenerateCommands(); err != nil {
	return err
}

If plugin configuration changes after registration, remember that plugin state is snapshotted at AddPlugins(...), so finish command setup before registering plugins with the bot.

Good command metadata practices

To make generated commands useful in Telegram clients:

  • keep command names short and stable;
  • provide SetDescription(...) for user-facing commands;
  • give CommandArg values readable names such as user, count, or reason;
  • hide internal commands with SkipCommandAutoGen().

Common reasons to use scope-specific registration

AutoGenerateCommandsForScope(...) is especially useful when:

  • private chats should expose a richer command set than groups;
  • admin commands should only be visible to administrators;
  • you want a staged rollout of command menus.

In those cases, manage each relevant scope explicitly instead of using the all-scopes helper.

Caveats

  • Auto-generation talks to Telegram and can return API errors.
  • It deletes existing commands in the target scope before setting the new list.
  • Only commands, not payload handlers, participate.
  • Invalid command names are skipped rather than forcefully normalized.