larksuite / larksuite/oapi-sdk-python
[Python lark-oapi 1.6.9] InboundMessage.mentioned_all is always False for post (rich-text) @all messages
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 559
- Forks
- 102
- PR merge metrics
- No merged PRs in 30d
Description
Summary
For post (rich-text) messages that mention everyone (@所有人 / @all),
InboundMessage.mentioned_all is always False. As a result PolicyGate
never emits policy_mention_all_blocked, so a bot configured with
respond_to_mention_all=False still responds to broadcast @all posts.
Plain text @all messages are handled correctly — only the post code
path is affected.
Root cause
In lark_oapi/channel/normalize/pipeline.py, the PostContent branch of
InboundPipeline.process derives mentioned_all only from:
ext.mentioned_all(the eventmentions[]array), andtext_has_mention_all(content.text)/parse_at_tags(content.text)
(the rendered text).
But for a post:
- Feishu does not populate
mentions[]for@all(already acknowledged in the
code comments on the text branch). - The
@allsignal lives in the post AST as anatnode with
user_id == "all"({"tag":"at","user_id":"all"}).converters/post.py
renders that node to the literal string@所有人/@<user_name>— not
the@_allplaceholder thattext_has_mention_alllooks for, and not an
<at>tag thatparse_at_tagsmatches.
So neither probe fires and mentioned_all stays False. The post AST is never
inspected for the mention-all node.
Reproduction (confirmed on 1.6.9, also reproduces on 1.6.6)
import asyncio, json
from lark_oapi.channel.normalize.pipeline import InboundPipeline, PipelineConfig, PipelineDeps
from lark_oapi.channel.config import PolicyConfig
from lark_oapi.channel.safety.policy_gate import PolicyGate
async def main():
pipe = InboundPipeline(PipelineConfig(), PipelineDeps())
# A post that @-mentions everyone, like a broadcast notice
content = {"content": [[
{"tag": "at", "user_id": "all", "user_name": "Everyone"},
{"tag": "text", "text": " heads up everyone"},
]]}
event = {"message_id": "om", "chat_id": "oc", "chat_type": "group",
"message_type": "post", "content": json.dumps(content), "mentions": []}
sender = {"sender_id": {"open_id": "ou_asker"}, "sender_type": "user"}
inbound = await pipe.process("e", event, sender)
print("post mentioned_all =", inbound.mentioned_all)
gate = PolicyGate(PolicyConfig(require_mention=False, respond_to_mention_all=False))
gate.set_bot_open_id("ou_bot")
print("post decision =", gate.evaluate(inbound))
# same intent as plain text — handled correctly
tevent = dict(event, message_type="text", content=json.dumps({"text": "@_all heads up"}))
tin = await pipe.process("e2", tevent, sender)
print("text mentioned_all =", tin.mentioned_all)
print("text decision =", gate.evaluate(tin))
asyncio.run(main())
Output:
post mentioned_all = False
post decision = PolicyDecision(allowed=True, reason=None)
text mentioned_all = True
text decision = PolicyDecision(allowed=False, reason='policy_mention_all_blocked')
Expected: the post case should match the text case
(mentioned_all = True, decision policy_mention_all_blocked).
Suggested fix
In the PostContent branch, probe the raw post AST for an at node with
user_id == "all" (mirroring is_mention_all):
elif isinstance(content, PostContent):
if not mentioned_all and text_has_mention_all(content.text):
mentioned_all = True
# post @all is an `at` node (user_id == "all") in the AST, not an
# @_all placeholder in the rendered text — probe the raw post.
if not mentioned_all and _post_has_mention_all(content.post):
mentioned_all = True
...
where _post_has_mention_all walks the post documents/paragraphs for any at
element whose user_id (or open_id) equals "all".
Environment
- lark-oapi 1.6.9 (also 1.6.6)
- Python 3.11
Possibly related: #134 (InboundMessage.mentioned_bot always False for IM
messages) — same family of post/IM mention-resolution gaps.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lark_oapi/channel/normalize/pipeline.py at the InboundPipeline.process PostContent branch, then inspect converters/post.py and the provided reproduction for the raw post AST shape. Verify that a post containing an at node with user_id "all" produces mentioned_all=True and that PolicyGate returns policy_mention_all_blocked, while ordinary text behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100