I recommend you read all of these as you will learn many interesting things. Or you can use Ctrl-F to search for a specific topic.
- Follow this installation guide to install the latest versions of the library.
- Here is the main documentation website.
- You can find more bot example projects here
- Search the official API documentation and official bots FAQ.
- check tooltips in your IDE, or navigate with F12 on API methods and read/expand comments.
If you're C# beginner, you should learn about async programming.
You likely have an exception somewhere. You should place a try..catch
around your whole update handler.
Also, you should learn to use a debugger and go step-by-step through your code to understand where and why an exception is raised. See next question.
Not all updates are about an incoming Message, so update.Message
could be null. (see also update.Type
)
Not all messages are text messages, message.Text
could be null (see also message.Type
). etc...
So please use a debugger to check the content of your variables or structure fields and make sure your code can handle all cases.
Pass an InlineKeyboardMarkup into the replyMarkup
parameter when sending the message. You will likely need to create a List<List<InlineKeyboardButton>>
for rows&columns
See also next question.
For buttons with callback data, your update handler should handle update.CallbackQuery
.
(Remember that not all updates are about update.Message
. See question #3)
Your code should answer to the query within 10 seconds, using AnswerCallbackQuery
(or else the button gets momentarily disabled)
It is only possible with inline callback button (see above questions).
Use AnswerCallbackQuery
with some text, and pass parameter showAlert: true
to display the text as an alert box instead of a short popup.
There is not a simple direct method for this, but here is what you can try:
- With a Public username link:
t.me/username?text=Hello+World
(works only if target is a user/bot and not the current chat) - With a Share link:
tg://msg_url?url=https://example.com&text=Hello+World
(user must select a target first) - With a Bot deep link:
t.me/botusername?start=param
(param is limited to base64 characters, bot will receive/start param
) - With a ReplyKeyboardMarkup: buttons under the textbox to send pre-made texts
- With an Inline Mode bot and
SwitchInlineQuery
inline buttons, you can make the user pre-type the name of your bot followed by some query
You can't with Bot API but it's possible with WTelegramBot.
Normally, bots only get messages at the moment they are posted. You could archive them all in a database for later retrieval.
You can't with Bot API but it's possible with WTelegramBot.
Normally, bots can only get the list of admins (GetChatAdministrators
) or detail about one specific member (GetChatMember
)
Alternatively, you can keep track of users by observing new messages in a chat and saving user info into a database.
You can't. Bots can only send private messages to users that have already initiated a private chat with your bot.
You would have received an update.MyChatMember
with NewChatMember.Status == ChatMemberStatus.Kicked
If you didn't record that info, you can try to SendChatAction
and see if it raises an exception.
Set the media.Caption
(and media.ParseMode
) on the first media
Either you can code a complex state machine workflow, saving where each user is currently in the discussion tree.
Or you can just use YourEasyBot which makes sequential bots very simple to write... (or one of the other frameworks available for Telegram.Bot)
Pass a ParseMode.Html
(or ParseMode.MarkDownV2
) to argument parseMode
. See formatting options.
I would recommend you make an ASP.NET webhook bot and host it on some WebApp hosting service.
For example, Azure WebApp Service has a F1 Free plan including 1 GB disk, 1 GB ram, 60 minutes of daily cumulated active CPU usage (more than enough for most bots without heavy use). And publishing to Azure is very easy from VS.
A credit-card is necessary but you shouldn't get charged if you stay within quotas.
Other cloud providers might also offer similar services.
See https://limits.tginfo.me for a list of limitations.
You can either do this via @BotFather (static entries), or you can use SetMyCommands
for more advanced settings
/
and containing only latin characters a-z_0-9
You should specify all update types including ChatMember in AllowedUpdates
array on StartReceiving
:ReceiverOptions
or SetWebhook
More details here
Pass true into StartReceiving
:ReceiverOptions
:DropPendingUpdates
or SetWebhook
:dropPendingUpdates
Alternatively, you can call await bot.DropPendingUpdates()
before polling or using bot.OnUpdate
.
- Make sure you
await
until the end of the send method before closing the file (a "using
" clause would close the file on leaving the current { scope } - If you just filled a
MemoryStream
, make sure to rewind it to the beginning withms.Position = 0;
before sending - If you send a media group, make sure you specify different filenames on
InputFile.FromStream
Medias in a media group are received as separate consecutive messages having the same MediaGroupId
property. You should collect them progressively as you receive those messages.
There is no way to know how many medias are in the album, so:
- look for consecutive messages in that chat with same
MediaGroupId
and stop when it's not the same - stop after 10 medias in the group (maximum)
- use a timeout of a few seconds not receiving new messages in that chat to determine the end
- First you need to buy a reserved username on Fragment.
- Then you need to pay an additional upgrade fee of 1K TON to apply that username to your bot.
- Finally, your bot can now post custom emojis using specific HTML or Markdown syntax (or entity).
To post to a specific group, there is an alternative solution:
- Have premium members boost your group to Level 4.
- Then you can assign a custom emoji pack to your group that your members AND bots can use freely in group messages.
A new lead developer (Wizou) is now in charge of the library and commits to reduce code-breaking changes in the future.
Version 21.x of the library and later have been much improved to facilitate migration from previous versions of the library, and include a lot of helpers/implicit operators to simplify your code.
You can call API methods (like sending messages) from several instances in parallel
BUT only one instance can call method GetUpdates (or else you will receive Telegram API Error 409: Conflict: terminated by other getUpdates request)
You can't with Bot API but it's possible with WTelegramBot.
Alternatively, you could store in database the mapping of UserId
<->Username
.
Remember that not every user has a username, and it can be changed.
Your bot has to be added as administrator of the channel.
You will then receive the messages as update.ChannelPost
or update.EditedChannelPost
.
The first time, you will send the media with a stream (upload). Next times, you will use its FileId:
var sent = await bot.SendVideo(chatId, stream, ....);
var fileId = sent.Video.FileId
// next times:
await bot.SendVideo(chatId2, fileId, ...);
For photos, use sent.Photo[^1].FileId
Feel free to join our Telegram group and ask your question there