[Python lark-oapi 1.6.9] InboundMessage.mentioned_all is always False for post (rich-text) @all messages

Abierto
#138 1 comentario 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
3/5
Tiempo estimado
1-2 días
Aptitud para principiantes
76/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Tranquilo
Stack tecnológico
python
Área
api, backend

Línea de trabajo

Comienza en lark_oapi/channel/normalize/pipeline.py, en la rama PostContent de InboundPipeline.process; después, inspecciona converters/post.py y la reproducción proporcionada para comprobar la estructura del AST sin procesar del post. Verifica que un post que contiene un nodo at con user_id "all" produzca mentioned_all=True y que PolicyGate devuelva policy_mention_all_blocked, mientras que el comportamiento del texto ordinario permanezca sin cambios.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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:

  1. ext.mentioned_all (the event mentions[] array), and
  2. text_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 @all signal lives in the post AST as an at node with
    user_id == "all" ({"tag":"at","user_id":"all"}). converters/post.py
    renders that node to the literal string @所有人 / @<user_name>not
    the @_all placeholder that text_has_mention_all looks for, and not an
    <at> tag that parse_at_tags matches.

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.

Lenguaje dominante
Python
Estrellas
559
Forks
102
Métricas de merge de PR
Sin PR fusionados en 30 d

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de larksuite/oapi-sdk-python

Todos los issues de larksuite/oapi-sdk-python

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.