All Versions
Latest Version
Avg Release Cycle
63 days
Latest Release
1479 days ago

Changelog History
Page 3

  • v0.9.0 Changes

    June 27, 2016

    Major changes:

    • Project ported to Swift 3.0 Snapshot 2016-06-20 (a). Xcode8 is required.

    • 💎 Types and Requests (methods) are now generated automatically from Telegram docs by a Ruby script located in API/ directory.

    • 👍 All types and requests are now supported.

    • Optional parameters added to request signatures. This code:

    bot.sendMessage(chatId, "text", ["reply_markup": markup])

    Can now be written as:

    bot.sendMessage(chatId, "text", reply_markup: markup)

    You can still pass an array with additional arguments at the end of parameters list if needed.

    Other changes:

    • 👍 Router now supports multiple comma separated paths:
    router["List Items", "list"] = onListItems
    • 0️⃣ Router is now case insensitive by default.

    • 👍 Multiword commands are now supported:

    router["list add"] = onListAdd
    router["list remove"] = onListRemove
    • 👍 Router chaining is now supported. Use handler method to use Router as a handler:

    router1.unmatched = router2.handler

    • To force the use of slash, instead of slash: .required option use:
    router["command", .slashRequired] = handler

    Multiple flags can be specified:

    router["command", [.caseSensitive, .slashRequired]] = handler
    • context.args.command is now context.command.

    • 🆕 New variable: context.slash. True, if command was prefixed with a slash.

    • router.unknownCommand handler renamed to router.unmatched

    • 👌 Support callback_query in Router.

    • JsonObject protocol renamed to JsonConvertible.

    • Context.message is now optional. Also, it fallbacks to edited_message and callback_query.message when nil.

    • Unknown command handler will no longer treat the first word as a command and will pass the entire string to a handler unchanged. Context.command will be empty.

    • partialMatchHandler return value is now ignored. It can no longer cancel commands.

    • All types changed from classes to structs.

    • HTTP error codes except 401 (authentication error) are no longer fatal errors. TelegramBot will try to reconnect when encountering them.

  • v0.8.0 Changes

    June 15, 2016
    • ⬆️ Upgrade to Xcode 8 (Swift 3.0 Preview 1)
    • 🛠 Bugfix: "unknown command" / "unsupported content type" messages are no longer sent to group chats.
  • v0.7.0 Changes

    June 13, 2016
    • All enums renamed to match Swift 3 guidelines.
    • 🛠 Request function signatures changed: parameters label is no longer explicit, added missing enum to sendChatAction and a few other fixes.
    • 🛠 Bugfix: ReplyKeyboardHide is now JsonObject.
    • 🛠 Bugfix: getMeAsync is now public.
    • 🛠 Bugfix: default parameters now work correctly. For example, to disable notifications for all sendMessage calls, do:
    bot.defaultParameters["sendMessage"] = {"disable_notification": true}
    • Int now conforms to JsonObject and can be used as Request's return value.
    • 🛠 Fixed existing tests and added more tests.
    • ⚠ When trying to access the message via context.message non-optional shortcut and the message was nil initially, a warning will be printed.
    • Added .new_chat_member router path to hello-bot sample project.
  • v0.6.2 Changes

    June 08, 2016
    • Ported to Swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a.
  • v0.6.0 Changes

    June 08, 2016
    • 🚚 Router handlers now take Context and return Bool. Other overloads were removed. This was done to simplify Router usage with closures. Closure signatures had to be specified explicitly, but now they can be inferred automatically.
    • Message.from is now Optional.
    • ➕ Add readConfigurationValue helper function which tries to read a single value from environment variable or from a file.
    • 📄 Request methods are now snake case like structure fields to match Telegram Bot API docs.
    • ⚡️ Examples updated to use the new API.
    • ➕ Added all types and requests except inline types.
    • ➕ Added missing fields which appeared in API 2.0 to all types.
    • ⚡️ Router now works with Updates instead of Messages.
    • 👍 Allow using raw JSON in requestAsync / requestSync.
    • Chat and user ids are now Int64.
  • v0.5.1 Changes

    May 31, 2016

    ➕ Added ReplyKeyboardMarkup which can be used with Strings:

            let markup = ReplyKeyboardMarkup()
            markup.keyboardStrings = [["/a", "/b"], ["/c", "/d"]]
            context.respondAsync("Simple keyboard", parameters: ["reply_markup": markup])

    Or with KeyboardButtons:

            let button1 = KeyboardButton()
            button1.text = "Request contact"
            button1.request_contact = true
            let button2 = KeyboardButton()
            button2.text = "Request location"
            button2.request_location = true
            markup.keyboardButtons = [ [ button1, button2 ] ]
            context.respondAsync("Another keyboard", parameters: ["reply_markup": markup])
  • v0.5.0 Changes

    May 30, 2016

    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!
            // 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(, "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(, "Bye!") // OK

    It's ok to use global bot variable, but is also available. It doesn't matter which one you use.

    ⚡️ The hello-bot and word-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 of
    • context.chatId in place of
    • context.privateChat in place of == .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
    func newChatMember(context: Context) throws {
        let message = context.message
        guard let newChatMember = message.new_chat_member where
     == 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 and bot.lastUpdate are no longer available. Added bot.lastUpdateId which can be used for debugging purposes.
    • ➕ Added generic requestSync and requestAsync 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, simplified getUpdates request.
    • ➕ Added leaveChat request.
    • 👀 Bool type now conforms to JsonObject and can be used as request result. See leaveChat for example.