cl-telegram-bot
cl-telegram-bot copied to clipboard
Telegram Bot API for Common Lisp
cl-telegram-bot - Telegram Bot API
CL-TELEGRAM-BOT ASDF System Details
- Description: Telegram Bot
API, based on sovietspaceship's work but mostly rewritten. - Licence:
MIT - Author: Alexander Artemenko [email protected]
- Homepage: https://40ants.com/cl-telegram-bot/
- Bug tracker: https://github.com/40ants/cl-telegram-bot/issues
- Source control: GIT
- Depends on: alexandria, arrows, bordeaux-threads, cl-ppcre, cl-strings, closer-mop, dexador, jonathan, kebab, log4cl, serapeum, str, trivial-backtrace
Installation
You can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:
(ql-dist:install-dist "http://dist.ultralisp.org/"
:prompt nil)
(ql:quickload :cl-telegram-bot)
Quickstart
The system uses CLOS to add new methods to process incoming messages.
To create a simple bot, all you need is to define on-message method.
If you want to match on a particular command, like /help or /make-me-happy 7 times,
then you better to define a on-command method.
During messages processing, function (reply "some text") is available, which will send
given text into the right chat. Also, there is send-message and other function exists
which allow your bot to post messages, images and other media into the any chat.
Here is example of a simple bot which reacts on the text message and /echo command:
CL-USER> (defpackage the-bot (:use :cl :cl-telegram-bot))
#<Package "THE-BOT">
CL-USER> (in-package the-bot)
#<Package "THE-BOT">
THE-BOT> (defbot echo-bot)
MAKE-ECHO-BOT
THE-BOT> (defmethod on-message ((bot echo-bot)
text)
(reply text))
#<STANDARD-METHOD ON-MESSAGE (ECHO-BOT T)>
THE-BOT> (defmethod on-command ((bot echo-bot)
(command (eql :help))
text)
(declare (ignorable text))
(reply "Just send me any text and I'll reply with the same text."))
#<STANDARD-METHOD ON-COMMAND (ECHO-BOT (EQL :HELP) T)>
THE-BOT> (defmethod on-command ((bot echo-bot)
(command (eql :start))
text)
(declare (ignorable text))
(reply "Welcome Lisper! Have a fun, playing with cl-telegram-bot!"))
#<STANDARD-METHOD ON-COMMAND (ECHO-BOT (EQL :START) T)>
Now, stop for the minute, open your Telegram client, and create a new bot using the BotFather bot:

When you've got token, return to the REPL and start our bot:
THE-BOT> (start-processing (make-echo-bot "5205125**********************************")
:debug t)
<INFO> [08:31:09] cl-telegram-bot core.lisp (start-processing) - Starting thread to process updates for CL-TELEGRAM-BOT/CORE::BOT: #<ECHO-BOT id=0>
#<PROCESS telegram-bot(33) [Reset] #x30200709246D>
THE-BOT>
This will start a new thread for processing incoming messages.
Now, find your bot in the Telegram client:

And start communicating with him:

API
CL-TELEGRAM-BOT/BOT
package cl-telegram-bot/bot
Classes
BOT
class bot ()
Readers
reader api-uri (bot) (:API-URI = "https://api.telegram.org/")
reader debug-mode (bot) (:debug-mode = nil)
When debug mode is T, then interactive debugger will be called on each error.
reader file-endpoint (bot) (:file-endpoint = nil)
HTTPS file-endpoint
reader get-endpoint (bot) (:endpoint)
HTTPS endpoint
reader get-last-update-id (bot) (= 0)
Update id
reader sent-commands-cache (bot) (= nil)
Command processing code will use this cache to update commands list on the server
when a new method for cl-telegram-bot/entities/command:on-command generic-function is defined.
This slot is for internal use.
reader token (bot) (:token = nil)
Bot token given by BotFather
Accessors
accessor api-uri (bot) (:API-URI = "https://api.telegram.org/")
accessor debug-mode (bot) (:debug-mode = nil)
When debug mode is T, then interactive debugger will be called on each error.
accessor file-endpoint (bot) (:file-endpoint = nil)
HTTPS file-endpoint
accessor get-last-update-id (bot) (= 0)
Update id
accessor sent-commands-cache (bot) (= nil)
Command processing code will use this cache to update commands list on the server
when a new method for cl-telegram-bot/entities/command:on-command generic-function is defined.
This slot is for internal use.
accessor token (bot) (:token = nil)
Bot token given by BotFather
Macros
macro defbot name
CL-TELEGRAM-BOT/CALLBACK
package cl-telegram-bot/callback
Classes
CALLBACK
class callback ()
Readers
reader callback-data (callback) (:data)
reader callback-id (callback) (:id)
reader callback-message (callback) (:message)
Generics
generic-function callback-chat callback
Returns a chat from where callback was sent.
generic-function make-callback bot callback-data
Called when user clicks callback button. Should return an instance of callback class.
Application may override this method to return objects of different callback classes depending on
callback-data string. This way it mab be easier to define more specific methods for
on-callback generic-function.
generic-function on-callback bot callback
Called when user clicks callback button. Second argument is an object of CALLBACK type.
CL-TELEGRAM-BOT/CHAT
package cl-telegram-bot/chat
Classes
CHANNEL
class channel (base-group)
CHAT
class chat ()
Readers
reader get-chat-id (chat) (:id)
reader get-has-protected-content (chat) (:has-protected-content)
reader get-message-auto-delete-time (chat) (:message-auto-delete-time)
reader get-raw-data (chat) (:raw-data)
reader get-username (chat) (:username)
GROUP
class group (base-group)
PRIVATE-CHAT
class private-chat (chat)
Readers
reader get-bio (private-chat) (:bio)
reader get-first-name (private-chat) (:first-name)
reader get-has-private-forwards (private-chat) (:has-private-forwards)
reader get-last-name (private-chat) (:last-name)
SUPER-GROUP
class super-group (base-group)
Readers
reader get-can-set-sticker-set (super-group) (:can-set-sticker-set)
reader get-join-by-request (super-group) (:join-by-request)
reader get-join-to-send-messages (super-group) (:join-to-send-messages)
reader get-slow-mode-delay (super-group) (:slow-mode-delay)
reader get-sticker-set-name (super-group) (:sticker-set-name)
Functions
function delete-chat-photo bot-var1 chat
https://core.telegram.org/bots/api#deletechatphoto
function export-chat-invite-link bot-var1 chat
https://core.telegram.org/bots/api#exportchatinvitelink
function get-chat-administrators bot-var1 chat
https://core.telegram.org/bots/api#getchatadministrators
function get-chat-by-id bot-var1 chat-id
https://core.telegram.org/bots/api#getchat
function get-chat-member bot-var1 chat user-id
https://core.telegram.org/bots/api#getchatmember
function get-chat-members-count bot-var1 chat
https://core.telegram.org/bots/api#getchatmemberscount
function kick-chat-member bot-var1 chat user-id until-date
https://core.telegram.org/bots/api#kickchatmember
function leave-chat bot-var1 chat
https://core.telegram.org/bots/api#leavechat
function pin-chat-message bot-var1 chat message-id disable-notification
https://core.telegram.org/bots/api#pinchatmessage
function promote-chat-member bot-var1 chat user-id can-change-info can-post-messages can-edit-messages can-delete-messages can-invite-users can-restrict-members can-pin-messages can-promote-members
https://core.telegram.org/bots/api#promotechatmember
function restrict-chat-member bot-var1 chat user-id until-date can-send-messages can-send-media-messages can-send-other-messages can-add-web-page-previews
https://core.telegram.org/bots/api#restrictchatmember
function send-chat-action bot-var1 chat action
https://core.telegram.org/bots/api#sendchataction
function set-chat-description bot-var1 chat description
https://core.telegram.org/bots/api#setchatdescription
function set-chat-photo bot-var1 chat photo
https://core.telegram.org/bots/api#setchatphoto
function set-chat-title bot-var1 chat title
https://core.telegram.org/bots/api#setchattitle
function unban-chat-member bot-var1 chat user-id
https://core.telegram.org/bots/api#unbanchatmember
function unpin-chat-message bot-var1 chat
https://core.telegram.org/bots/api#unpinchatmessage
CL-TELEGRAM-BOT/CORE
package cl-telegram-bot/core
Classes
REPLY
class reply (response-with-text)
Generics
generic-function on-command bot command rest-text
This method will be called for each command. First argument is a keyword. If user input was /save_note, then first argument will be :save-note.
By default, logs call and does nothing.
generic-function on-message bot text
This method gets called with raw text from the message. By default it does nothing.
Functions
function reply text &rest args &key parse-mode disable-web-page-preview disable-notification reply-to-message-id reply-markup (immediately t)
Works like a send-message, but only when an incoming message is processed.
Automatically sends reply to a chat from where current message came from.
function start-processing BOT &KEY DEBUG (DELAY-BETWEEN-RETRIES 10) (THREAD-NAME "telegram-bot")
function stop-processing bot
Macros
macro defbot name
CL-TELEGRAM-BOT/ENTITIES/COMMAND
package cl-telegram-bot/entities/command
Classes
BOT-COMMAND
class bot-command (entity)
Readers
reader get-command (bot-command) (:command)
reader get-rest-text (bot-command) (:rest-text)
Generics
generic-function on-command bot command rest-text
This method will be called for each command. First argument is a keyword. If user input was /save_note, then first argument will be :save-note.
By default, logs call and does nothing.
CL-TELEGRAM-BOT/ENTITIES/CORE
package cl-telegram-bot/entities/core
Generics
generic-function make-entity-internal entity-type payload data
Extendable protocol to support entities of different kinds. First argument is a keyword, denoting a type of the entity. Payload is an object of type `message'. And data is a plist with data, describing the entity.
Functions
function make-entity payload data
CL-TELEGRAM-BOT/INLINE-KEYBOARD
package cl-telegram-bot/inline-keyboard
Classes
CALLBACK-BUTTON
class callback-button (inline-keyboard-button)
Readers
reader callback-button-data (callback-button) (:data)
INLINE-KEYBOARD-BUTTON
class inline-keyboard-button ()
Base class for all inline keyboard buttons.
API: https://core.telegram.org/bots/api#inlinekeyboardbutton
Readers
reader button-text (inline-keyboard-button) (:text)
INLINE-KEYBOARD
class inline-keyboard ()
Represents an inline keyboard as specified in API https://core.telegram.org/bots/api#inlinekeyboardmarkup.
Readers
reader keyboard-rows (inline-keyboard) (:rows = nil)
URL-BUTTON
class url-button (inline-keyboard-button)
Readers
reader button-url (url-button) (:data)
Functions
function answer-callback-query bot callback &key text show-alert url
https://core.telegram.org/bots/api#answercallbackquery
function callback-button text data
Creates a button which will call a callback.
function inline-keyboard rows
Returns an inline keyboard which can be passed
to cl-telegram-bot/response:reply (1 2) as REPLY-MARKUP argument.
Each row should be a list of inline-keyboard-button objects or a single
object of this class. In latter case, such row will have only one button.
function url-button text url
Creates a button which will open an url.
CL-TELEGRAM-BOT/MARKUP
package cl-telegram-bot/markup
Generics
generic-function to-markup obj
Transforms object into markup of Telegram API.
Methods of this class should return a hash-table, representing OBJ
in terms of Telegram API.
CL-TELEGRAM-BOT/MESSAGE
package cl-telegram-bot/message
Classes
ANIMATION-MESSAGE
class animation-message (file-message)
ANIMATION
class animation (file temporal spatial)
AUDIO-MESSAGE
class audio-message (file-message)
AUDIO
class audio (file temporal)
Readers
reader get-performer (audio) (:performer)
Performer of the audio as defined by sender or by audio tags.
reader get-title (audio) (:title)
Title of the audio as defined by sender or by audio tags.
DOCUMENT-MESSAGE
class document-message (file-message)
DOCUMENT
class document (file)
FILE-MESSAGE
class file-message (message)
Readers
reader get-file (file-message) (:file)
FILE
class file ()
Readers
reader get-file-id (file) (:file-id)
Identifier for this file, which can be used to download or reuse the file.
reader get-file-name (file) (:file-name)
Original filename as defined by sender.
reader get-file-size (file) (:file-size)
File size in bytes.
reader get-file-unique-id (file) (:file-unique-id)
Unique identifier for this file, which is supposed to be the same over time and for different bots. Can't be used to download or reuse the file.
reader get-mime-type (file) (:mime-type)
MIME type of the file as defined by sender.
MESSAGE
class message ()
Readers
reader get-caption (message) (:caption)
Caption for the animation, audio, document, photo, video or voice.
reader get-chat (message) (:chat)
reader get-entities (message) (:entities = nil)
reader get-forward-from (message) (:forward-from)
For forwarded messages, sender of the original message.
reader get-forward-from-chat (message) (:forward-from-chat)
For messages forwarded from channels or from anonymous administrators, information about the original sender chat.
reader get-forward-sender-name (message) (:forward-sender-name)
For forwarded messages, sender of the original message.
reader get-message-id (message) (:id)
reader get-raw-data (message) (:raw-data)
reader get-text (message) (:text)
PHOTO-MESSAGE
class photo-message (file-message)
Readers
reader get-photo-options (photo-message) (:photo-options)
PHOTO
class photo (file spatial)
REPLY
class reply (message)
Readers
reader get-reply-to-message (reply) (:reply-to-message)
SPATIAL
class spatial ()
Readers
reader get-height (spatial) (:height)
File height as defined by sender.
reader get-width (spatial) (:width)
File width as defined by sender.
STICKER-MESSAGE
class sticker-message (file-message)
STICKER
class sticker (file spatial)
Readers
reader get-emoji (sticker) (:emoji)
Emoji associated with the sticker
reader get-is-animated (sticker) (:is-animated)
True if the sticker is animated.
reader get-is-video (sticker) (:is-video)
True if the sticker is a video sticker.
reader get-set-name (sticker) (:set-name)
Name of the sticker set to which the sticker belongs.
TEMPORAL
class temporal ()
Readers
reader get-duration (temporal) (:duration)
Duration of the file in seconds as defined by sender.
UNISPATIAL
class unispatial ()
Readers
reader get-length (unispatial) (:length)
VIDEO-MESSAGE
class video-message (file-message)
VIDEO-NOTE-MESSAGE
class video-note-message (file-message)
VIDEO-NOTE
class video-note (file temporal unispatial)
VIDEO
class video (file temporal spatial)
VOICE-MESSAGE
class voice-message (file-message)
VOICE
class voice (file temporal)
Generics
generic-function on-message bot text
This method gets called with raw text from the message. By default it does nothing.
generic-function send-animation bot chat animation &rest options &key caption parse-mode caption-entities duration width height thumb disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
Sends animation to a chat.
generic-function send-audio bot chat audio &rest options &key caption parse-mode caption-entities duration performer title thumb disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
generic-function send-document bot chat document &rest options &key caption parse-mode caption-entities disable-content-type-detection thumb disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
generic-function send-photo bot chat photo &rest options &key caption parse-mode caption-entities disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
generic-function send-sticker bot chat sticker &rest options &key disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
A function to send sticker.
generic-function send-video bot chat video &rest options &key caption parse-mode caption-entities duration width height thumb disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
generic-function send-video-note bot chat video-note &rest options &key caption parse-mode caption-entities duration length thumb disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
generic-function send-voice bot chat voice &rest options &key caption parse-mode caption-entities duration disable-notification protect-content reply-to-message-id allow-sending-without-reply reply-markup
Functions
function delete-message bot chat message
https://core.telegram.org/bots/api#deletemessage
function forward-message bot chat from-chat message &key disable-notification
https://core.telegram.org/bots/api#forwardmessage
function get-current-chat
Returns a chat where currently processing message was received.
function get-current-message
Returns currently processed message.
function make-message data
function send-message bot chat text &rest options &key parse-mode disable-web-page-preview disable-notification reply-to-message-id reply-markup
https://core.telegram.org/bots/api#sendmessage
CL-TELEGRAM-BOT/NETWORK
package cl-telegram-bot/network
Classes
REQUEST-ERROR
condition request-error (error)
Readers
reader what (request-error) (:what)
Functions
function make-request bot name &rest options &key (streamp nil) (timeout 3) &allow-other-keys
Perform HTTP request to 'name API method with 'options JSON-encoded object.
function set-proxy proxy
CL-TELEGRAM-BOT/PIPELINE
package cl-telegram-bot/pipeline
Generics
generic-function process bot object
This method is called by when processing a single update. It is called multiple times on different parts of an update. Whole pipeline looks like that:
For each update we call: process(update) process(update.payload) For each entity in payload: process(entity)
CL-TELEGRAM-BOT/RESPONSE
package cl-telegram-bot/response
Classes
ALERT
class alert (response-with-text)
NOTIFY
class notify (response-with-text)
OPEN-URL
class open-url (response)
Readers
reader url-to-open (open-url) (:text)
REPLY
class reply (response-with-text)
RESPONSE-WITH-TEXT
class response-with-text (response)
Readers
reader response-text (response-with-text) (:text)
RESPONSE
class response ()
Readers
reader rest-args (response) (:args)
Functions
function alert text
Works like a send-message, but only when an incoming message is processed.
Automatically sends reply to a chat from where current message came from.
function notify text
Works like a send-message, but only when an incoming message is processed.
Automatically sends reply to a chat from where current message came from.
function open-url url
Works like a send-message, but only when an incoming message is processed.
Automatically sends reply to a chat from where current message came from.
function reply text &rest args &key parse-mode disable-web-page-preview disable-notification reply-to-message-id reply-markup (immediately t)
Works like a send-message, but only when an incoming message is processed.
Automatically sends reply to a chat from where current message came from.
CL-TELEGRAM-BOT/RESPONSE-PROCESSING
package cl-telegram-bot/response-processing
Classes
INTERRUPT-PROCESSING
condition interrupt-processing ()
Generics
generic-function process-response bot message response
Processes immediate responses of different types.
Functions
function interrupt-processing
CL-TELEGRAM-BOT/UPDATE
package cl-telegram-bot/update
Classes
UPDATE
class update ()
Readers
reader get-payload (update) (:payload)
reader get-raw-data (update) (:raw-data)
reader get-update-id (update) (:id)
Generics
generic-function process-updates bot
By default, this method starts an infinite loop and fetching new updates using long polling.
Functions
function make-update data
CL-TELEGRAM-BOT/UTILS
package cl-telegram-bot/utils
Functions
function make-keyword text
function obfuscate url
Credits
- Rei – initial version.
- Alexander Artemenko – large refactoring, usage of
CLOSclasses, etc.