Telegram Bot SDK v0.5.0 Release Notes
Release Date: 2016-05-30 // almost 8 years ago-
Message context
The biggest change in this version is the addition of
context
in router handlers. It's also an API breaking change.Consider the old code below:
func commandHandler(args: Arguments) { bot.respondAsync("Hello, \(bot.lastMessage.from.first_name)") { // OK print("Succesfully sent message to \(bot.lastMessage.from.first_name)!") // BAD: bot.lastMessage was overwritten by nextMessage() at this point // and now belongs to another chat and/or user! bot.respondAsync("Bye!") // BAD: bot.respondAsync here will send the message to wrong user // because it uses lastMessage internally! } }
You had to copy
lastMessage
before using it in async block, which was very error-prone:func commandHandler(args: Arguments) { let message = bot.lastMessage bot.respondAsync("Hello, \(message.from.first_name)") { // OK print("Succesfully sent message to \(message.from.first_name)!") // OK bot.respondAsync("Bye!") // STILL BAD, uses bot.lastMessage internally bot.sendMessage(message.chat.id, "Bye!") // OK } }
So, now router handlers have
context
parameter which contains:bot
: a reference to bot.message
: a copy of message.args
: command arguments which can be fetched word-by-word etc.- helper methods like
respondAsync
,respondPrivately(groupText:)
etc.
The code above now works as expected without any additional steps:
func commandHandler(context: Context) { context.respondAsync("Hello, \(context.message.from.first_name)") { // OK print("Succesfully sent message to \(context.message.from.first_name)!") // OK context.respondAsync("Bye!") // OK bot.sendMessage(context.message.chat.id, "Bye!") // OK } }
It's ok to use global
bot
variable, butcontext.bot
is also available. It doesn't matter which one you use.⚡️ The
hello-bot
andword-reverse-bot
examples have been updated to use the new API.Some helper methods were added to
Context
for frequently used variables. For example, you can use:context.fromId
in place ofcontext.message.from.id
context.chatId
in place ofcontext.message.chat.id
context.privateChat
in place ofcontext.message.chat.type == .privateChat
Router can now work with any message types
Another big change: router now accepts messages. You can do things like:
router[.newChatMember] = newChatMember router[.leftChatMember] = leftChatMember router[.document] = onDocument etc func newChatMember(context: Context) throws { let message = context.message guard let newChatMember = message.new_chat_member where newChatMember.id == bot.user.id else { return } ...someone invited bot to chat... }
In addition to
partialMatch
handler there are two new fallback handlers:router.partialMatch = partialMatchHandler router.unknownCommand = unknownCommandHandler router.unsupportedContentType = unsupportedContentTypeHandler
0️⃣ They have a reasonable default implementations, but can be overridden.
Other changes
- ⚡️
bot.lastCommand
,bot.lastMessage
andbot.lastUpdate
are no longer available. Addedbot.lastUpdateId
which can be used for debugging purposes. - ➕ Added generic
requestSync
andrequestAsync
requests which can be used for any requests. All other requests now use these functions internally. - All async request completion handlers now consistently return
(result, error)
tuple. Result type is different depending on request. - 👌 Supported
array of objects
as request return value, simplifiedgetUpdates
request. - ➕ Added
leaveChat
request. - 👀
Bool
type now conforms toJsonObject
and can be used as request result. SeeleaveChat
for example.