[Python lark-oapi 1.6.9] InboundMessage.mentioned_all is always False for post (rich-text) @all messages
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 76/100
調査の方向性
lark_oapi/channel/normalize/pipeline.py の InboundPipeline.process にある PostContent ブランチから始め、次に converters/post.py と提供されている再現コードを調べて、raw post AST の構造を確認します。user_id が "all" の at ノードを含む post で mentioned_all=True が生成され、PolicyGate が policy_mention_all_blocked を返すことを確認し、通常のテキストの動作が変わらないことも確認します。
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- Python
- スター
- 559
- フォーク
- 102
- PR マージ指標
- 30日以内にマージされた PR はありません
コントリビューションガイド
このリポジトリのコントリビューションガイドは索引されていません
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
larksuite/oapi-sdk-python のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 67/100
larksuite/oapi-sdk-python#163 · コメント 1 件 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
larksuite/oapi-sdk-python#162 · コメント 1 件 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 94/100
larksuite/oapi-sdk-python#161 ·
-
難易度 1/5 1時間未満 初心者へのやさしさ 90/100
larksuite/oapi-sdk-python#160 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
larksuite/oapi-sdk-python#159 ·
larksuite/oapi-sdk-python の issue をすべて見る
似ている issue
-
documentation help wanted
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
simonw/sqlite-utils#872 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100