Skip to content

Commit

Permalink
Merge pull request #1152 from RockChinQ/feat/dingtalk-audio
Browse files Browse the repository at this point in the history
feat(dingtalk): add supports for audio receiving
  • Loading branch information
RockChinQ authored Mar 2, 2025
2 parents 0f3dc35 + bc8c346 commit 60c0adc
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 23 deletions.
3 changes: 2 additions & 1 deletion libs/dingtalk_api/EchoHandler.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import json
import dingtalk_stream
from dingtalk_stream import AckMessage

Expand All @@ -17,7 +18,7 @@ async def process(self, callback: dingtalk_stream.CallbackMessage):
await self.client.update_incoming_message(incoming_message)

return AckMessage.STATUS_OK, 'OK'

async def get_incoming_message(self):
"""异步等待消息的到来"""
while self.incoming_message is None:
Expand Down
39 changes: 34 additions & 5 deletions libs/dingtalk_api/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
import json
import time
from typing import Callable
import dingtalk_stream
Expand Down Expand Up @@ -92,8 +93,31 @@ async def download_url_to_base64(self,download_url):
base64_str = base64.b64encode(file_bytes).decode('utf-8') # 返回字符串格式
return base64_str
else:
raise Exception("获取图片失败")

raise Exception("获取文件失败")

async def get_audio_url(self,download_code:str):
if not await self.check_access_token():
await self.get_access_token()
url = 'https://api.dingtalk.com/v1.0/robot/messageFiles/download'
params = {
"downloadCode":download_code,
"robotCode":self.robot_code
}
headers ={
"x-acs-dingtalk-access-token": self.access_token
}
async with httpx.AsyncClient() as client:
response = await client.post(url, headers=headers, json=params)
if response.status_code == 200:
result = response.json()
download_url = result.get("downloadUrl")
if download_url:
return await self.download_url_to_base64(download_url)
else:
raise Exception("获取音频失败")
else:
raise Exception(f"Error: {response.status_code}, {response.text}")

async def update_incoming_message(self, message):
"""异步更新 DingTalkClient 中的 incoming_message"""
message_data = await self.get_message(message)
Expand Down Expand Up @@ -133,6 +157,7 @@ async def _handle_message(self, event: DingTalkEvent):

async def get_message(self,incoming_message:dingtalk_stream.chatbot.ChatbotMessage):
try:
# print(json.dumps(incoming_message.to_dict(), indent=4, ensure_ascii=False))
message_data = {
"IncomingMessage":incoming_message,
}
Expand Down Expand Up @@ -160,10 +185,14 @@ async def get_message(self,incoming_message:dingtalk_stream.chatbot.ChatbotMessa
message_data['Picture'] = await self.download_image(incoming_message.get_image_list()[0])

message_data['Type'] = 'image'
elif incoming_message.message_type == 'audio':
message_data['Audio'] = await self.get_audio_url(incoming_message.to_dict()['content']['downloadCode'])

message_data['Type'] = 'audio'

# 删掉开头的@消息
if message_data["Content"].startswith("@"+self.robot_name):
message_data["Content"][len("@"+self.robot_name):]
copy_message_data = message_data.copy()
del copy_message_data['IncomingMessage']
# print("message_data:", json.dumps(copy_message_data, indent=4, ensure_ascii=False))
except Exception:
traceback.print_exc()

Expand Down
9 changes: 7 additions & 2 deletions libs/dingtalk_api/dingtalkevent.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import Dict, Any, Optional
import dingtalk_stream

class DingTalkEvent(dict):
@staticmethod
Expand All @@ -15,7 +16,7 @@ def content(self):
return self.get("Content","")

@property
def incoming_message(self):
def incoming_message(self) -> Optional["dingtalk_stream.chatbot.ChatbotMessage"]:
return self.get("IncomingMessage")

@property
Expand All @@ -25,6 +26,10 @@ def type(self):
@property
def picture(self):
return self.get("Picture","")

@property
def audio(self):
return self.get("Audio","")

@property
def conversation(self):
Expand Down Expand Up @@ -61,4 +66,4 @@ def __repr__(self) -> str:
Returns:
str: 字符串表示。
"""
return f"<WecomEvent {super().__repr__()}>"
return f"<DingTalkEvent {super().__repr__()}>"
37 changes: 22 additions & 15 deletions pkg/platform/sources/dingtalk.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,23 @@ async def yiri2target(
return msg.text

@staticmethod
async def target2yiri(event:DingTalkEvent):
async def target2yiri(event:DingTalkEvent, bot_name:str):
yiri_msg_list = []
yiri_msg_list.append(
platform_message.Source(id = '0',time=datetime.datetime.now())
platform_message.Source(id = event.incoming_message.message_id,time=datetime.datetime.now())
)

for atUser in event.incoming_message.at_users:
if atUser.dingtalk_id == event.incoming_message.chatbot_user_id:
yiri_msg_list.append(platform_message.At(target=bot_name))

if event.content:
yiri_msg_list.append(platform_message.Plain(text=event.content))
text_content = event.content.replace("@"+bot_name, '')
yiri_msg_list.append(platform_message.Plain(text=text_content))
if event.picture:
yiri_msg_list.append(platform_message.Image(base64=event.picture))
if event.audio:
yiri_msg_list.append(platform_message.Voice(base64=event.audio))

chain = platform_message.MessageChain(yiri_msg_list)

Expand All @@ -54,33 +61,33 @@ async def yiri2target(

@staticmethod
async def target2yiri(
event:DingTalkEvent
event:DingTalkEvent,
bot_name:str
):

message_chain = await DingTalkMessageConverter.target2yiri(event)
message_chain = await DingTalkMessageConverter.target2yiri(event, bot_name)


if event.conversation == 'FriendMessage':

return platform_events.FriendMessage(
sender=platform_entities.Friend(
id= 0,
nickname ='nickname',
id=event.incoming_message.sender_id,
nickname = event.incoming_message.sender_nick,
remark=""
),
message_chain = message_chain,
time = datetime.datetime.now(),
source_platform_object=event,
)
elif event.conversation == 'GroupMessage':
message_chain.insert(0, platform_message.At(target="justbot"))
sender = platform_entities.GroupMember(
id = 111,
member_name="name",
id = event.incoming_message.sender_id,
member_name=event.incoming_message.sender_nick,
permission= 'MEMBER',
group = platform_entities.Group(
id = 111,
name = 'MEMBER',
id = event.incoming_message.conversation_id,
name = event.incoming_message.conversation_title,
permission=platform_entities.Permission.Member
),
special_title='',
Expand Down Expand Up @@ -117,6 +124,8 @@ def __init__(self,config:dict,ap:app.Application):
missing_keys = [key for key in required_keys if key not in config]
if missing_keys:
raise ParamNotEnoughError("钉钉缺少相关配置项,请查看文档或联系管理员")

self.bot_account_id = self.config["robot_name"]

self.bot = DingTalkClient(
client_id=config["client_id"],
Expand Down Expand Up @@ -153,10 +162,9 @@ def register_listener(
],
):
async def on_message(event: DingTalkEvent):
self.bot_account_id = 'justbot'
try:
return await callback(
await self.event_converter.target2yiri(event), self
await self.event_converter.target2yiri(event, self.config["robot_name"]), self
)
except:
traceback.print_exc()
Expand All @@ -167,7 +175,6 @@ async def on_message(event: DingTalkEvent):
self.bot.on_message("GroupMessage")(on_message)

async def run_async(self):

await self.bot.start()

async def kill(self) -> bool:
Expand Down

0 comments on commit 60c0adc

Please sign in to comment.