trading_agent.channels.telegram_api
¶
The one place that talks to Telegram's servers, through python-telegram-bot.
The bot asks Telegram for new messages with long polling: each request waits up to poll_seconds for a message and returns as soon as one arrives. The gateway therefore needs no open port and no public address; it only makes outgoing requests, like a browser.
Everything else in the Telegram channel talks to this class, so tests can replace it with a stand-in and never reach the internet.
Typical usage example:
api = TelegramApi(token, poll_seconds=30) await api.start() messages = await api.messages() await api.send(chat_id, 'Hello') await api.send_photo(chat_id, Path('chart.png'), 'Today')
TelegramApiError
¶
Bases: RuntimeError
Telegram could not be reached or refused a request.
IncomingFile
dataclass
¶
A photo or file attached to a message, not yet downloaded.
Attributes:
| Name | Type | Description |
|---|---|---|
file_id |
str
|
Telegram's id for the file, used to download it. |
file_name |
str
|
The file's name; a photo, which has none, gets one made from the message. |
size_bytes |
int
|
The file's size as Telegram reports it, or 0 when unknown. |
IncomingMessage
dataclass
¶
One message sent to the bot: its text, and any photo or file with it.
Attributes:
| Name | Type | Description |
|---|---|---|
chat_id |
int
|
Telegram's id for the chat it came from. |
sender_name |
str
|
The sender's first name, or their username when they have none. |
text |
str
|
The message's text, or a photo's or file's caption; may be empty. |
files |
tuple[IncomingFile, ...]
|
The photo or file attached, not yet downloaded. |
IncomingButton
dataclass
¶
A press on one of the bot's buttons.
Attributes:
| Name | Type | Description |
|---|---|---|
chat_id |
int
|
The chat the button's message is in. |
sender_name |
str
|
The presser's first name, or their username when they have none. |
callback_id |
str
|
Telegram's id for the press, used to acknowledge it. |
data |
str
|
The text the bot attached to the button when sending it. |
message_id |
int
|
The message that holds the button. |
TelegramApi
¶
The bot's connection to Telegram.
Creates the connection without contacting Telegram.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
token
|
str
|
The bot token from BotFather. |
required |
poll_seconds
|
int
|
How long one long-poll request waits for messages. |
required |
Source code in src/trading_agent/channels/telegram_api.py
start
async
¶
Checks the token and learns the bot's username.
Returns:
| Type | Description |
|---|---|
str
|
The bot's username, such as my_trading_agent_bot. |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
The token is wrong or Telegram cannot be reached. |
Source code in src/trading_agent/channels/telegram_api.py
set_commands
async
¶
Sets the command menu Telegram shows when the user types a slash.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
commands
|
Sequence[tuple[str, str]]
|
Each command as (name without the slash, description). |
required |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the menu. |
Source code in src/trading_agent/channels/telegram_api.py
messages
async
¶
Waits for new messages and button presses, up to the poll time; stickers, voice notes and the like are skipped.
Updates are acknowledged once returned, so each is returned only once.
Returns:
| Type | Description |
|---|---|
list[IncomingMessage | IncomingButton]
|
The new messages and presses, oldest first; empty when none arrived in time. |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the request. |
Source code in src/trading_agent/channels/telegram_api.py
download
async
¶
Downloads a file that was sent to the bot.
Telegram lets a bot download files of up to 20 MB.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_id
|
str
|
Telegram's id for the file. |
required |
Returns:
| Type | Description |
|---|---|
bytes
|
The file's contents. |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached, or refused because the file is too large. |
Source code in src/trading_agent/channels/telegram_api.py
send
async
¶
Sends a plain-text message, split into parts when it is longer than Telegram allows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chat_id
|
int
|
The chat. |
required |
text
|
str
|
The message. |
required |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the message. |
Source code in src/trading_agent/channels/telegram_api.py
send_with_buttons
async
¶
Sends a message with buttons under it; a text too long for one message is sent in parts, the buttons under the last.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chat_id
|
int
|
The chat. |
required |
text
|
str
|
The message. |
required |
rows
|
ButtonRows
|
The buttons, row by row, each a (label, data) pair; the data comes back when it is pressed. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The id of the message holding the buttons. |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the message. |
Source code in src/trading_agent/channels/telegram_api.py
edit
async
¶
Replaces the text and buttons of a message the bot sent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chat_id
|
int
|
The chat. |
required |
message_id
|
int
|
The message. |
required |
text
|
str
|
The new text, cut to fit one message. |
required |
rows
|
ButtonRows | None
|
The new buttons, or None to remove them. |
required |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the change. |
Source code in src/trading_agent/channels/telegram_api.py
acknowledge
async
¶
Tells Telegram a button press was handled, optionally showing a short note on the phone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback_id
|
str
|
The press. |
required |
text
|
str
|
A note of up to 200 characters, or empty for none. |
''
|
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the request. |
Source code in src/trading_agent/channels/telegram_api.py
send_photo
async
¶
Sends a picture with a caption.
Telegram shows a photo inline but refuses one over 10 MB or with very long or thin proportions, such as a tall table; such a picture is sent as a file instead. A caption longer than Telegram allows follows as its own message.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
chat_id
|
int
|
The chat. |
required |
path
|
Path
|
The picture. |
required |
caption
|
str
|
The text shown with it; may be empty. |
required |
Raises:
| Type | Description |
|---|---|
TelegramApiError
|
Telegram could not be reached or refused the picture both ways. |
Source code in src/trading_agent/channels/telegram_api.py
close
async
¶
parts
staticmethod
¶
Splits a long message at line breaks into parts Telegram accepts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The message. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
The parts, each at most 4000 characters; one part for a short message. |