amanobot reference¶
Amanobot has two versions:
- Traditional version uses urllib3 to make HTTP requests, and uses threads to achieve delegation by default.
- Async version is based on asyncio, uses aiohttp to make asynchronous HTTP requests, and uses asyncio tasks to achieve delegation.
This page focuses on traditional version. Async version is very similar, the most significant differences being:
- Blocking methods (mostly network operations) become coroutines, and should be
called with
await
. - Delegation is achieved by tasks, instead of threads. Thread-safety ceases to be a concern.
Traditional modules are under the package amanobot
, while async modules are
under amanobot.aio
:
Traditional | Async |
---|---|
amanobot | amanobot.aio |
amanobot.loop | amanobot.aio.loop |
amanobot.delegate | amanobot.aio.delegate |
amanobot.helper | amanobot.aio.helper |
amanobot.routing | amanobot.aio.routing |
amanobot.api | amanobot.aio.api |
Some modules do not have async counterparts, e.g. amanobot.namedtuple
and
amanobot.exception
, because they are shared.
Try to combine this reading with the provided examples . One example is worth a thousand words. I hope they make things clear.
Basic Bot¶
The Bot
class is mostly a wrapper around Telegram Bot API.
Many methods are straight mappings to Bot API methods. Where appropriate,
I only give links below. No point to duplicate all the details.
-
class
amanobot.
Bot
(token: str, raise_errors: bool = True, api_endpoint: str = 'https://api.telegram.org')[source]¶ -
class
Scheduler
[source]¶ -
class
Event
(timestamp, data)¶ Create new instance of Event(timestamp, data)
-
data
¶ Alias for field number 1
-
timestamp
¶ Alias for field number 0
-
-
event_at
(when, data)[source]¶ Schedule some data to emit at an absolute timestamp.
Returns: an internal Event object
-
event_later
(delay, data)[source]¶ Schedule some data to emit after a number of seconds.
Returns: an internal Event object
-
run
()[source]¶ Method representing the thread’s activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
-
class
-
sendMessage
(chat_id: Union[int, str], text: str, parse_mode: str = None, entities=None, disable_web_page_preview: bool = None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
forwardMessage
(chat_id: Union[int, str], from_chat_id: Union[int, str], message_id: int, disable_notification: bool = None)[source]¶
-
copyMessage
(chat_id: Union[int, str], from_chat_id: Union[int, str], message_id: int, caption: str = None, parse_mode: str = None, caption_entities=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
sendPhoto
(chat_id: Union[int, str], photo, caption: str = None, parse_mode: str = None, caption_entities=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendphoto
Parameters: photo – - string:
file_id
for a photo existing on Telegram servers - string: HTTP URL of a photo from the Internet
- file-like object: obtained by
open(path, 'rb')
- tuple: (filename, file-like object).
- string:
-
sendAudio
(chat_id: Union[int, str], audio, caption: str = None, parse_mode: str = None, caption_entities=None, duration=None, performer=None, title=None, thumb=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendaudio
Parameters: audio – Same as photo
inamanobot.Bot.sendPhoto()
-
sendDocument
(chat_id: Union[int, str], document, thumb=None, caption: str = None, parse_mode: str = None, caption_entities=None, disable_content_type_detection=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#senddocument
Parameters: document – Same as photo
inamanobot.Bot.sendPhoto()
-
sendVideo
(chat_id: Union[int, str], video, duration=None, width=None, height=None, thumb=None, caption: str = None, parse_mode: str = None, caption_entities=None, supports_streaming=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendvideo
Parameters: video – Same as photo
inamanobot.Bot.sendPhoto()
-
sendAnimation
(chat_id: Union[int, str], animation, duration=None, width=None, height=None, thumb=None, caption: str = None, parse_mode: str = None, caption_entities=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendanimation
Parameters: animation – Same as photo
inamanobot.Bot.sendPhoto()
-
sendVoice
(chat_id: Union[int, str], voice, caption: str = None, parse_mode: str = None, caption_entities=None, duration=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendvoice
Parameters: voice – Same as photo
inamanobot.Bot.sendPhoto()
-
sendVideoNote
(chat_id: Union[int, str], video_note, duration=None, length=None, thumb=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendvideonote
Parameters: - video_note – Same as
photo
inamanobot.Bot.sendPhoto()
- length – Although marked as optional, this method does not seem to work without it being specified. Supply any integer you want. It seems to have no effect on the video note’s display size.
- video_note – Same as
-
sendMediaGroup
(chat_id: Union[int, str], media, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None)[source]¶ See: https://core.telegram.org/bots/api#sendmediagroup
Parameters: media (array of InputMedia objects) – To indicate media locations, each InputMedia object’s
media
field should be one of these:- string:
file_id
for a file existing on Telegram servers - string: HTTP URL of a file from the Internet
- file-like object: obtained by
open(path, 'rb')
- tuple: (form-data name, file-like object)
- tuple: (form-data name, (filename, file-like object))
In case of uploading, you may supply customized multipart/form-data names for each uploaded file (as in last 2 options above). Otherwise, amanobot assigns unique names to each uploaded file. Names assigned by amanobot will not collide with user-supplied names, if any.
- string:
-
sendLocation
(chat_id: Union[int, str], latitude, longitude, horizontal_accuracy=None, live_period=None, heading=None, proximity_alert_radius=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
editMessageLiveLocation
(msg_identifier, latitude, longitude, horizontal_accuracy=None, heading=None, proximity_alert_radius=None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#editmessagelivelocation
Parameters: msg_identifier – Same as in Bot.editMessageText()
-
stopMessageLiveLocation
(msg_identifier, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#stopmessagelivelocation
Parameters: msg_identifier – Same as in Bot.editMessageText()
-
sendVenue
(chat_id: Union[int, str], latitude, longitude, title, address, foursquare_id=None, foursquare_type=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
sendContact
(chat_id: Union[int, str], phone_number, first_name, last_name=None, vcard=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
sendPoll
(chat_id: Union[int, str], question, options, is_anonymous=None, type=None, allows_multiple_answers=None, correct_option_id=None, explanation=None, explanation_parse_mode: str = None, open_period=None, is_closed=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
sendDice
(chat_id: Union[int, str], emoji=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
sendGame
(chat_id: Union[int, str], game_short_name, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
sendInvoice
(chat_id: Union[int, str], title, description, payload, provider_token, start_parameter, currency, prices, provider_data=None, photo_url=None, photo_size=None, photo_width=None, photo_height=None, need_name=None, need_phone_number=None, need_email=None, need_shipping_address=None, is_flexible=None, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶
-
getUserProfilePhotos
(user_id, offset=None, limit=None)[source]¶ See: https://core.telegram.org/bots/api#getuserprofilephotos
-
kickChatMember
(chat_id: Union[int, str], user_id, until_date: int = None, revoke_messages: bool = None)[source]¶
-
restrictChatMember
(chat_id: Union[int, str], user_id, until_date=None, can_send_messages=None, can_send_media_messages=None, can_send_polls=None, can_send_other_messages=None, can_add_web_page_previews=None, can_change_info=None, can_invite_users=None, can_pin_messages=None, permissions=None)[source]¶
-
promoteChatMember
(chat_id: Union[int, str], user_id, is_anonymous=None, can_manage_chat=None, can_post_messages=None, can_edit_messages=None, can_delete_messages=None, can_manage_voice_chats=None, can_restrict_members=None, can_promote_members=None, can_change_info=None, can_invite_users=None, can_pin_messages=None)[source]¶
-
setChatAdministratorCustomTitle
(chat_id: Union[int, str], user_id, custom_title)[source]¶ See: https://core.telegram.org/bots/api#setchatadministratorcustomtitle
-
setChatPermissions
(chat_id: Union[int, str], can_send_messages=None, can_send_media_messages=None, can_send_polls=None, can_send_other_messages=None, can_add_web_page_previews=None, can_change_info=None, can_invite_users=None, can_pin_messages=None, permissions=None)[source]¶
-
exportChatInviteLink
(chat_id)[source]¶ See: https://core.telegram.org/bots/api#exportchatinvitelink
-
createChatInviteLink
(chat_id, expire_date: int = None, member_limit: int = None)[source]¶ See: https://core.telegram.org/bots/api#createchatinvitelink
-
editChatInviteLink
(chat_id, invite_link: str, expire_date: int = None, member_limit: int = None)[source]¶
-
revokeChatInviteLink
(chat_id, invite_link: str)[source]¶ See: https://core.telegram.org/bots/api#revokechatinvitelink
-
pinChatMessage
(chat_id: Union[int, str], message_id: int, disable_notification: bool = None)[source]¶
-
unpinAllChatMessages
(chat_id)[source]¶ See: https://core.telegram.org/bots/api#unpinallchatmessages
-
getChatAdministrators
(chat_id)[source]¶ See: https://core.telegram.org/bots/api#getchatadministrators
-
deleteChatStickerSet
(chat_id)[source]¶ See: https://core.telegram.org/bots/api#deletechatstickerset
-
answerCallbackQuery
(callback_query_id, text=None, show_alert=None, url=None, cache_time=None)[source]¶
-
setPassportDataErrors
(user_id, errors)[source]¶ See: https://core.telegram.org/bots/api#setpassportdataerrors
-
answerPreCheckoutQuery
(pre_checkout_query_id, ok, error_message=None)[source]¶ See: https://core.telegram.org/bots/api#answerprecheckoutquery
-
editMessageText
(msg_identifier, text: str, parse_mode: str = None, entities=None, disable_web_page_preview: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#editmessagetext
Parameters: msg_identifier – a 2-tuple ( chat_id
,message_id
), a 1-tuple (inline_message_id
), or simplyinline_message_id
. You may extract this value easily withamanobot.message_identifier()
-
editMessageCaption
(msg_identifier, caption: str = None, parse_mode: str = None, caption_entities=None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#editmessagecaption
Parameters: msg_identifier – Same as msg_identifier
inamanobot.Bot.editMessageText()
-
editMessageMedia
(msg_identifier, media, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#editmessagemedia
Parameters: msg_identifier – Same as msg_identifier
inamanobot.Bot.editMessageText()
-
editMessageReplyMarkup
(msg_identifier, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#editmessagereplymarkup
Parameters: msg_identifier – Same as msg_identifier
inamanobot.Bot.editMessageText()
-
stopPoll
(msg_identifier, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#stoppoll
Parameters: msg_identifier – a 2-tuple ( chat_id
,message_id
). You may extract this value easily withamanobot.message_identifier()
-
deleteMessage
(msg_identifier)[source]¶ See: https://core.telegram.org/bots/api#deletemessage
Parameters: msg_identifier – Same as msg_identifier
inamanobot.Bot.editMessageText()
, except this method does not work on inline messages.
-
sendSticker
(chat_id: Union[int, str], sticker, disable_notification: bool = None, reply_to_message_id: int = None, allow_sending_without_reply: bool = None, reply_markup=None)[source]¶ See: https://core.telegram.org/bots/api#sendsticker
Parameters: sticker – Same as photo
inamanobot.Bot.sendPhoto()
-
createNewStickerSet
(user_id, name, title, emojis, png_sticker=None, tgs_sticker=None, contains_masks=None, mask_position=None)[source]¶
-
addStickerToSet
(user_id, name, emojis, png_sticker=None, tgs_sticker=None, mask_position=None)[source]¶
-
setStickerPositionInSet
(sticker, position)[source]¶ See: https://core.telegram.org/bots/api#setstickerpositioninset
-
deleteStickerFromSet
(sticker)[source]¶ See: https://core.telegram.org/bots/api#deletestickerfromset
-
answerInlineQuery
(inline_query_id, results, cache_time=None, is_personal=None, next_offset=None, switch_pm_text=None, switch_pm_parameter=None)[source]¶
-
getUpdates
(offset=None, limit=None, timeout=None, allowed_updates=None, _raise_errors=None)[source]¶
-
setWebhook
(url=None, certificate=None, ip_address=None, max_connections=None, allowed_updates=None, drop_pending_updates=None)[source]¶
-
setGameScore
(user_id, score, game_message_identifier, force=None, disable_edit_message=None)[source]¶ See: https://core.telegram.org/bots/api#setgamescore
Parameters: game_message_identifier – Same as msg_identifier
inamanobot.Bot.editMessageText()
-
getGameHighScores
(user_id, game_message_identifier)[source]¶ See: https://core.telegram.org/bots/api#getgamehighscores
Parameters: game_message_identifier – Same as msg_identifier
inamanobot.Bot.editMessageText()
-
download_file
(file_id, dest)[source]¶ Download a file to local disk.
Parameters: dest – a path or a file
object
-
message_loop
(callback=None, relax=0.1, timeout=20, allowed_updates=None, source=None, ordered=True, maxhold=3, run_forever=False)[source]¶ Deprecated: will be removed in future. Use MessageLoop
instead.Spawn a thread to constantly
getUpdates
or pull updates from a queue. Applycallback
to every message received. Also starts the scheduler thread for internal events.Parameters: callback – a function that takes one argument (the message), or a routing table. If None
, the bot’shandle
method is used.A routing table is a dictionary of
{flavor: function}
, mapping messages to appropriate handler functions according to their flavors. It allows you to define functions specifically to handle one flavor of messages. It usually looks like this:{'chat': fn1, 'callback_query': fn2, 'inline_query': fn3, ...}
. Each handler function should take one argument (the message).Parameters: source – Source of updates. If None
,getUpdates
is used to obtain new messages from Telegram servers. If it is a synchronized queue, new messages are pulled from the queue. A web application implementing a webhook can dump updates into the queue, while the bot pulls from it. This is how amanobot can be integrated with webhooks.Acceptable contents in queue:
str
orbytes
(decoded using UTF-8) representing a JSON-serialized Update object.- a
dict
representing an Update object.
When
source
isNone
, these parameters are meaningful:Parameters: - relax (float) – seconds between each
getUpdates
- timeout (int) –
timeout
parameter supplied toamanobot.Bot.getUpdates()
, controlling how long to poll. - allowed_updates (array of string) –
allowed_updates
parameter supplied toamanobot.Bot.getUpdates()
, controlling which types of updates to receive.
When
source
is a queue, these parameters are meaningful:Parameters: - ordered (bool) – If
True
, ensure in-order delivery of messages tocallback
(i.e. updates with a smallerupdate_id
always come before those with a largerupdate_id
). IfFalse
, no re-ordering is done.callback
is applied to messages as soon as they are pulled from queue. - maxhold (float) – Applied only when
ordered
isTrue
. The maximum number of seconds an update is held waiting for a not-yet-arrived smallerupdate_id
. When this number of seconds is up, the update is delivered tocallback
even if some smallerupdate_id
s have not yet arrived. If those smallerupdate_id
s arrive at some later time, they are discarded.
Finally, there is this parameter, meaningful always:
Parameters: run_forever (bool or str) – If True
or any non-empty string, append an infinite loop at the end of this method, so it never returns. Useful as the very last line in a program. A non-empty string will also be printed, useful as an indication that the program is listening.
-
class
Message Loop and Webhook¶
There are two ways to obtain updates from Telegram Bot API: make calls to
Bot.getUpdates()
continuously, or use webhook.
In the former case, it is troublesome to have to program that manually.
So MessageLoop
is here to ease your burden. In the latter case,
although the programming overhead is mainly on the web server, a structured way
to funnel web requests into amanobot is desirable. The result is Webhook
and OrderedWebhook
.
The idea is similar. You supply a message-handling function to the object
constructor, then use run_as_thread()
to get it going. A MessageLoop
makes calls to getUpdates()
continuously, and apply the message-handling
function to every message received. A Webhook
or OrderedWebhook
would not do anything by itself; you have to feed()
it the new update
every time the web server receives one.
In place of the message-handling function, you can supply one of the following:
- a function that takes one argument (the message)
- if
None
, the bot’shandle
method is used - a routing table
A routing table is a dictionary of {flavor: function}
, mapping messages to
appropriate handler functions according to their flavors. It allows you to
define functions specifically to handle one flavor of messages. It usually looks
like this: {'chat': fn1, 'callback_query': fn2, 'inline_query': fn3, ...}
.
Each handler function should take one argument (the message).
-
class
amanobot.loop.
MessageLoop
(bot, handle=None)[source]¶ -
run_forever
(*args, **kwargs)[source]¶ Parameters: - relax (float) – seconds between each
getUpdates()
- offset (int) – initial
offset
parameter supplied togetUpdates()
- timeout (int) –
timeout
parameter supplied togetUpdates()
, controlling how long to poll. - allowed_updates (array of string) –
allowed_updates
parameter supplied togetUpdates()
, controlling which types of updates to receive.
Calling this method will block forever. Use
run_as_thread()
to run it non-blockingly.- relax (float) – seconds between each
-
run_as_thread
(*args, **kwargs)¶
-
In practice, you should always use OrderedWebhook
rather than Webhook
.
Updates are individual HTTP requests, and there is no guarantee of their arrival
order. OrderedWebhook
puts them in order (according to update_id
)
before applying the message-handling function. In contrast, Webhook
applies the message-handling function in the order you feed them. Unless you
want to implement your own ordering logic, Webhook
should not be used.
In async version, a task of run_forever()
should be created instead of
run_as_thread()
.
Refer to webhook examples for usage.
-
class
amanobot.loop.
OrderedWebhook
(bot, handle=None)[source]¶ -
run_forever
(*args, **kwargs)[source]¶ Parameters: maxhold (float) – The maximum number of seconds an update is held waiting for a not-yet-arrived smaller update_id
. When this number of seconds is up, the update is delivered to the message-handling function even if some smallerupdate_id
s have not yet arrived. If those smallerupdate_id
s arrive at some later time, they are discarded.Calling this method will block forever. Use
run_as_thread()
to run it non-blockingly.
-
feed
(data)[source]¶ Parameters: data – One of these:
str
orbytes
(decoded using UTF-8) representing a JSON-serialized Update object.- a
dict
representing an Update object.
-
run_as_thread
(*args, **kwargs)¶
-
Functions¶
-
amanobot.
flavor
(msg)[source]¶ Return flavor of message or event.
A message’s flavor may be one of these:
chat
callback_query
inline_query
chosen_inline_result
shipping_query
pre_checkout_query
An event’s flavor is determined by the single top-level key.
-
amanobot.
glance
(msg, flavor='chat', long=False)[source]¶ Extract “headline” info about a message. Use parameter
long
to control whether a short or long tuple is returned.When
flavor
ischat
(msg
being a Message object):- short: (content_type,
msg['chat']['type']
,msg['chat']['id']
) - long: (content_type,
msg['chat']['type']
,msg['chat']['id']
,msg['date']
,msg['message_id']
)
content_type can be:
text
,audio
,document
,game
,photo
,sticker
,video
,voice
,video_note
,contact
,location
,venue
,new_chat_member
,left_chat_member
,new_chat_title
,new_chat_photo
,delete_chat_photo
,group_chat_created
,supergroup_chat_created
,channel_chat_created
,migrate_to_chat_id
,migrate_from_chat_id
,pinned_message
,new_chat_members
,invoice
,successful_payment
.When
flavor
iscallback_query
(msg
being a CallbackQuery object):- regardless: (
msg['id']
,msg['from']['id']
,msg['data']
)
When
flavor
isinline_query
(msg
being a InlineQuery object):- short: (
msg['id']
,msg['from']['id']
,msg['query']
) - long: (
msg['id']
,msg['from']['id']
,msg['query']
,msg['offset']
)
When
flavor
ischosen_inline_result
(msg
being a ChosenInlineResult object):- regardless: (
msg['result_id']
,msg['from']['id']
,msg['query']
)
When
flavor
isshipping_query
(msg
being a ShippingQuery object):- regardless: (
msg['id']
,msg['from']['id']
,msg['invoice_payload']
)
When
flavor
ispre_checkout_query
(msg
being a PreCheckoutQuery object):- short: (
msg['id']
,msg['from']['id']
,msg['invoice_payload']
) - long: (
msg['id']
,msg['from']['id']
,msg['invoice_payload']
,msg['currency']
,msg['total_amount']
)
- short: (content_type,
-
amanobot.
flance
(msg, long=False)[source]¶ A combination of
amanobot.flavor()
andamanobot.glance()
, return a 2-tuple (flavor, headline_info), where headline_info is whatever extracted byamanobot.glance()
depending on the message flavor and thelong
parameter.
-
amanobot.
peel
(event)[source]¶ Remove an event’s top-level skin (where its flavor is determined), and return the core content.
-
amanobot.
fleece
(event)[source]¶ A combination of
amanobot.flavor()
andamanobot.peel()
, return a 2-tuple (flavor, content) of an event.
-
amanobot.
is_event
(msg)[source]¶ Return whether the message looks like an event. That is, whether it has a flavor that starts with an underscore.
-
amanobot.
message_identifier
(msg)[source]¶ Extract an identifier for message editing. Useful with
amanobot.Bot.editMessageText()
and similar methods. Returned value is guaranteed to be a tuple.msg
is expected to bechat
orchoson_inline_result
.
DelegatorBot¶
-
class
amanobot.
DelegatorBot
(token, delegation_patterns)[source]¶ Parameters: delegation_patterns – a list of (seeder, delegator) tuples.
A seeder is a function that:
takes one argument - a message
- returns a seed. Depending on the nature of the seed, behavior is as follows:
if the seed is a hashable (e.g. number, string, tuple), it looks for a delegate associated with the seed. (Think of a dictionary of
{seed: delegate}
)- if such a delegate exists and is alive, it is assumed that the message will be picked up by the delegate. Nothing more is done.
- if no delegate exists or that delegate is no longer alive, a new delegate is obtained by calling the delegator function. The new delegate is associated with the seed.
- In essence, when the seed is a hashable, only one delegate is running for a given seed.
if the seed is a non-hashable, (e.g. list), a new delegate is always obtained by calling the delegator function. No seed-delegate association occurs.
if the seed is
None
, nothing is done.
A delegator is a function that:
- takes one argument - a (bot, message, seed) tuple. This is called a seed tuple.
- returns a delegate, which can be one of the following:
- an object that has methods
start()
andis_alive()
. Therefore, athreading.Thread
object is a natural delegate. Once returned, the object’sstart()
method is called. - a function. Once returned, it is wrapped in a
Thread(target=function)
and started. - a (function, args, kwargs) tuple. Once returned, it is wrapped in a
Thread(target=function, args=args, kwargs=kwargs)
and started.
- an object that has methods
The above logic is implemented in the handle
method.
You only have to create a MessageLoop
with no callback
argument, the above logic will be executed for every message received.
In the list of delegation patterns, all seeder functions are evaluated in order. One message may start multiple delegates.
The module amanobot.delegate
has a bunch of seeder factories
and delegator factories, which greatly ease the use of DelegatorBot. The module
amanobot.helper
also has a number of *Handler
classes which provide
a connection-like interface to deal with individual chats or users.
I have given an answer on Stack Overflow which elaborates on the inner workings of DelegatorBot in greater details. Interested readers are encouraged to read that.
In the rest of discussions, seed tuple means a (bot, message, seed) tuple, referring to the single argument taken by delegator functions.
amanobot.delegate
¶
-
amanobot.delegate.
per_chat_id
(types='all')[source]¶ Parameters: types – all
or a list of chat types (private
,group
,channel
)Returns: a seeder function that returns the chat id only if the chat type is in types
.
-
amanobot.delegate.
per_chat_id_in
(s, types='all')[source]¶ Parameters: - s – a list or set of chat id
- types –
all
or a list of chat types (private
,group
,channel
)
Returns: a seeder function that returns the chat id only if the chat id is in
s
and chat type is intypes
.
-
amanobot.delegate.
per_chat_id_except
(s, types='all')[source]¶ Parameters: - s – a list or set of chat id
- types –
all
or a list of chat types (private
,group
,channel
)
Returns: a seeder function that returns the chat id only if the chat id is not in
s
and chat type is intypes
.
-
amanobot.delegate.
per_from_id
(flavors=None)[source]¶ Parameters: flavors – all
or a list of flavorsReturns: a seeder function that returns the from id only if the message flavor is in flavors
.
-
amanobot.delegate.
per_from_id_in
(s, flavors=None)[source]¶ Parameters: - s – a list or set of from id
- flavors –
all
or a list of flavors
Returns: a seeder function that returns the from id only if the from id is in
s
and message flavor is inflavors
.
-
amanobot.delegate.
per_from_id_except
(s, flavors=None)[source]¶ Parameters: - s – a list or set of from id
- flavors –
all
or a list of flavors
Returns: a seeder function that returns the from id only if the from id is not in
s
and message flavor is inflavors
.
-
amanobot.delegate.
per_inline_from_id
()[source]¶ Returns: a seeder function that returns the from id only if the message flavor is inline_query
orchosen_inline_result
-
amanobot.delegate.
per_inline_from_id_in
(s)[source]¶ Parameters: s – a list or set of from id Returns: a seeder function that returns the from id only if the message flavor is inline_query
orchosen_inline_result
and the from id is ins
.
-
amanobot.delegate.
per_inline_from_id_except
(s)[source]¶ Parameters: s – a list or set of from id Returns: a seeder function that returns the from id only if the message flavor is inline_query
orchosen_inline_result
and the from id is not ins
.
-
amanobot.delegate.
per_application
()[source]¶ Returns: a seeder function that always returns 1, ensuring at most one delegate is ever spawned for the entire application.
-
amanobot.delegate.
per_message
(flavors='all')[source]¶ Parameters: flavors – all
or a list of flavorsReturns: a seeder function that returns a non-hashable only if the message flavor is in flavors
.
-
amanobot.delegate.
per_event_source_id
(event_space)[source]¶ Returns: a seeder function that returns an event’s source id only if that event’s source space equals to event_space
.
-
amanobot.delegate.
per_callback_query_chat_id
(types='all')[source]¶ Parameters: types – all
or a list of chat types (private
,group
,channel
)Returns: a seeder function that returns a callback query’s originating chat id if the chat type is in types
.
-
amanobot.delegate.
per_callback_query_origin
(origins='all')[source]¶ Parameters: origins – all
or a list of origin types (chat
,inline
)Returns: a seeder function that returns a callback query’s origin identifier if that origin type is in origins
. The origin identifier is guaranteed to be a tuple.
-
amanobot.delegate.
per_invoice_payload
()[source]¶ Returns: a seeder function that returns the invoice payload.
-
amanobot.delegate.
call
(func, *args, **kwargs)[source]¶ Returns: a delegator function that returns a tuple ( func
, (seed tuple,)+args
,kwargs
). That is, seed tuple is inserted before supplied positional arguments. By default, a thread wrappingfunc
and all those arguments is spawned.
-
amanobot.delegate.
create_run
(cls, *args, **kwargs)[source]¶ Returns: a delegator function that calls the cls
constructor whose arguments being a seed tuple followed by supplied*args
and**kwargs
, then returns the object’srun
method. By default, a thread wrapping thatrun
method is spawned.
-
amanobot.delegate.
create_open
(cls, *args, **kwargs)[source]¶ Returns: a delegator function that calls the cls
constructor whose arguments being a seed tuple followed by supplied*args
and**kwargs
, then returns a looping function that uses the object’slistener
to wait for messages and invokes instance methodopen
,on_message
, andon_close
accordingly. By default, a thread wrapping that looping function is spawned.
-
amanobot.delegate.
until
(condition, fns)[source]¶ Try a list of seeder functions until a condition is met.
Parameters: - condition – a function that takes one argument - a seed - and returns
True
orFalse
- fns – a list of seeder functions
Returns: a “composite” seeder function that calls each supplied function in turn, and returns the first seed where the condition is met. If the condition is never met, it returns
None
.- condition – a function that takes one argument - a seed - and returns
-
amanobot.delegate.
chain
(*fns)[source]¶ Returns: a “composite” seeder function that calls each supplied function in turn, and returns the first seed that is not None
.
-
amanobot.delegate.
pair
(seeders, delegator_factory, *args, **kwargs)[source]¶ The basic pair producer.
Returns: a (seeder, delegator_factory(*args, **kwargs)) tuple. Parameters: seeders – If it is a seeder function or a list of one seeder function, it is returned as the final seeder. If it is a list of more than one seeder function, they are chained together before returned as the final seeder.
-
amanobot.delegate.
pave_event_space
(fn=<function pair>)[source]¶ Returns: a pair producer that ensures the seeder and delegator share the same event space.
-
amanobot.delegate.
include_callback_query_chat_id
(fn=<function pair>, types='all')[source]¶ Returns: a pair producer that enables static callback query capturing across seeder and delegator. Parameters: types – all
or a list of chat types (private
,group
,channel
)
-
amanobot.delegate.
intercept_callback_query_origin
(fn=<function pair>, origins='all')[source]¶ Returns: a pair producer that enables dynamic callback query origin mapping across seeder and delegator. Parameters: origins – all
or a list of origin types (chat
,inline
). Origin mapping is only enabled for specified origin types.
amanobot.helper
¶
Handlers¶
-
class
amanobot.helper.
Monitor
(seed_tuple, capture, **kwargs)[source]¶ Bases:
amanobot.helper.ListenerContext
,amanobot.helper.DefaultRouterMixin
A delegate that never times-out, probably doing some kind of background monitoring in the application. Most naturally paired with
per_application()
.Parameters: capture – a list of patterns for Listener
to capture
-
class
amanobot.helper.
ChatHandler
(seed_tuple, include_callback_query=False, **kwargs)[source]¶ Bases:
amanobot.helper.ChatContext
,amanobot.helper.DefaultRouterMixin
,amanobot.helper.StandardEventMixin
,amanobot.helper.IdleTerminateMixin
A delegate to handle a chat.
-
class
amanobot.helper.
UserHandler
(seed_tuple, include_callback_query=False, flavors=['chat', 'inline_query', 'chosen_inline_result'], **kwargs)[source]¶ Bases:
amanobot.helper.UserContext
,amanobot.helper.DefaultRouterMixin
,amanobot.helper.StandardEventMixin
,amanobot.helper.IdleTerminateMixin
A delegate to handle a user’s actions.
Parameters: flavors – A list of flavors to capture. all
covers all flavors.
-
class
amanobot.helper.
InlineUserHandler
(seed_tuple, **kwargs)[source]¶ Bases:
amanobot.helper.UserHandler
A delegate to handle a user’s inline-related actions.
-
class
amanobot.helper.
CallbackQueryOriginHandler
(seed_tuple, **kwargs)[source]¶ Bases:
amanobot.helper.CallbackQueryOriginContext
,amanobot.helper.DefaultRouterMixin
,amanobot.helper.StandardEventMixin
,amanobot.helper.IdleTerminateMixin
A delegate to handle callback query from one origin.
-
class
amanobot.helper.
InvoiceHandler
(seed_tuple, **kwargs)[source]¶ Bases:
amanobot.helper.InvoiceContext
,amanobot.helper.DefaultRouterMixin
,amanobot.helper.StandardEventMixin
,amanobot.helper.IdleTerminateMixin
A delegate to handle messages related to an invoice.
Contexts¶
-
class
amanobot.helper.
ChatContext
(bot, context_id, *args, **kwargs)[source]¶ Bases:
amanobot.helper.ListenerContext
-
chat_id
¶
-
administrator
¶ An
Administrator
for this chat
-
-
class
amanobot.helper.
UserContext
(bot, context_id, *args, **kwargs)[source]¶ Bases:
amanobot.helper.ListenerContext
-
user_id
¶
-
-
class
amanobot.helper.
CallbackQueryOriginContext
(bot, context_id, *args, **kwargs)[source]¶ Bases:
amanobot.helper.ListenerContext
-
origin
¶ Mesasge identifier of callback query’s origin
-
-
class
amanobot.helper.
InvoiceContext
(bot, context_id, *args, **kwargs)[source]¶ Bases:
amanobot.helper.ListenerContext
-
payload
¶
-
-
class
amanobot.helper.
Sender
(bot, chat_id)[source]¶ When you are dealing with a particular chat, it is tedious to have to supply the same
chat_id
every time to send a message, or to send anything.This object is a proxy to a bot’s
send*
andforwardMessage
methods, automatically fills in a fixed chat id for you. Available methods have identical signatures as those of the underlying bot, except there is no need to supply the aforementionedchat_id
:
-
class
amanobot.helper.
Administrator
(bot, chat_id)[source]¶ When you are dealing with a particular chat, it is tedious to have to supply the same
chat_id
every time to get a chat’s info or to perform administrative tasks.This object is a proxy to a bot’s chat administration methods, automatically fills in a fixed chat id for you. Available methods have identical signatures as those of the underlying bot, except there is no need to supply the aforementioned
chat_id
:Bot.kickChatMember()
Bot.unbanChatMember()
Bot.restrictChatMember()
Bot.promoteChatMember()
Bot.exportChatInviteLink()
Bot.setChatPhoto()
Bot.deleteChatPhoto()
Bot.setChatTitle()
Bot.setChatDescription()
Bot.pinChatMessage()
Bot.unpinChatMessage()
Bot.leaveChat()
Bot.getChat()
Bot.getChatAdministrators()
Bot.getChatMembersCount()
Bot.getChatMember()
Bot.setChatStickerSet()
Bot.deleteChatStickerSet()
-
class
amanobot.helper.
Editor
(bot, msg_identifier)[source]¶ If you want to edit a message over and over, it is tedious to have to supply the same
msg_identifier
every time.This object is a proxy to a bot’s message-editing methods, automatically fills in a fixed message identifier for you. Available methods have identical signatures as those of the underlying bot, except there is no need to supply the aforementioned
msg_identifier
:Bot.editMessageText()
Bot.editMessageCaption()
Bot.editMessageReplyMarkup()
Bot.deleteMessage()
Bot.editMessageLiveLocation()
Bot.stopMessageLiveLocation()
A message’s identifier can be easily extracted with
amanobot.message_identifier()
.Parameters: msg_identifier – a message identifier as mentioned above, or a message (whose identifier will be automatically extracted).
-
class
amanobot.helper.
Listener
(mic, q)[source]¶ -
capture
(pattern)[source]¶ Add a pattern to capture.
Parameters: pattern – a list of templates. - A template may be a function that:
- takes one argument - a message
- returns
True
to indicate a match
- A template may also be a dictionary whose:
- keys are used to select parts of message. Can be strings or
regular expressions (as obtained by
re.compile()
) - values are used to match against the selected parts. Can be typical data or a function.
- keys are used to select parts of message. Can be strings or
regular expressions (as obtained by
All templates must produce a match for a message to be considered a match.
-
Mixins¶
-
class
amanobot.helper.
Router
(key_function, routing_table)[source]¶ Map a message to a handler function, using a key function and a routing table (dictionary).
A key function digests a message down to a value. This value is treated as a key to the routing table to look up a corresponding handler function.
Parameters: - key_function –
A function that takes one argument (the message) and returns one of the following:
- a key to the routing table
- a 1-tuple (key,)
- a 2-tuple (key, (positional, arguments, …))
- a 3-tuple (key, (positional, arguments, …), {keyword: arguments, …})
Extra arguments, if returned, will be applied to the handler function after using the key to look up the routing table.
- routing_table – A dictionary of
{key: handler}
. ANone
key acts as a default catch-all. If the key being looked up does not exist in the routing table, theNone
key and its corresponding handler is used.
-
route
(msg, *aa, **kw)[source]¶ Apply key function to
msg
to obtain a key, look up routing table to obtain a handler function, then call the handler function with positional and keyword arguments, if any is returned by the key function.*aa
and**kw
are dummy placeholders for easy chaining. Regardless of any number of arguments returned by the key function, multi-level routing may be achieved like this:top_router.routing_table['key1'] = sub_router1.route top_router.routing_table['key2'] = sub_router2.route
- key_function –
-
class
amanobot.helper.
DefaultRouterMixin
(*args, **kwargs)[source]¶ Install a default
Router
and the instance methodon_message()
.-
router
¶
-
on_message
(msg)[source]¶ Call
Router.route()
to handle the message.
-
-
class
amanobot.helper.
StandardEventScheduler
(scheduler, event_space, source_id)[source]¶ A proxy to the underlying
Bot
’s scheduler, this object implements the standard event format. A standard event looks like this:{'_flavor': { 'source': { 'space': event_space, 'id': source_id} 'custom_key1': custom_value1, 'custom_key2': custom_value2, ... }}
- There is a single top-level key indicating the flavor, starting with an _underscore.
- On the second level, there is a
source
key indicating the event source. - An event source consists of an event space and a source id.
- An event space is shared by all delegates in a group. Source id simply refers to a delegate’s id. They combine to ensure a delegate is always able to capture its own events, while its own events would not be mistakenly captured by others.
Events scheduled through this object always have the second-level
source
key fixed, while the flavor and other data may be customized.-
event_space
¶
-
configure
(listener)[source]¶ Configure a
Listener
to capture events with this object’s event space and source id.
-
event_at
(when, data_tuple)[source]¶ Schedule an event to be emitted at a certain time.
Parameters: - when – an absolute timestamp
- data_tuple – a 2-tuple (flavor, data)
Returns: an event object, useful for cancelling.
-
event_later
(delay, data_tuple)[source]¶ Schedule an event to be emitted after a delay.
Parameters: - delay – number of seconds
- data_tuple – a 2-tuple (flavor, data)
Returns: an event object, useful for cancelling.
-
class
amanobot.helper.
StandardEventMixin
(event_space, *args, **kwargs)[source]¶ Install a
StandardEventScheduler
.-
scheduler
¶
-
-
class
amanobot.helper.
IdleEventCoordinator
(scheduler, timeout)[source]¶
-
class
amanobot.helper.
IdleTerminateMixin
(timeout, *args, **kwargs)[source]¶ Install an
IdleEventCoordinator
to manage idle timeout. Also define instance methodon__idle()
to handle idle timeout events.-
idle_event_coordinator
¶
-
static
on__idle
(event)[source]¶ Raise an
IdleTerminate
to close the delegate.
-
-
class
amanobot.helper.
CallbackQueryCoordinator
(id, origin_set, enable_chat, enable_inline)[source]¶ Parameters: - origin_set – Callback query whose origin belongs to this set will be captured
- enable_chat –
False
: Do not intercept chat-originated callback queryTrue
: Do intercept- Notifier function: Do intercept and call the notifier function on adding or removing an origin
- enable_inline – Same meaning as
enable_chat
, but apply to inline-originated callback query
Notifier functions should have the signature
notifier(origin, id, adding)
:- On adding an origin,
notifier(origin, my_id, True)
will be called. - On removing an origin,
notifier(origin, my_id, False)
will be called.
-
augment_send
(send_func)[source]¶ Parameters: send_func – a function that sends messages, such as Bot.send*()
Returns: a function that wraps around send_func
and examines whether the sent message contains an inline keyboard with callback data. If so, future callback query originating from the sent message will be captured.
-
augment_edit
(edit_func)[source]¶ Parameters: edit_func – a function that edits messages, such as Bot.edit*()
Returns: a function that wraps around edit_func
and examines whether the edited message contains an inline keyboard with callback data. If so, future callback query originating from the edited message will be captured. If not, such capturing will be stopped.
-
augment_delete
(delete_func)[source]¶ Parameters: delete_func – a function that deletes messages, such as Bot.deleteMessage()
Returns: a function that wraps around delete_func
and stops capturing callback query originating from that deleted message.
-
augment_on_message
(handler)[source]¶ Parameters: handler – an on_message()
handler functionReturns: a function that wraps around handler
and examines whether the incoming message is a chosen inline result with aninline_message_id
field. If so, future callback query originating from this chosen inline result will be captured.
-
augment_bot
(bot)[source]¶ Returns: a proxy to bot
with these modifications:- all
send*
methods augmented byaugment_send()
- all
edit*
methods augmented byaugment_edit()
deleteMessage()
augmented byaugment_delete()
- all other public methods, including properties, copied unchanged
- all
-
class
amanobot.helper.
InterceptCallbackQueryMixin
(intercept_callback_query, *args, **kwargs)[source]¶ Install a
CallbackQueryCoordinator
to capture callback query dynamically.Using this mixin has one consequence. The
self.bot()
property no longer returns the originalBot
object. Instead, it returns an augmented version of theBot
(augmented byCallbackQueryCoordinator
). The originalBot
can be accessed withself.__bot
(double underscore).Parameters: intercept_callback_query – a 2-tuple (enable_chat, enable_inline) to pass to CallbackQueryCoordinator
-
callback_query_coordinator
¶
-
-
class
amanobot.helper.
Answerer
(bot)[source]¶ When processing inline queries, ensure at most one active thread per user id.
-
answer
(inline_query, compute_fn, *compute_args, **compute_kwargs)[source]¶ Spawns a thread that calls
compute fn
(along with additional arguments*compute_args
and**compute_kwargs
), then applies the returned value toBot.answerInlineQuery()
to answer the inline query. If a preceding thread is already working for a user, that thread is cancelled, thus ensuring at most one active thread per user id.Parameters: - inline_query – The inline query to be processed. The originating user is inferred from
msg['from']['id']
. - compute_fn –
A thread-safe function whose returned value is given to
Bot.answerInlineQuery()
to send. May return:- a list of InlineQueryResult
- a tuple whose first element is a list of InlineQueryResult,
followed by positional arguments to be supplied to
Bot.answerInlineQuery()
- a dictionary representing keyword arguments to be supplied to
Bot.answerInlineQuery()
- *compute_args – positional arguments to
compute_fn
- **compute_kwargs – keyword arguments to
compute_fn
- inline_query – The inline query to be processed. The originating user is inferred from
-
Utilities¶
-
class
amanobot.helper.
SafeDict
(*args, **kwargs)[source]¶ A subclass of
dict
, thread-safety added:d = SafeDict() # Thread-safe operations include: d['a'] = 3 # key assignment d['a'] # key retrieval del d['a'] # key deletion
-
amanobot.helper.
openable
(cls)[source]¶ A class decorator to fill in certain methods and properties to ensure a class can be used by
create_open()
.These instance methods and property will be added, if not defined by the class:
open(self, initial_msg, seed)
on_message(self, msg)
on_close(self, ex)
close(self, ex=None)
- property
listener
amanobot.exception
¶
-
exception
amanobot.exception.
BadHTTPResponse
[source]¶ All requests to Bot API should result in a JSON response. If non-JSON, this exception is raised. While it is hard to pinpoint exactly when this might happen, the following situations have been observed to give rise to it:
- an unreasonable token, e.g.
abc
,123
, anything that does not even remotely resemble a correct token. - a bad gateway, e.g. when Telegram servers are down.
-
status
¶
-
text
¶
-
response
¶
- an unreasonable token, e.g.
-
exception
amanobot.exception.
TelegramError
[source]¶ To indicate erroneous situations, Telegram returns a JSON object containing an error code and a description. This will cause a
TelegramError
to be raised. Before raising a genericTelegramError
, amanobot looks for a more specific subclass that “matches” the error. If such a class exists, an exception of that specific subclass is raised. This allows you to either catch specific errors or to cast a wide net (by a catch-allTelegramError
). This also allows you to incorporate customTelegramError
easily.Subclasses must define a class variable
DESCRIPTION_PATTERNS
which is a list of regular expressions. If an error’s description matches any of the regular expressions, an exception of that subclass is raised.-
description
¶
-
error_code
¶
-
json
¶
-
-
exception
amanobot.exception.
TooManyRequestsError
[source]¶ -
DESCRIPTION_PATTERNS
= ['too *many *requests']¶
-
amanobot.namedtuple
¶
Amanobot’s custom is to represent Bot API object as dictionary.
On the other hand, the module amanobot.namedtuple
also provide namedtuple
classes mirroring those objects. The reasons are twofold:
- Under some situations, you may want an object with a complete set of fields,
including those whose values are
None
. A dictionary translated from Bot API’s response would have thoseNone
fields absent. By converting such a dictionary to a namedtuple, all fields are guaranteed to be present, even if their values areNone
. This usage is for incoming objects received from Telegram servers. - Namedtuple allows easier construction of objects like ReplyKeyboardMarkup, InlineKeyboardMarkup, and various InlineQueryResult, etc. This usage is for outgoing objects sent to Telegram servers.
Incoming objects include:
- User
- Chat
- Message
- MessageEntity
- PhotoSize
- Audio
- Document
- Sticker
- Video
- Voice
- VideoNote
- Contact
- Location
- Venue
- UserProfilePhotos
- File
- ChatPhoto
- ChatMember
- CallbackQuery
- InlineQuery
- ChosenInlineResult
- Invoice
- ShippingAddress
- OrderInfo
- ShippingQuery
- PreCheckoutQuery
- SuccessfulPayment
Outgoing objects include:
- ReplyKeyboardMarkup
- KeyboardButton
- ReplyKeyboardRemove
- InlineKeyboardMarkup
- InlineKeyboardButton
- ForceReply
- Various types of InlineQueryResult
- Various types of InputMessageContent
- LabeledPrice
- ShippingOption
amanobot.routing
¶
This module has a bunch of key function factories and routing table factories
to facilitate the use of Router
.
Things to remember:
- A key function takes one argument - the message, and returns a key, optionally followed by positional arguments and keyword arguments.
- A routing table is just a dictionary. After obtaining one from a factory function, you can customize it to your liking.
-
amanobot.routing.
by_content_type
()[source]¶ Returns: A key function that returns a 2-tuple (content_type, (msg[content_type],)). In plain English, it returns the message’s content type as the key, and the corresponding content as a positional argument to the handler function.
-
amanobot.routing.
by_command
(extractor, prefix=('/', ), separator=' ', pass_args=False)[source]¶ Parameters: - extractor – a function that takes one argument (the message) and returns a portion
of message to be interpreted. To extract the text of a chat message,
use
lambda msg: msg['text']
. - prefix – a list of special characters expected to indicate the head of a command.
- separator – a command may be followed by arguments separated by
separator
. - pass_args (bool) – If
True
, arguments following a command will be passed to the handler function.
Returns: a key function that interprets a specific part of a message and returns the embedded command, optionally followed by arguments. If the text is not preceded by any of the specified
prefix
, it returns a 1-tuple(None,)
as the key. This is to distinguish with the specialNone
key in routing table.- extractor – a function that takes one argument (the message) and returns a portion
of message to be interpreted. To extract the text of a chat message,
use
-
amanobot.routing.
by_chat_command
(prefix=('/', ), separator=' ', pass_args=False)[source]¶ Parameters: - prefix – a list of special characters expected to indicate the head of a command.
- separator – a command may be followed by arguments separated by
separator
. - pass_args (bool) – If
True
, arguments following a command will be passed to the handler function.
Returns: a key function that interprets a chat message’s text and returns the embedded command, optionally followed by arguments. If the text is not preceded by any of the specified
prefix
, it returns a 1-tuple(None,)
as the key. This is to distinguish with the specialNone
key in routing table.
-
amanobot.routing.
by_regex
(extractor, regex, key=1)[source]¶ Parameters: - extractor – a function that takes one argument (the message) and returns a portion
of message to be interpreted. To extract the text of a chat message,
use
lambda msg: msg['text']
. - regex (str or regex object) – the pattern to look for
- key – the part of match object to be used as key
Returns: a key function that returns
match.group(key)
as key (wherematch
is the match object) and the match object as a positional argument. If no match is found, it returns a 1-tuple(None,)
as the key. This is to distinguish with the specialNone
key in routing table.- extractor – a function that takes one argument (the message) and returns a portion
of message to be interpreted. To extract the text of a chat message,
use
-
amanobot.routing.
process_key
(processor, fn)[source]¶ Parameters: - processor – a function to process the key returned by the supplied key function
- fn – a key function
Returns: a function that wraps around the supplied key function to further process the key before returning.
-
amanobot.routing.
lower_key
(fn)[source]¶ Parameters: fn – a key function Returns: a function that wraps around the supplied key function to ensure the returned key is in lowercase.
-
amanobot.routing.
upper_key
(fn)[source]¶ Parameters: fn – a key function Returns: a function that wraps around the supplied key function to ensure the returned key is in uppercase.
-
amanobot.routing.
make_routing_table
(obj, keys, prefix='on_')[source]¶ Returns: a dictionary roughly equivalent to
{'key1': obj.on_key1, 'key2': obj.on_key2, ...}
, butobj
does not have to define all methods. It may define the needed ones only.Parameters: - obj – the object
- keys – a list of keys
- prefix – a string to be prepended to keys to make method names
-
amanobot.routing.
make_content_type_routing_table
(obj, prefix='on_')[source]¶ Returns: a dictionary covering all available content types, roughly equivalent to
{'text': obj.on_text, 'photo': obj.on_photo, ...}
, butobj
does not have to define all methods. It may define the needed ones only.Parameters: - obj – the object
- prefix – a string to be prepended to content types to make method names
amanobot.text
¶
-
amanobot.text.
apply_entities_as_markdown
(text, entities)[source]¶ Format text as Markdown. Also take care of escaping special characters. Returned value can be passed to
Bot.sendMessage()
with appropriateparse_mode
.Parameters: - text – plain text
- entities –
a list of MessageEntity objects
-
amanobot.text.
apply_entities_as_html
(text, entities)[source]¶ Format text as HTML. Also take care of escaping special characters. Returned value can be passed to
Bot.sendMessage()
with appropriateparse_mode
.Parameters: - text – plain text
- entities –
a list of MessageEntity objects