cl-telegram-bot

2024-10-12

Telegram Bot API, based on sovietspaceship's work but mostly rewritten.

Upstream URL

github.com/40ants/cl-telegram-bot

Author

Alexander Artemenko <svetlyak.40wt@gmail.com>

License

MIT
README

cl-telegram-bot - Telegram Bot API

CL-TELEGRAM-BOT ASDF System Details

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


[generated by 40ANTS-DOC]

Dependencies (20)

  • 40ants-asdf-system
  • alexandria
  • arrows
  • bordeaux-threads
  • ci
  • closer-mop
  • cl-ppcre
  • cl-str
  • cl-strings
  • dexador
  • doc
  • docs-builder
  • jonathan
  • kebab
  • log4cl
  • named-readtables
  • pythonic-string-reader
  • rove
  • serapeum
  • trivial-backtrace

Dependents (0)

    • GitHub
    • Quicklisp