Skip to content
Nill edited this page Jul 8, 2026 · 6 revisions

The Bot class is a base class for providing low level Bot API functionality. Its usage and lifecycle is what you'd expect -- new one up, give it some settings, hook up some event handlers, and call some methods. Alternatively you can inherit from Bot and override a number of virtual methods in the derived class to achieve the same results without any event wire-up.

Hello World Example

Let's start out really basic:

using Telefrag;
using Telefrag.Bots;
using Telefrag.Telegram.BotAPI;

...

var bot = new Bot("mybot", API_KEY);
var myUserId = 3119302928L;

var msg = await bot.SendMessage((ChatId)myUserId, (HTML)"<B>Hello world</B>");
Console.WriteLine(msg.Dump());

Replace the value of myUserId with your Telegram user_id (you can message @UserInfoBot among other ways of obtaining it). If all goes well, you should receive a Telegram message from your bot upon running this code, and your console should display the JSON representation of the message object you created.

Watch out: Make sure you've started a conversation with your bot previously, bots typically cannot message users that have not previously "started" a conversation with them.

var bot = new Bot("mybot", API_KEY);

In the first line we're obviously instantiating a bot, the "myBot" is an immutable ID we're giving to the bot -- this is used in logging and many other places. It should be unique and it's a good idea (but not required) for it to match your bot's username.

var msg = await bot.SendMessage((ChatId)myUserId, (HTML)"<B>Hello world</B>");

What's happening is that the user id is being implictly converted from a long to a Telefrag.Telegram.BotAPI.ChatId which is an ISendTarget that merely wraps a blind chat_id number. Typically you'd use a User or Chat object obtained from previous updates as a target, but this works as well.

Likewise, the string literal is being cast to an HTML object, which is a wrapper that tells Telegram how to parse the string (whether it will treat it as HTML, plain text, Markdown, or MarkdownV2). See Text for more information on working with text formats.

If Telegram succeeds in sending the message, it returns a Message object, which is what is returned from the asynchronous SendMessage method. If Telegram refuses to send the message or communication with Telegram fails, an exception would be thrown, as expected.

Receiving Data

So far all we did was make an outbound method call (to sendMessage). In order to receive data back from Telegram we need to either enable polling or set up webhooks.

A note about polling For most purposes polling is more than adequate, responsive, and resilient. Setting up webhooks provides better performance when dealing with large volumes of updates (popular bots or bots in popular chats), but requires an internet-facing web server, working DNS, inbound traffic accessibility and valid certificates. Hooking up webhooks requires the use of ASP.NET or another platform that can act as your web server, and is not covered here.

When polling is used, a technique called long polling is employed which results in virtually no delay and a trivial amount of overhead. Telefrag opens a connection to Telegram and requests any queued updates we haven't yet acknolwedged. When there are no remaining updates to send, Telegram holds our request open for a configurable amount of time (default is 60 seconds). If something happens and Telegram needs to update us, it immediately uses the request we already have outstanding to deliver the update quickly. Once we process the update, or if no updates were available prior within the timeout period, we make another request and the cycle repeats.

Replace the call to SendMessage with this code:

bot.Events.UpdateReceived.Subscribe(
    (c, e) => Console.WriteLine(e.Update.Dump()));
    
await bot.Connection.StartPolling();

If this is a console project you may need to add this to prevent your program from terminating automatically:

Console.ReadLine();`

If all goes well, your app should sit at a blank console window. Now send your bot a message on Telegram -- you should see the JSON representation of the Update in your console output.

The first line you added subscribed to the UpdateReceived event with a basic event handler, and the call to StartPolling() started the (perpetual) process of polling Telegram.

You can stop polling if needed using Bot.Connection.StopPolling().

Note: Despite the StartPolling() method being async and awaitable; its Task completes as soon as polling is started successfully and control is returned to your app while polling occurs in the background. The reason the method is async is because it may need to trigger a call to Telegram to remove any existing webhooks and the polling does not actually begin until that API call has completed.

Instantiating a Bot

Constructing Bots

There are several ways to construct bots, choose the method that is easiest based on your needs:

  • You can just use new with any of the constructors listed below.
    • The bot's identity and key can be stored in Configuration
    • The bot's identity and key can be supplied directly
  • You can use Microsoft's DI container if you are configuring a ServiceCollection as part of your application startup
    • Use the AddTelefrag extension method to configure Telefrag with the application
    • Use the AddBot extension method(s) to configure your Bot(s)
  • You can have a parent bot (whether it's a "bot master" in Botfather or not) create child bots as necessary (in Telefrag) -- as long as it can supply the key -- using AddChildBot. This allows it to inherit components registered to the parent bot.

Constructors

Method Signature Remarks
Bot(string id) Creates a Bot
Bot(string id, IBotParent parent) Creates a Bot within a specific parent container
Bot(string id, string apiKey, IBotParent parent) Creates a Bot and sets the ApiKey (Bot.Options.ApiKey)
Bot(string id, BotOptions options, IBotParent parent) Creates a Bot and uses the supplied BotOptions (which includes API Key)
Bot(string id, IConfiguration config) Creates a Bot and attempts to read the options from the IConfiguration provided.

Constructing a Bot using IConfiguration

You can store the values for the settings in BotOptions in a any configuration store that implements IConfiguration, such as appsettings.json. Here is an example of the hierarchy Telefrag expects:

"Telefrag.Bots": {
    "bot_id": {
      "ApiKey": "1234565:qwertyuiopwertyuiortyui"
    }
  }

Calling API Methods

High Level

You can call any of the native Telegram Bot API methods by accessing their C# equivilant functions inside Bot.Methods.

await bot.Methods.BanChatMember(chat, spammer);

Low Level

If you need more control, have existing logic, or want to call a new or experimental method that Telefrag doesn't have a function defined for, you can use a number of low level methods on the BotConnection class:

var msg = bot.Connection.Method<Message>(o => {
       o.text = "hello world",
       o.chat_id = -1029838094,
       o.disable_notifications = true
   }, "sendMessage");
);

Handling Events

Events are exposed via the Events property. Here's an example of capturing the event that fires when the bot initially connects and obtains its own identity.

bot.Events.BotIdentityObtained.Subscribe(handler);

void Handler(Context c, BotIdentityObtainedEventArgs e)
{
    Console.WriteLine($"My bot's username is:  {e.Identity.username}");
    Console.WriteLine($"My bot's ID is:  {e.Identity.id}");
}

Properties

Property Type Description
Connection BotConnection Access to the bot's connection mechanics
Events BotEvents Access to all subscribable events
Id string Unique ID for this bot; providing during creation.
Identity User? The bot's own identity (once it knows it)
IsActive bool Whether or not the bot is active (true) or disposed (false)
Logger ILogger Logger associated with this bot
Methods BotMethods Access to high level method calls
Options BotOptions Configurable options
Parent IBotParent The parent container, if any.
Services IUnityContainer DI container scoped to this Bot

Methods

Method Signature Return Type Description
SendMessage(ISendTarget target, TelegramText text, SendOptions options = default) Task<Message> Sends a message (same as Bot.Methods.SendMessage)
SendReply(ISendTarget target, IMessage message, TelegramText text, SendOptions options = default) Task<Message> Sends a reply message (same as Bot.Methods.SendReply)
Initialize() void Initializes the bot; this is not required to be called by the user. Accessing Methods or Events implicitly initializes the bot if necessary.

Clone this wiki locally