Swiftpack.co - Package - Takanu/Pelican

Pelican 0.8

Telegram API Wrapper for Swift.

Hi, 2-3 people that somehow both like Telegram and Swift! This package gives you a complete set of tools for making bots. It's still a little rough and not everything has been finished, so be careful

If you’ve never heard of Telegram it’s an awesome non-profit, secure messaging service that offers a lot of great features, one of them being a free Bot API where you can make bots for all kinds of tasks, from helping schedule channel posts to operating your own online HTML5 games that are playable inside the app.

Pelican is a framework I've developed personally for my own Telegram games and has a lot of great features:

  • Pelican automates the handling and distribution of updates through a unique session system that you can customise for your own specific needs - no need to make your own.
  • It's multi-threaded by default, with thread-safe session update handling and quick APIs for delaying code and Telegram API calls.
  • Features modular, tree-based routing systems for more advanced and interchangeable update sorting.

The code has extensive API documentation to help you use it, and I will include up-to-date tests and demo code soon. If you have any questions, feel free to message me on GitHub or on Telegram @takanu.

If you're interested in creating games with Pelican, I've also made a great game framework called TrashBoat.


Stars: 19


Used By

Total: 1


Initial Swift 4.2 Merge - 2018-10-14 22:42:15

  • Initial conversion to Swift 4.2
  • Fixed misleading "useWebPreview" argument in the sendMessage Sync and Async method to "disableWebPreview"

🎉🎉🎉 - 2018-04-18 22:52:15

The release seems stable enough to make a "proper" numbered version. Swift Package Manager also really doesn't like pointing at revisions or odd tag names so this was a necessary change for dependency management.

0.8 Beta #6 - 2018-04-18 22:40:46

New SessionRequest Module

  • The "linked sessions" functionality has been removed for accessing other sessions inside sessions, replaced with the SessionRequest type.
  • You can delete, fetch and create new sessions using this, and it will allow you to create multiple sessions for a single Telegram ID.
  • SessionBuilder types now require a name to be defined, which can be used by SessionRequest to precisely locate the type of Session you want to fetch, delete or create.
  • The type previously called SessionRequest has been renamed to MethodRequest, which better expresses it's purpose.


  • SessionTag and Update now use String-based Telegram IDs to ensure flexibility.
  • All TelegramRequest and MethodRequest methods that request a chat or user ID now request it as a string to keep ID types uniform.
  • MethodRequest now has a asynchronous implementation of Telegram's Edit methods, and has fixed sync methods which return a boolean.
  • Most API types have been moved to structs where it made sense.
  • Begun implementation on a SynchronisedDictionary type, used internally to allow a dictionary to be edited and read by multiple threads without any race conditions or state issues. This and it's Array counterpart will be expanded upon and made public later so anyone can utilise them.
  • Added CustomStringConvertible conformance to Route, SessionTag, Update, TelegramRequest and TelegramResponse for better debugging. More types will receive this soon.


  • Please note that Moderator is currently dangerous to use as it has not been properly multi-threaded. The system will be replaced in 0.9 with something better, so it will not yet be fixed.

0.8 Beta #5 - 2018-03-27 01:13:39


  • Fixed some quick sticker-related build issues.

0.8 Beta #4 - 2018-03-27 01:09:44


  • answerInlineQuery and answerCallbackQuery now have async versions.
  • Sticker-related methods have now been implemented, and have both sync and async versions.
  • New location argument when initialising an inlineQuery.
  • When specifying a file path for files to upload and send to Telegram, you can now specify a path outside the project directory using file:// as a suffix. This syntax will likely change in future versions.


  • Added a default value for markup in sendMessage.
  • Updated access control properties for TelegramResponse.
  • Implemented "non-bundle" file fetches in CacheManager.
  • Fixed kickChatMember method name.

0.8 Beta #3 - 2018-03-25 17:39:29

More Bug Fixes

  • Moved the SwiftyJSON dependency to IBM's own implementation to ensure Linux compatibility.
  • Changed various settings and fixed a few things that prevented Pelican from building or running on Linux.

0.8 Beta #2 - 2018-03-25 03:57:48

A Bunch of Fixes

  • Fixed an issue where sending files through File IDs wouldn't work.
  • Made Schedule thread-safe
  • Various smaller fixes

0.8 Beta #1 - 2018-03-22 21:19:26

This took a while... 😰

New Features

Multi-Threaded Design

Pelican is now multi-threaded by design, and will make your bots much speedier and more responsive.

  • Update fetching runs on the main thread and no longer requires a polling interval.
  • When updates are sent to a Session to be handled, they are queued on a Session’s DispatchQueue. This runs sequentially, which means any events from a session that operates within it’s own session are thread-safe.
  • API requests can now be made asynchronously using requests.async.
  • Scheduling events using SessionQueue and Schedule now use a different thread, to ensure more timely and accurate execution of scheduled events. Scheduled events once run will always be run on the DispatchQueue of the Session that created it, in order to preserve thread safety.

Codable Conformance

All API types now conform to Codable, making them easily converted into JSON data, useful for databasing applications.

New Routing System

Route collections and arrays are gone in favour of a tree-branch design. One route is always the base route, and you can always program the behaviour of a route to act like a filter before it reaches other routes.

New UpdateFilter Type

This is for use with Sessions and lets you better manage spam inputs by preventing certain kinds of updates from ever being passed to the Base Route while still triggering both timeout and flood monitors.

Important Changes

Pelican no longer uses Vapor

This was required to be able to handle timeout conditions and better perform and handle other things elsewhere in the framework (like multi-threading) but this doesn’t stop you using Vapor and Pelican together in a single App should you need to.

The upside to this is that Pelican builds waaaaay faster with a smaller footprint and if your computer is anything like mine, Xcode will be far snappier and responsive.

The Request API has changed

When making requests from a Session, a few key things have changed:

  • The SessionRequest type now branches into two other types - sync and async . Sync will let you make requests where your program’s execution will wait for a response from Telegram before continuing, and async will perform the request on a separate thread letting your code execute immediately after being sent.
  • All the request API design now follows the design of the Telegram Bot API in most instances, and has been written with clarity in mind.
  • Every request now requires you to specify the chat ID instead of inferring it from the SessionTag. I might change this in the future to pre-assigned parameter, but ensuring this is exposed is important.

Please Note - The method API in this beta is not complete, and many async methods are still missing.

New Config and Asset Directories

Pelican now has new locations for placing your config file and assets:

Config files

  • Instead of pelican.json, your token file should be called config.json.
  • For bot tokens, make a string entry called “bot_token”
  • For payment tokens, make a string entry called “payment_token”

Asset files

  • To upload local files, place them in a folder called “Resources” instead of “Public”. Thats it.

Other Important Stuff

Some of the contents remain untested, this is an early-ish version of 0.8. If you find any issues, please report them or make a Pull Request.

Don’t hesitate to contact me at t.me/takanu if you have any questions.

Session Closure Fix - 2017-11-01 17:25:03

Package and Swift Upgrades - 2017-10-31 02:08:06

  • The package manifest file now uses Swift Package Manager 4
  • Initial Swift 4 compatibility
  • Now supports Vapor up to the latest 2.x update.

Quick Builder thing and Linux Build Fixes - 2017-10-25 02:47:41

- 2017-10-22 19:20:00

(Sorry for the delay, been working on personal projects using Pelican. It does mean i've been doing a lot more testing though, hence this update)

Prompt (!!!)

It served a useful purpose before the huge 0.7 update, but now i've found this system to be far less useful than mixing custom Route types with custom functions. It tries to do too much at once, and as a result...

  • It is being marked as DEPRECATED for now, and will be removed in a 0.8 update in the future
  • Additional Route types and expanded versions of current Route types will make setting up more complex inline interactions simpler and more transparent than Prompt.


  • Fixed an issue where ScheduleEvent types were not assigning the given Durations correctly


  • Fixed a bug where delays and view timers were calculated incorrectly, causing unpredictable delay timing.


  • Added the ability to automatically drop updates that have no update content or user assigned to them. Use handleEmptyContent and handleEmptyUser respectively.
  • Added the ability to assign names to any Route type, and fetch them from the controller using a subscript (eg. routes["birthday_cake"])
  • Added the ability to disable Routes individually, using route.enabled. Even if a route belongs to a group that is currently enabled, it will not be used to handle an update if disabled.


  • Added by default the Monitor and Flood modules to it (should have done this before...)


  • Removed various miscellaneous prints
  • Moved CasedEnum to its own file under Utilities

Future Release Notes

0.8 is going to have some further API cleanup changes specifically targeted at Telegram Requests to make the API calls more expandable and purposeful.

  • Will be upgrading to Swift 4 to make use of Codable for Bot API types
  • Will be aiming for 100% API compatibility before considering multi-threading and databasing additions


0.7.15 - 2017-10-22 18:33:10


Bug Fixes and Small Changes - 2017-09-13 09:14:11

File Uploads R2 - 2017-09-01 16:53:30

FIle uploading now works and got better!

  • Instead of FileLink, make the Telegram API type you wish to send directly
let photo = Photo(url: "friend.jpg")!
self.send.file(photo, caption: "Here's a friend for you, please be friendly.", markup: nil)
  • This will work with all file-type objects, but not types like Contact yet.

Debug System Tests - 2017-08-24 08:19:55

I added a new debug/logging system that will eventually link to Vapor's own log/console system for normal use. For the time-being its a small, lightweight system designed to debug issues in Pelican.

File Changes + Minor Fixes - 2017-08-21 01:44:58

  • Fixes thumb property parsing for various API types (thanks Leo!)
  • Restructured the file and folder system for the project. Now it's easier to read, manage and maintain.
  • Removed redundant prints
  • Moved the Vapor dependency back to the latest version.

1000% Fixed Connection Issues - 2017-08-20 04:03:11

Please ensure under Config/droplet.json that the Client type is set to "foundation" until Engine is fixed or the mysteries of the universe unravel themselves (probably the former).

Further Connection Tinkering... - 2017-08-19 21:23:17

Fixed Critical Connection Issues - 2017-08-18 19:06:25

Please use this version <3

Network Debug (USE 0.7.5 PLEASE) - 2017-08-18 15:58:58

Currently debugging connection drops here, please continue to use 0.7.5.

- 2017-08-17 00:18:48

- 2017-08-02 03:21:40

- 2017-07-29 02:58:01

SPM Stuff - 2017-07-28 22:33:20

- 2017-07-28 19:08:58

Small UserSession Fixes - 2017-07-28 18:51:44

(0.7) A Really Really Big Re-Factor - 2017-07-27 04:18:34


The re-factor set out to achieve the following goals:

  • Remove anti-patterns and make type relationships more clear.
  • Make code easier to read and maintain.
  • Build in better logical naming patterns through extensive delegation (while also making code easier to maintain, read and isolate).
  • Make the Session creation process customisable.
  • Make the roles of a Session customisable, and enable different combinations of types to be used.

Although with a few caveats that require patching, this re-factor is 99% complete. telepot was partly used in informing better design patterns, so thanks for being there <3

New SessionBuilder type

Sessions can now be created dynamically, letting you setup Sessions for different tasks before Pelican starts.

// Make sure you set up Pelican manually so you can assign it variables.
let config = try Config()
let pelican = try Pelican(config: config)

// Add Builder
pelican.addBuilder(SessionBuilder(spawner: Spawn.perChatID(types: nil), idType: .chat, session: TestUser.self, setup: nil) )

try config.addProvider(pelican)
let drop = try Droplet(config)
try drop.run()

Spawn comes with a few pre-made spawn functions that let you decide based on an incoming message whether or not a Builder can use it, and what ID it should be used to identify or make a new Session from.

New Session Interaction Methods

The way you interact with core Session types like ChatSession has changed dramatically

Route Changes

Updates filtered to routes now only accept an Update as a closure input, but as Sessions can now be defined in a custom way, it's recommended to either sub-class one of the existing Session types or inherit from the Session protocol to define your own.

class TestBot: ChatSession {
	// Do your setup here, this is when the session gets created.
	override func postInit() {
		self.routes.add("/start@SpookyHouseBot", type: .message) { update in
			if update.content == "" || update.from == nil { return false }
			_ = self.send.message("Hi there dude!", markup: markup)

New Delegates

Different delegates included in ChatSession (or that you can add to your own custom session types) neatly categorise possible API calls and tasks.

_ = self.send.message("Hi there @\(update.from!.username!)", markup: markup)

New admin controls from the Bot API 3.1 have been added as a delegate.

let link = self.admin.getInviteLink()

Flood and Timeout Controls

You can now define both Flood and Timeout conditions through two different delegates.

self.flood.add(type: [.message], hits: 50, duration: 120.seconds) {
		self.send.message("Hey, cool off would ya?", markup: nil)
self.timeout.set(updateTypes: [.message, .inlineQuery], duration: 5.minutes) {
		self.send.message("Come back when you're interested.  Bye!", markup: nil)

There's a lot of other changes that would be better explained in other example code. All new delegates and functions have documentation however, so it should be easier to adjust.

Things that don't work

  • File uploads
  • API Methods directly from Pelican (both of these will be re-added in the next update)

Death Test #1 - 2017-07-17 19:59:20

Encapsulates all the large re-factoring work put into making the design of Pelican smarter, more versatile and easier to use.

Sessions R2 (Test #1) - 2017-07-02 21:32:23

Detailed notes forthcoming, test!