🤖 The wrapper for the Telegram Bot API written in Swift. It's not a framework. There is no special syntax here. This is a library that implements all Telegram Bot API methods, which is available to you to work with Vapor, Smoke, FlyingFox.
Swift Server Side Community - Ukraine / Russian / CIS Telegram Chat
For now with swift 6 please use 4.0.0 and above
- Clone one of examples
git clone https://github.com/nerzh/swift-telegram-bot
cd swift-telegram-bot/Examples/Vapor-Telegram-Bot
- Add your telegram bot id to configure.swift
let botId: String = "XXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
- Run in Xcode or build and run binary file
- check commands in your telegram bots
- /ping
- /show_buttons
- Vapor Telegram Bot
- Hummingbird Telegram Bot (AsyncHttpClient)
- Hummingbird Telegram Bot (URLSession)
- Smoke Telegram Bot (AsyncHttpClient)
- FlyingFox Telegram Bot (AsyncHttpClient)
import SwiftTelegramBot
import Logging
let tgApi: String = "XXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY"
var logger: Logger = .init(label: "swift_telegram_bot")
logger.logLevel = .error
let connectionType: TGConnectionType = .longpolling()
let connectionType: TGConnectionType = .webhook(webHookURL: URL(string: "\(TG_WEBHOOK_DOMAIN!)/\(TGWebHookRouteName)")!)
/// Add route for webhook. For example Vapor:
/// routes.swift
func routes(_ app: Application) throws {
try app.register(collection: TelegramController())
}
/// TelegramController.swift
final class TelegramController: RouteCollection {
func boot(routes: Vapor.RoutesBuilder) throws {
routes.post(TGWebHookRouteName, use: telegramWebHook)
}
func telegramWebHook(_ req: Request) async throws -> Bool {
let update: TGUpdate = try req.content.decode(TGUpdate.self)
Task { await bot.processing(updates: [update]) }
return true
}
}
let bot: TGBot = try await .init(connectionType: connectionType,
tgClient: TGClientDefault(),
tgURI: TGBot.standardTGURL,
botId: botId,
log: logger)
/// add dispatcher with some bot logic
try await bot.add(dispatcher: TestDispatcher.self)
/// try await bot.add(dispatcher: SecondDispatcher.self)
/// etc
try await bot.start()
import SwiftTelegramBot
class TestDispatcher: TGDefaultDispatcher, @unchecked Sendable {
override
func handle() async {
/// defaultBaseHandler example
await add(TGBaseHandler({ update in
guard let message = update.message else { return }
let params: TGSendMessageParams = .init(chatId: .chat(message.chat.id), text: "TGBaseHandler")
try await self.bot.sendMessage(params: params)
}))
/// commandPingHandler example
await add(TGCommandHandler(commands: ["/ping"]) { update in
try await update.message?.reply(text: "pong", bot: self.bot)
})
/// commandShowButtonsHandler example
await add(TGCommandHandler(commands: ["/show_buttons"]) { update in
guard let userId = update.message?.from?.id else { fatalError("user id not found") }
let buttons: [[TGInlineKeyboardButton]] = [
[.init(text: "Button 1", callbackData: "press 1"), .init(text: "Button 2", callbackData: "press 2")]
]
let keyboard: TGInlineKeyboardMarkup = .init(inlineKeyboard: buttons)
let params: TGSendMessageParams = .init(chatId: .chat(userId),
text: "Keyboard active",
replyMarkup: .inlineKeyboardMarkup(keyboard))
try await self.bot.sendMessage(params: params)
})
/// buttonsActionHandler 1 example
await add(TGCallbackQueryHandler(pattern: "press 1") { update in
await self.bot.log.info("press 1")
guard let userId = update.callbackQuery?.from.id else { fatalError("user id not found") }
let params: TGAnswerCallbackQueryParams = .init(callbackQueryId: update.callbackQuery?.id ?? "0",
text: update.callbackQuery?.data ?? "data not exist",
showAlert: nil,
url: nil,
cacheTime: nil)
try await self.bot.answerCallbackQuery(params: params)
try await self.bot.sendMessage(params: .init(chatId: .chat(userId), text: "press 1"))
})
/// buttonsActionHandler 2 example
await add(TGCallbackQueryHandler(pattern: "press 2") { update in
await self.bot.log.info("press 2")
guard let userId = update.callbackQuery?.from.id else { fatalError("user id not found") }
let params: TGAnswerCallbackQueryParams = .init(callbackQueryId: update.callbackQuery?.id ?? "0",
text: update.callbackQuery?.data ?? "data not exist",
showAlert: nil,
url: nil,
cacheTime: nil)
try await self.bot.answerCallbackQuery(params: params)
try await self.bot.sendMessage(params: .init(chatId: .chat(userId), text: "press 2"))
})
}
}
To configure and run a bot with or without any framework, you need to use TGClientDefault or implement a simple TGClient protocol to send requests to the network with Content-Type: multipart/form-data. You can see an example here: TGClientDefault
public protocol TGClientPrtcl {
@discardableResult
func post<Params: Encodable, Response: Decodable>(_ url: URL, params: Params?, as mediaType: HTTPMediaType?) async throws -> Response
@discardableResult
func post<Response: Decodable>(_ url: URL) async throws -> Response
}
add to yor Package.json
// swift-tools-version:6.0
import PackageDescription
var packageDependencies: [Package.Dependency] = [
.package(url: "https://github.com/vapor/vapor.git", .upToNextMajor(from: "4.57.0")),
]
packageDependencies.append(.package(url: "https://github.com/nerzh/swift-telegram-bot", .upToNextMajor(from: "4.0.0")))
let package = Package(
name: "Telegram-bot-example",
platforms: [
.macOS(.v12)
],
dependencies: packageDependencies,
targets: [
.executableTarget(
name: "Telegram-bot-example",
dependencies: [
.product(name: "Vapor", package: "vapor"),
.product(name: "SwiftTelegramBot", package: "swift-telegram-bot"),
]
)
]
)
Inspired by Telegrammer