This guide walks you through creating your first ExGram bot from scratch.

Prerequisites

Make sure you have:

Create a New Project

Create a new Elixir project with supervision tree:

mix new my_bot --sup
cd my_bot

Install ExGram

Add ExGram to mix.exs as shown in the Installation guide, then:

mix deps.get

Add formatter (Optional)

It is recommended to add ExGram to your .formatter.exs deps, that way the DSL will look clean.

# .formatter.exs
[
    # ....
    import_deps: [:ex_gram] # Add :ex_gram here
]

Generate Your Bot

ExGram provides a Mix task to generate a bot module:

mix bot.new

This creates lib/my_bot/bot.ex with a basic bot structure:

defmodule MyBot.Bot do
  @bot :my_bot

  use ExGram.Bot,
    name: @bot,
    setup_commands: true

  command("start")
  command("help", description: "Print the bot's help")

  middleware(ExGram.Middleware.IgnoreUsername)

  def handle({:command, :start, _msg}, context) do
    answer(context, "Hi!")
  end

  def handle({:command, :help, _msg}, context) do
    answer(context, "Here is your help:")
  end
end

Understanding the Generated Bot

  • @bot :my_bot - Internal name for your bot
  • use ExGram.Bot - Imports the bot framework
  • setup_commands: true - Automatically registers commands with Telegram
  • command/1-2 - Declares commands that your bot handles
  • middleware/1 - Adds middleware to the processing pipeline (see ExGram.Middleware)
  • handle/2 - Handles incoming updates (callback from ExGram.Handler.handle/2)

Configure Your Application

Get your bot token from @BotFather and configure it in config/config.exs:

import Config

config :ex_gram,
  token: "YOUR_BOT_TOKEN_HERE"

Security Note: For production, use environment variables instead:

config :ex_gram,
  token: System.get_env("BOT_TOKEN")

Add Bot to Supervision Tree

Open lib/my_bot/application.ex and add ExGram and your bot to the children list:

defmodule MyBot.Application do
  use Application

  @impl true
  def start(_type, _args) do
    children = [
      ExGram,
      {MyBot.Bot, [method: :polling, token: Application.fetch_env!(:ex_gram, :token)]}
    ]

    opts = [strategy: :one_for_one, name: MyBot.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

Key points:

  • ExGram must be started before your bot
  • method: :polling - Use polling to receive updates, learn more about how to get updates in this guide
  • token: - Pass the token explicitly

Run Your Bot

Start your bot:

mix run --no-halt

Open Telegram and send /start to your bot. It should reply with "Hi!"

Token Configuration Options

1. Global Config + Explicit on bot

If you just have one bot, this combination will allow you to use the DSL and the normal methods without any problem.

# config/config.exs
config :ex_gram, token: "TOKEN"

# lib/my_bot/application.ex
token = System.get_env("BOT_TOKEN") || Application.fetch_env!(:ex_gram, :token)
{MyBot.Bot, [method: :polling, token: token]}

2. Only global config

If you are just going to use the normal methods, no ExGram.Bot bots, then you can just configure the global token.

# config/config.exs
config :ex_gram, token: "TOKEN"

3. Runtime Configuration

DO NOT hardcode any token in any configuration file or source code. It's the most common reason people publish secret tokens by mistake.

The easiest way to avoid this is to have a config/runtime.exs

# config/runtime.exs
import Config

if config_env() == :prod do
  config :ex_gram, token: System.fetch_env!("BOT_TOKEN")
end

# config/config.exs
config :ex_gram, token: "fake token"

Next Steps

Now that you have a working bot:

Troubleshooting

Bot doesn't respond

  1. Verify your token is correct
  2. Check logs for errors: Logger.configure(level: :debug)

"Registry.ExGram not started"

Make sure ExGram is in your supervision tree before your bot.