Просмотр исходного кода

feat: add DingTalk(钉钉) tool for sending message to chat group bot via webhook (#2693)

Bowen Liang 1 год назад
Родитель
Сommit
f82a64d149

+ 1 - 0
api/core/tools/provider/_position.yaml

@@ -24,3 +24,4 @@
 - gaode
 - wecom
 - qrcode
+- dingtalk

+ 7 - 0
api/core/tools/provider/builtin/dingtalk/_assets/icon.svg

@@ -0,0 +1,7 @@
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
+<svg fill="#4aa4f8" width="800px" height="800px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg" class="icon" stroke="#4aa4f8">
+
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
+
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
+
<g id="SVGRepo_iconCarrier"> <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm227 385.3c-1 4.2-3.5 10.4-7 17.8h.1l-.4.7c-20.3 43.1-73.1 127.7-73.1 127.7s-.1-.2-.3-.5l-15.5 26.8h74.5L575.1 810l32.3-128h-58.6l20.4-84.7c-16.5 3.9-35.9 9.4-59 16.8 0 0-31.2 18.2-89.9-35 0 0-39.6-34.7-16.6-43.4 9.8-3.7 47.4-8.4 77-12.3 40-5.4 64.6-8.2 64.6-8.2S422 517 392.7 512.5c-29.3-4.6-66.4-53.1-74.3-95.8 0 0-12.2-23.4 26.3-12.3 38.5 11.1 197.9 43.2 197.9 43.2s-207.4-63.3-221.2-78.7c-13.8-15.4-40.6-84.2-37.1-126.5 0 0 1.5-10.5 12.4-7.7 0 0 153.3 69.7 258.1 107.9 104.8 37.9 195.9 57.3 184.2 106.7z"/> </g>
+
</svg>

+ 8 - 0
api/core/tools/provider/builtin/dingtalk/dingtalk.py

@@ -0,0 +1,8 @@
+from core.tools.provider.builtin.dingtalk.tools.dingtalk_group_bot import DingTalkGroupBotTool
+from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
+
+
+class DingTalkProvider(BuiltinToolProviderController):
+    def _validate_credentials(self, credentials: dict) -> None:
+        DingTalkGroupBotTool()
+        pass

+ 13 - 0
api/core/tools/provider/builtin/dingtalk/dingtalk.yaml

@@ -0,0 +1,13 @@
+identity:
+  author: Bowen Liang
+  name: dingtalk
+  label:
+    en_US: DingTalk
+    zh_Hans: 钉钉
+    pt_BR: DingTalk
+  description:
+    en_US: DingTalk group robot
+    zh_Hans: 钉钉群机器人
+    pt_BR: DingTalk group robot
+  icon: icon.svg
+credentials_for_provider:

+ 83 - 0
api/core/tools/provider/builtin/dingtalk/tools/dingtalk_group_bot.py

@@ -0,0 +1,83 @@
+import base64
+import hashlib
+import hmac
+import logging
+import time
+import urllib.parse
+from typing import Any, Union
+
+import httpx
+
+from core.tools.entities.tool_entities import ToolInvokeMessage
+from core.tools.tool.builtin_tool import BuiltinTool
+
+
+class DingTalkGroupBotTool(BuiltinTool):
+    def _invoke(self, user_id: str, tool_parameters: dict[str, Any]
+                ) -> Union[ToolInvokeMessage, list[ToolInvokeMessage]]:
+        """
+            invoke tools
+            Dingtalk custom group robot API docs:
+            https://open.dingtalk.com/document/orgapp/custom-robot-access
+        """
+        content = tool_parameters.get('content')
+        if not content:
+            return self.create_text_message('Invalid parameter content')
+
+        access_token = tool_parameters.get('access_token')
+        if not access_token:
+            return self.create_text_message('Invalid parameter access_token. '
+                                            'Regarding information about security details,'
+                                            'please refer to the DingTalk docs:'
+                                            'https://open.dingtalk.com/document/robots/customize-robot-security-settings')
+
+        sign_secret = tool_parameters.get('sign_secret')
+        if not sign_secret:
+            return self.create_text_message('Invalid parameter sign_secret. '
+                                            'Regarding information about security details,'
+                                            'please refer to the DingTalk docs:'
+                                            'https://open.dingtalk.com/document/robots/customize-robot-security-settings')
+
+        msgtype = 'text'
+        api_url = 'https://oapi.dingtalk.com/robot/send'
+        headers = {
+            'Content-Type': 'application/json',
+        }
+        params = {
+            'access_token': access_token,
+        }
+
+        self._apply_security_mechanism(params, sign_secret)
+
+        payload = {
+            "msgtype": msgtype,
+            "text": {
+                "content": content,
+            }
+        }
+
+        try:
+            res = httpx.post(api_url, headers=headers, params=params, json=payload)
+            if res.is_success:
+                return self.create_text_message("Text message sent successfully")
+            else:
+                return self.create_text_message(
+                    f"Failed to send the text message, status code: {res.status_code}, response: {res.text}")
+        except Exception as e:
+            return self.create_text_message("Failed to send message to group chat bot. {}".format(e))
+
+    @staticmethod
+    def _apply_security_mechanism(params: dict[str, Any], sign_secret: str):
+        try:
+            timestamp = str(round(time.time() * 1000))
+            secret_enc = sign_secret.encode('utf-8')
+            string_to_sign = f'{timestamp}\n{sign_secret}'
+            string_to_sign_enc = string_to_sign.encode('utf-8')
+            hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
+            sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
+
+            params['timestamp'] = timestamp
+            params['sign'] = sign
+        except Exception:
+            msg = "Failed to apply security mechanism to the request."
+            logging.exception(msg)

+ 52 - 0
api/core/tools/provider/builtin/dingtalk/tools/dingtalk_group_bot.yaml

@@ -0,0 +1,52 @@
+identity:
+  name: dingtalk_group_bot
+  author: Bowen Liang
+  label:
+    en_US: Send Group Message
+    zh_Hans: 发送群消息
+    pt_BR: Send Group Message
+  icon: icon.svg
+description:
+  human:
+    en_US: Sending a group message on DingTalk via the webhook of group bot
+    zh_Hans: 通过钉钉的群机器人webhook发送群消息
+    pt_BR: Sending a group message on DingTalk via the webhook of group bot
+  llm: A tool for sending messages to a chat group on DingTalk(钉钉) .
+parameters:
+  - name: access_token
+    type: secret-input
+    required: true
+    label:
+      en_US: access token
+      zh_Hans: access token
+      pt_BR: access token
+    human_description:
+      en_US: access_token in the group robot webhook
+      zh_Hans: 群自定义机器人webhook中access_token字段的值
+      pt_BR: access_token in the group robot webhook
+    form: form
+  - name: sign_secret
+    type: secret-input
+    required: true
+    label:
+      en_US: secret key for signing
+      zh_Hans: 加签秘钥
+      pt_BR: secret key for signing
+    human_description:
+      en_US: secret key for signing
+      zh_Hans: 加签秘钥
+      pt_BR: secret key for signing
+    form: form
+  - name: content
+    type: string
+    required: true
+    label:
+      en_US: content
+      zh_Hans: 消息内容
+      pt_BR: content
+    human_description:
+      en_US: Content to sent to the group.
+      zh_Hans: 群消息文本
+      pt_BR: Content to sent to the group.
+    llm_description: Content of the message
+    form: llm