Message hooks
A plugin can intercept messages before sending and before showing. A hook is declared in contributes, and it needs the matching permission.
Outgoing
Section titled “Outgoing”Permission: messages.transform_outgoing. Manifest:
"contributes": { "outgoing": { "block": false, "media": false, "filter": { "chatTypes": ["user", "group"] } }}block— the hook may cancel sending.media— also sees file sends (the text is the caption).filter— limits by chats (chats) or chat types:user,bot,self,group,supergroup,forum,channel.
The event is message.outgoing. Inside the handler these are available (only in the synchronous freshgram.messages):
@freshgram.on("message.outgoing")def outgoing(event): if "secret" in event["text"]: freshgram.messages.drop_outgoing("Not sending secrets") return freshgram.messages.set_outgoing(event["text"].upper(), silent=True)set_outgoing accepts text, markdown, silent, schedule, reply_to, topic, entities. An unusable value is ignored. drop_outgoing(reason) does not send the message; a non-empty reason is shown as a toast.
Incoming
Section titled “Incoming”Permission: messages.transform_incoming. In the manifest, contributes.incoming with onFailure (pass or block), mode (swap or hold), service and filter. See the full manifest reference.
The event is message.incoming:
@freshgram.on("message.incoming")def incoming(event): freshgram.messages.set_incoming(text="…", markdown=True) # or freshgram.messages.hide_incoming("spam")Only the display changes: forwarding, editing and other plugins’ events see the real text.
Formatting
Section titled “Formatting”markdown=True parses **bold**, __italic__, ~~strike~~, ||spoiler||, `code`, code blocks, [text](url) and quotes. markdown="html" parses <b>, <i>, <u>, <s>, <code>, <pre>, <a href>, <tg-spoiler>, <blockquote expandable>, <emoji id=N>, <br> (needs the format.html feature). Bad markup raises Invalid.
