Skip to content

Commit 01a47b8

Browse files
authored
feat: pass through qq webhook extra fields (#6274)
1 parent d16e6a8 commit 01a47b8

2 files changed

Lines changed: 36 additions & 9 deletions

File tree

astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_adapter.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,20 @@ async def on_c2c_message_create(self, message: botpy.message.C2CMessage) -> None
7575

7676
def _commit(self, abm: AstrBotMessage) -> None:
7777
self.platform.remember_session_message_id(abm.session_id, abm.message_id)
78-
self.platform.commit_event(
79-
QQOfficialWebhookMessageEvent(
80-
abm.message_str,
81-
abm,
82-
self.platform.meta(),
83-
abm.session_id,
84-
self,
85-
),
78+
event = QQOfficialWebhookMessageEvent(
79+
abm.message_str,
80+
abm,
81+
self.platform.meta(),
82+
abm.session_id,
83+
self,
8684
)
85+
# Populate extra fields cached from the raw webhook payload
86+
webhook_helper = getattr(self.platform, "webhook_helper", None)
87+
if webhook_helper and abm.message_id:
88+
extra_data = webhook_helper.pop_extra_data(abm.message_id)
89+
for key, val in extra_data.items():
90+
event.set_extra(key, val)
91+
self.platform.commit_event(event)
8792

8893

8994
@register_platform_adapter("qq_official_webhook", "QQ 机器人官方 API 适配器(Webhook)")

astrbot/core/platform/sources/qqofficial_webhook/qo_webhook_server.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ def __init__(
4040
self.client = botpy_client
4141
self.event_queue = event_queue
4242
self.shutdown_event = asyncio.Event()
43+
44+
# Cache for extra fields extracted from raw webhook payloads, keyed by message id
45+
self._extra_data_cache: dict[str, dict] = {}
46+
4347
# Deduplication cache for webhook retry callbacks.
4448
self._seen_event_ids: dict[str, float] = {}
4549
self._dedup_ttl: int = 60 # seconds
@@ -84,6 +88,10 @@ async def webhook_validation(self, validation_payload: dict):
8488
}
8589
return response
8690

91+
def pop_extra_data(self, message_id: str) -> dict:
92+
"""Pop and return extra fields cached from the raw webhook payload for a given message ID."""
93+
return self._extra_data_cache.pop(message_id, {})
94+
8795
async def callback(self):
8896
"""内部服务器的回调入口"""
8997
return await self.handle_callback(quart.request)
@@ -107,7 +115,7 @@ async def handle_callback(self, request) -> dict:
107115
if opcode == 13:
108116
# validation
109117
signed = await self.webhook_validation(cast(dict, data))
110-
print(signed)
118+
logger.debug(f"webhook validation response: {signed}")
111119
return signed
112120

113121
event_id = msg.get("id")
@@ -128,10 +136,24 @@ async def handle_callback(self, request) -> dict:
128136

129137
if event and opcode == BotWebSocket.WS_DISPATCH_EVENT:
130138
event = msg["t"].lower()
139+
# Extract extra fields from raw payload before botpy parses and discards them
140+
if data:
141+
msg_id = data.get("id")
142+
if msg_id:
143+
author = data.get("author") or {}
144+
extra: dict = {}
145+
if union_openid := author.get("union_openid"):
146+
extra["union_openid"] = union_openid
147+
if message_scene := data.get("message_scene"):
148+
extra["message_scene"] = message_scene
149+
if extra:
150+
self._extra_data_cache[msg_id] = extra
131151
try:
132152
func = self._connection.parser[event]
133153
except KeyError:
134154
logger.error("_parser unknown event %s.", event)
155+
if data:
156+
self._extra_data_cache.pop(data.get("id", ""), None)
135157
else:
136158
func(msg)
137159

0 commit comments

Comments
 (0)