Added RichBlock (half) and RichText stuff#2602
Conversation
|
Added RichText stuff and half of RichBlock classes This could've been more simplified (e.g. by having text in the init of the base class), but I chose not to display and confuse people for some classes that don't have the text attribute, for example. Long way to go, I hope I'm on the right way |
|
@Badiboy I think I'm done, but I will double-check & test things tomorrow; you can, however, start reviewing the code |
Thank you for your work!! I do not think I can do it before weekend, but I'll do my best. |
|
@coder2020official Tried the 1. Async
await asyncio_helper.send_rich_message(
self.token, chat_id, rich_message,
business_connection_id=..., message_thread_id=message_thread_id,
direct_messages_topic_id=..., ...)but (The sync 2. Parsing the response crashes on plain-string rich text After working around (1), Per the docs, Minimal repro (async): |
|
Hi! Thanks for noting that--I have fixed your issue exactly; however, I am yet to address RichText being an array of RichText. I will have to test and see how it will look like. And I'm not sure my current implementation is safe. It seems to work, though. |
|
This should hypothetically work for arrays. Not really having the time to test--would be amazing if you could play around |
|
@coder2020official — your fix works. Confirmed on One thing worth flagging separately, because I don't think it was obvious from how I first framed it (my original report was only about the send path): the same When a
In effect it's a remotely-triggerable poller stall: anyone can send/forward rich content to any polling bot and freeze it — even if the bot never sends rich messages itself. That's actually how I hit it: an inbound forward, not a send. # no server needed to reproduce the crash Update.de_json would hit:
from telebot.types import RichText
RichText.de_json({"type": "bold", "text": "Detail"}) # pre-fix: JSONDecodeError
So it may be worth making the receive/parse path fail-safe while the block classes are being finished: if |
|
@coder2020official — one more of the same family (like the earlier
return await asyncio_helper.send_rich_message_draft(
self.token, chat_id, draft_id, rich_message,
message_thread_id=message_thread_id, business_connection_id=business_connection_id)but async def send_rich_message_draft(token, chat_id, draft_id, rich_message, message_thread_id=None):so every call fails with: Minimal repro (async): await bot.send_rich_message_draft(chat_id, 1, types.InputRichMessage(html="<tg-thinking>hi</tg-thinking>"))The sync Suggested fix: add I worked around it by calling the helper directly, and the draft itself streams fine once that's bypassed. |
|
sendrichmessagedraft shouldn't even have business connection id |
|
I tried forwarding a rich message to the bot and there were no issues |
It was fixed in dee734d |
|
@coder2020official Sorry for been so long. Hope to review today. |
|
|
||
| :param query_id: Optional. Identifier of the join request query; for bots assigned to process join request only. | ||
| If present, then the bot must call sendChatJoinRequestWebApp or directly call answerChatJoinRequestQuery within 10 seconds. | ||
| :type query_id: :obj:`int` |
| self.bio: Optional[str] = bio | ||
| self.invite_link: Optional[ChatInviteLink] = invite_link | ||
| self.user_chat_id: int = user_chat_id | ||
| self.query_id: Optional[int] = query_id |
| return cls(**obj) | ||
|
|
||
|
|
||
| class InputMediaLink(JsonDeserializable): |
There was a problem hiding this comment.
Propose to inherut it from InputMedia for consistency. Yes, I know that "media" field is required. I see two options:
- Make "media" optional for all InputMedia-s
- Override "init" here to avoid "media" for this class and set it to "None" inside.
First option looks more correct.
|
|
||
| :param text: The text | ||
| :type text: :class:`RichText` | ||
|
|
| self.is_header: Optional[bool] = is_header | ||
| self.colspan: Optional[int] = colspan | ||
| self.rowspan: Optional[int] = rowspan | ||
| self.align: Optional[str] = align |
| :param voice_note: The voice note | ||
| :type voice_note: :class:`Voice` | ||
|
|
||
| :param has_spoiler: Optional. True, if the media preview is covered by a spoiler animation |
| def __init__(self, voice_note: Voice, has_spoiler: Optional[bool] = None, caption: Optional[RichBlockCaption] = None, **kwargs): | ||
| super().__init__(type='voice_note', **kwargs) | ||
| self.voice_note: Voice = voice_note | ||
| self.has_spoiler: Optional[bool] = has_spoiler |
There was a problem hiding this comment.
Remove has_spoiler here also. And from init params.
| :param type: Type of the block, always “thinking” | ||
| :type type: :obj:`str` | ||
|
|
||
| :return: Instance of the class |




Rich Messages
Join Request Queries
Polls