Skip to content

Commit 7f3c0fd

Browse files
authored
fix: cannot receive image, file in dingtalk (#5920)
fixes: #5916 #5786
1 parent 8e431e2 commit 7f3c0fd

1 file changed

Lines changed: 95 additions & 7 deletions

File tree

astrbot/core/platform/sources/dingtalk/dingtalk_adapter.py

Lines changed: 95 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from astrbot import logger
1313
from astrbot.api.event import MessageChain
14-
from astrbot.api.message_components import At, Image, Plain, Record, Video
14+
from astrbot.api.message_components import At, File, Image, Plain, Record, Video
1515
from astrbot.api.platform import (
1616
AstrBotMessage,
1717
MessageMember,
@@ -178,10 +178,38 @@ async def convert_msg(
178178
abm.session_id = abm.sender.user_id
179179

180180
message_type: str = cast(str, message.message_type)
181+
robot_code = cast(str, message.robot_code or "")
182+
raw_content = cast(dict, message.extensions.get("content") or {})
183+
if not isinstance(raw_content, dict):
184+
raw_content = {}
181185
match message_type:
182186
case "text":
183187
abm.message_str = message.text.content.strip()
184188
abm.message.append(Plain(abm.message_str))
189+
case "picture":
190+
if not robot_code:
191+
logger.error("钉钉图片消息解析失败: 回调中缺少 robotCode")
192+
await self._remember_sender_binding(message, abm)
193+
return abm
194+
image_content = cast(
195+
dingtalk_stream.ImageContent | None,
196+
message.image_content,
197+
)
198+
download_code = cast(
199+
str, (image_content.download_code if image_content else "") or ""
200+
)
201+
if not download_code:
202+
logger.warning("钉钉图片消息缺少 downloadCode,已跳过")
203+
else:
204+
f_path = await self.download_ding_file(
205+
download_code,
206+
robot_code,
207+
"jpg",
208+
)
209+
if f_path:
210+
abm.message.append(Image.fromFileSystem(f_path))
211+
else:
212+
logger.warning("钉钉图片消息下载失败,无法解析为图片")
185213
case "richText":
186214
rtc: dingtalk_stream.RichTextContent = cast(
187215
dingtalk_stream.RichTextContent, message.rich_text_content
@@ -193,14 +221,64 @@ async def convert_msg(
193221
plains += content["text"]
194222
abm.message.append(Plain(plains))
195223
elif "type" in content and content["type"] == "picture":
224+
download_code = cast(str, content.get("downloadCode") or "")
225+
if not download_code:
226+
logger.warning(
227+
"钉钉富文本图片消息缺少 downloadCode,已跳过"
228+
)
229+
continue
230+
if not robot_code:
231+
logger.error(
232+
"钉钉富文本图片消息解析失败: 回调中缺少 robotCode"
233+
)
234+
continue
196235
f_path = await self.download_ding_file(
197-
content["downloadCode"],
198-
cast(str, message.robot_code),
236+
download_code,
237+
robot_code,
199238
"jpg",
200239
)
201-
abm.message.append(Image.fromFileSystem(f_path))
202-
case "audio":
203-
pass
240+
if f_path:
241+
abm.message.append(Image.fromFileSystem(f_path))
242+
case "audio" | "voice":
243+
download_code = cast(str, raw_content.get("downloadCode") or "")
244+
if not download_code:
245+
logger.warning("钉钉语音消息缺少 downloadCode,已跳过")
246+
elif not robot_code:
247+
logger.error("钉钉语音消息解析失败: 回调中缺少 robotCode")
248+
else:
249+
voice_ext = cast(str, raw_content.get("fileExtension") or "")
250+
if not voice_ext:
251+
voice_ext = "amr"
252+
voice_ext = voice_ext.lstrip(".")
253+
f_path = await self.download_ding_file(
254+
download_code,
255+
robot_code,
256+
voice_ext,
257+
)
258+
if f_path:
259+
abm.message.append(Record.fromFileSystem(f_path))
260+
case "file":
261+
download_code = cast(str, raw_content.get("downloadCode") or "")
262+
if not download_code:
263+
logger.warning("钉钉文件消息缺少 downloadCode,已跳过")
264+
elif not robot_code:
265+
logger.error("钉钉文件消息解析失败: 回调中缺少 robotCode")
266+
else:
267+
file_name = cast(str, raw_content.get("fileName") or "")
268+
file_ext = Path(file_name).suffix.lstrip(".") if file_name else ""
269+
if not file_ext:
270+
file_ext = cast(str, raw_content.get("fileExtension") or "")
271+
if not file_ext:
272+
file_ext = "file"
273+
f_path = await self.download_ding_file(
274+
download_code,
275+
robot_code,
276+
file_ext,
277+
)
278+
if f_path:
279+
if not file_name:
280+
file_name = Path(f_path).name
281+
abm.message.append(File(name=file_name, file=f_path))
204282

205283
await self._remember_sender_binding(message, abm)
206284
return abm # 别忘了返回转换后的消息对象
@@ -270,7 +348,17 @@ async def download_ding_file(
270348
)
271349
return ""
272350
resp_data = await resp.json()
273-
download_url = resp_data["data"]["downloadUrl"]
351+
download_url = cast(
352+
str,
353+
(
354+
resp_data.get("downloadUrl")
355+
or resp_data.get("data", {}).get("downloadUrl")
356+
or ""
357+
),
358+
)
359+
if not download_url:
360+
logger.error(f"下载钉钉文件失败: 未找到 downloadUrl, 响应: {resp_data}")
361+
return ""
274362
await download_file(download_url, str(f_path))
275363
return str(f_path)
276364

0 commit comments

Comments
 (0)