-
-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Add support for Telegram message attachments #153216
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
f578caf
485962e
925b758
4d17795
4c1024e
adc3dda
6af7423
beb9dce
4e55541
0cc0c6b
c656765
7b2faf3
39d36b3
84b43b6
e89c63d
527aa15
180052c
d8e74cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -7,7 +7,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| import logging | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from ssl import SSLContext | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from types import MappingProxyType | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import Any, cast | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import httpx | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from telegram import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -23,6 +23,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| InputMediaVideo, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| InputPollOption, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Message, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PhotoSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ReplyKeyboardMarkup, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ReplyKeyboardRemove, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Update, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -56,6 +57,10 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_DISABLE_NOTIF, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_DISABLE_WEB_PREV, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_ID, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_MIME_TYPE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_NAME, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_SIZE, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FROM_FIRST, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FROM_LAST, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_INLINE_MESSAGE_ID, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -85,6 +90,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONF_CHAT_ID, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CONF_PROXY_URL, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DOMAIN, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EVENT_TELEGRAM_ATTACHMENT, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EVENT_TELEGRAM_CALLBACK, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EVENT_TELEGRAM_COMMAND, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EVENT_TELEGRAM_SENT, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -182,6 +188,10 @@ def _get_message_event_data(self, message: Message) -> tuple[str, dict[str, Any] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This is a command message - set event type to command and split data into command and args | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_type = EVENT_TELEGRAM_COMMAND | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_data.update(self._get_command_event_data(message.text)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif filters.ATTACHMENT.filter(message): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_type = EVENT_TELEGRAM_ATTACHMENT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_data[ATTR_TEXT] = message.caption | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_data.update(self._get_file_id_event_data(message)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_type = EVENT_TELEGRAM_TEXT | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| event_data[ATTR_TEXT] = message.text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -191,6 +201,26 @@ def _get_message_event_data(self, message: Message) -> tuple[str, dict[str, Any] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return event_type, event_data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _get_file_id_event_data(self, message: Message) -> dict[str, Any]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Extract file_id from a message attachment, if any.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if filters.PHOTO.filter(message): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| photos = cast(Sequence[PhotoSize], message.effective_attachment) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_ID: photos[-1].file_id, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_MIME_TYPE: "image/jpeg", # telegram always uses jpeg for photos | ||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ATTR_FILE_MIME_TYPE: "image/jpeg", # telegram always uses jpeg for photos | |
| ATTR_FILE_MIME_TYPE: getattr(photos[-1], "mime_type", "image/jpeg"), # Telegram typically delivers photos as JPEG, but other formats are possible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PhotoSize does not hold mime_type fields. other formats other than JPEG is only available as Document.
https://stackoverflow.com/a/64927595
Copilot
AI
Oct 16, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] The dictionary comprehension silently skips attributes that don't exist using hasattr. This could mask issues if expected attributes are missing. Consider logging when attributes are missing or documenting which attachment types have which attributes to make the behavior more transparent.
| return { | |
| k: getattr(message.effective_attachment, v) | |
| for k, v in ( | |
| (ATTR_FILE_ID, "file_id"), | |
| (ATTR_FILE_NAME, "file_name"), | |
| (ATTR_FILE_MIME_TYPE, "mime_type"), | |
| (ATTR_FILE_SIZE, "file_size"), | |
| ) | |
| if hasattr(message.effective_attachment, v) | |
| } | |
| result = {} | |
| for k, v in ( | |
| (ATTR_FILE_ID, "file_id"), | |
| (ATTR_FILE_NAME, "file_name"), | |
| (ATTR_FILE_MIME_TYPE, "mime_type"), | |
| (ATTR_FILE_SIZE, "file_size"), | |
| ): | |
| if hasattr(message.effective_attachment, v): | |
| result[k] = getattr(message.effective_attachment, v) | |
| else: | |
| _LOGGER.debug( | |
| "Attachment of type %s is missing expected attribute '%s'", | |
| type(message.effective_attachment).__name__, | |
| v, | |
| ) | |
| return result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't think it's necessary to have that log, but willing to change that if anyone think otherwise
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| { | ||
| "update_id": 2, | ||
| "message": { | ||
| "message_id": 2, | ||
| "date": 1441645532, | ||
| "from": { | ||
| "id": 12345678, | ||
| "is_bot": false, | ||
| "last_name": "Test Lastname", | ||
| "first_name": "Test Firstname", | ||
| "username": "Testusername" | ||
| }, | ||
| "chat": { | ||
| "last_name": "Test Lastname", | ||
| "id": 1111111, | ||
| "type": "private", | ||
| "first_name": "Test Firstname", | ||
| "username": "Testusername" | ||
| }, | ||
| "document": { | ||
| "file_id": "AgACAgUAAxkBAAIBUWJ5aXl6Y3h5bXl6Y3h5bXl6Y3gAAJxvMRtP7nG4Fq7m0m0vBAAMCAAN5AAMjBA", | ||
| "file_unique_id": "AQADcbzEbT-5xuBa", | ||
| "mime_type": "application/pdf", | ||
| "file_size": 123456 | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| { | ||
| "update_id": 1, | ||
| "message": { | ||
| "message_id": 1, | ||
| "date": 1441645532, | ||
| "from": { | ||
| "id": 12345678, | ||
| "is_bot": false, | ||
| "last_name": "Test Lastname", | ||
| "first_name": "Test Firstname", | ||
| "username": "Testusername" | ||
| }, | ||
| "chat": { | ||
| "last_name": "Test Lastname", | ||
| "id": 1111111, | ||
| "type": "private", | ||
| "first_name": "Test Firstname", | ||
| "username": "Testusername" | ||
| }, | ||
| "photo": [ | ||
| { | ||
| "file_id": "AgACAgUAAxkBAAIBUWJ5aXl6Y3h5bXl6Y3h5bXl6Y3gAAJxvMRtP7nG4Fq7m0m0vBAAMCAAN5AAMjBA", | ||
| "file_unique_id": "AQADcbzEbT-5xuBa", | ||
| "file_size": 1234, | ||
| "width": 90, | ||
| "height": 90 | ||
| }, | ||
| { | ||
| "file_id": "AgACAgUAAxkBAAIBUWJ5aXl6Y3h5bXl6Y3h5bXl6Y3gAAJxvMRtP7nG4Fq7m0m0vBAAMCAAN5AAMjBA", | ||
| "file_unique_id": "AQADcbzEbT-5xuBa", | ||
| "file_size": 12345, | ||
| "width": 320, | ||
| "height": 320 | ||
| }, | ||
| { | ||
| "file_id": "AgACAgUAAxkBAAIBUWJ5aXl6Y3h5bXl6Y3h5bXl6Y3gAAJxvMRtP7nG4Fq7m0m0vBAAMCAAN5AAMjBA", | ||
| "file_unique_id": "AQADcbzEbT-5xuBa", | ||
| "file_size": 123456, | ||
| "width": 800, | ||
| "height": 800 | ||
| } | ||
| ] | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.