feat(Tools): add feishu document and message plugins (#6435)

Co-authored-by: 黎斌 <libin.23@bytedance.com>
This commit is contained in:
走在修行的大街上 2024-08-27 20:21:42 +08:00 committed by GitHub
parent 3f467613fc
commit 92cab33b73
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 707 additions and 0 deletions

View File

@ -30,5 +30,7 @@
- dingtalk
- feishu
- feishu_base
- feishu_document
- feishu_message
- slack
- tianditu

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64px" height="64px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
<g><path style="opacity:1" fill="#fefefe" d="M -0.5,-0.5 C 20.8333,-0.5 42.1667,-0.5 63.5,-0.5C 63.5,20.8333 63.5,42.1667 63.5,63.5C 42.1667,63.5 20.8333,63.5 -0.5,63.5C -0.5,42.1667 -0.5,20.8333 -0.5,-0.5 Z"/></g>
<g><path style="opacity:1" fill="#346df3" d="M 47.5,33.5 C 43.3272,29.8779 38.9939,29.7112 34.5,33C 32.682,35.4897 30.3487,37.3231 27.5,38.5C 23.5003,43.5136 24.167,47.847 29.5,51.5C 24.1563,51.666 18.8229,51.4994 13.5,51C 13,50.5 12.5,50 12,49.5C 11.3333,36.8333 11.3333,24.1667 12,11.5C 12.5,11 13,10.5 13.5,10C 24.1667,9.33333 34.8333,9.33333 45.5,10C 46,10.5 46.5,11 47,11.5C 47.4997,18.8258 47.6663,26.1591 47.5,33.5 Z"/></g>
<g><path style="opacity:1" fill="#f9fafe" d="M 20.5,19.5 C 25.1785,19.3342 29.8452,19.5008 34.5,20C 35.8333,21 35.8333,22 34.5,23C 29.8333,23.6667 25.1667,23.6667 20.5,23C 19.3157,21.8545 19.3157,20.6879 20.5,19.5 Z"/></g>
<g><path style="opacity:1" fill="#f3f6fe" d="M 20.5,27.5 C 22.5273,27.3379 24.5273,27.5045 26.5,28C 27.8333,29 27.8333,30 26.5,31C 24.5,31.6667 22.5,31.6667 20.5,31C 19.3157,29.8545 19.3157,28.6879 20.5,27.5 Z"/></g>
<g><path style="opacity:1" fill="#36d4c1" d="M 47.5,33.5 C 48.7298,35.2972 49.3964,37.2972 49.5,39.5C 51.3904,39.2965 52.8904,39.9632 54,41.5C 55.1825,45.2739 54.3492,48.4406 51.5,51C 44.1742,51.4997 36.8409,51.6663 29.5,51.5C 24.167,47.847 23.5003,43.5136 27.5,38.5C 30.3487,37.3231 32.682,35.4897 34.5,33C 38.9939,29.7112 43.3272,29.8779 47.5,33.5 Z"/></g>
</svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -0,0 +1,15 @@
from core.tools.errors import ToolProviderCredentialValidationError
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
from core.tools.utils.feishu_api_utils import FeishuRequest
class FeishuDocumentProvider(BuiltinToolProviderController):
def _validate_credentials(self, credentials: dict) -> None:
app_id = credentials.get('app_id')
app_secret = credentials.get('app_secret')
if not app_id or not app_secret:
raise ToolProviderCredentialValidationError("app_id and app_secret is required")
try:
assert FeishuRequest(app_id, app_secret).tenant_access_token is not None
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))

View File

@ -0,0 +1,34 @@
identity:
author: Doug Lea
name: feishu_document
label:
en_US: Lark Cloud Document
zh_Hans: 飞书云文档
description:
en_US: Lark Cloud Document
zh_Hans: 飞书云文档
icon: icon.svg
tags:
- social
- productivity
credentials_for_provider:
app_id:
type: text-input
required: true
label:
en_US: APP ID
placeholder:
en_US: Please input your feishu app id
zh_Hans: 请输入你的飞书 app id
help:
en_US: Get your app_id and app_secret from Feishu
zh_Hans: 从飞书获取您的 app_id 和 app_secret
url: https://open.feishu.cn
app_secret:
type: secret-input
required: true
label:
en_US: APP Secret
placeholder:
en_US: Please input your app secret
zh_Hans: 请输入你的飞书 app secret

View File

@ -0,0 +1,19 @@
from typing import Any
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.utils.feishu_api_utils import FeishuRequest
class CreateDocumentTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
app_id = self.runtime.credentials.get('app_id')
app_secret = self.runtime.credentials.get('app_secret')
client = FeishuRequest(app_id, app_secret)
title = tool_parameters.get('title')
content = tool_parameters.get('content')
folder_token = tool_parameters.get('folder_token')
res = client.create_document(title, content, folder_token)
return self.create_json_message(res)

View File

@ -0,0 +1,47 @@
identity:
name: create_document
author: Doug Lea
label:
en_US: Create Lark document
zh_Hans: 创建飞书文档
description:
human:
en_US: Create Lark document
zh_Hans: 创建飞书文档,支持创建空文档和带内容的文档,支持 markdown 语法创建。
llm: A tool for creating Feishu documents.
parameters:
- name: title
type: string
required: false
label:
en_US: Document title
zh_Hans: 文档标题
human_description:
en_US: Document title, only supports plain text content.
zh_Hans: 文档标题,只支持纯文本内容。
llm_description: 文档标题,只支持纯文本内容,可以为空。
form: llm
- name: content
type: string
required: false
label:
en_US: Document content
zh_Hans: 文档内容
human_description:
en_US: Document content, supports markdown syntax, can be empty.
zh_Hans: 文档内容,支持 markdown 语法,可以为空。
llm_description: 文档内容,支持 markdown 语法,可以为空。
form: llm
- name: folder_token
type: string
required: false
label:
en_US: folder_token
zh_Hans: 文档所在文件夹的 Token
human_description:
en_US: The token of the folder where the document is located. If it is not passed or is empty, it means the root directory.
zh_Hans: 文档所在文件夹的 Token不传或传空表示根目录。
llm_description: 文档所在文件夹的 Token不传或传空表示根目录。
form: llm

View File

@ -0,0 +1,17 @@
from typing import Any
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.utils.feishu_api_utils import FeishuRequest
class GetDocumentRawContentTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
app_id = self.runtime.credentials.get('app_id')
app_secret = self.runtime.credentials.get('app_secret')
client = FeishuRequest(app_id, app_secret)
document_id = tool_parameters.get('document_id')
res = client.get_document_raw_content(document_id)
return self.create_json_message(res)

View File

@ -0,0 +1,23 @@
identity:
name: get_document_raw_content
author: Doug Lea
label:
en_US: Get Document Raw Content
zh_Hans: 获取文档纯文本内容
description:
human:
en_US: Get document raw content
zh_Hans: 获取文档纯文本内容
llm: A tool for getting the plain text content of Feishu documents
parameters:
- name: document_id
type: string
required: true
label:
en_US: document_id
zh_Hans: 飞书文档的唯一标识
human_description:
en_US: Unique ID of Feishu document document_id
zh_Hans: 飞书文档的唯一标识 document_id
llm_description: 飞书文档的唯一标识 document_id
form: llm

View File

@ -0,0 +1,19 @@
from typing import Any
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.utils.feishu_api_utils import FeishuRequest
class ListDocumentBlockTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
app_id = self.runtime.credentials.get('app_id')
app_secret = self.runtime.credentials.get('app_secret')
client = FeishuRequest(app_id, app_secret)
document_id = tool_parameters.get('document_id')
page_size = tool_parameters.get('page_size', 500)
page_token = tool_parameters.get('page_token', '')
res = client.list_document_block(document_id, page_token, page_size)
return self.create_json_message(res)

View File

@ -0,0 +1,48 @@
identity:
name: list_document_block
author: Doug Lea
label:
en_US: List Document Block
zh_Hans: 获取飞书文档所有块
description:
human:
en_US: List document block
zh_Hans: 获取飞书文档所有块的富文本内容并分页返回。
llm: A tool to get all blocks of Feishu documents
parameters:
- name: document_id
type: string
required: true
label:
en_US: document_id
zh_Hans: 飞书文档的唯一标识
human_description:
en_US: Unique ID of Feishu document document_id
zh_Hans: 飞书文档的唯一标识 document_id
llm_description: 飞书文档的唯一标识 document_id
form: llm
- name: page_size
type: number
required: false
default: 500
label:
en_US: page_size
zh_Hans: 分页大小
human_description:
en_US: Paging size, the default and maximum value is 500.
zh_Hans: 分页大小, 默认值和最大值为 500。
llm_description: 分页大小, 表示一次请求最多返回多少条数据,默认值和最大值为 500。
form: llm
- name: page_token
type: string
required: false
label:
en_US: page_token
zh_Hans: 分页标记
human_description:
en_US: Pagination tag, used to paginate query results so that more items can be obtained in the next traversal.
zh_Hans: 分页标记,用于分页查询结果,以便下次遍历时获取更多项。
llm_description: 分页标记,第一次请求不填,表示从头开始遍历;分页查询结果还有更多项时会同时返回新的 page_token下次遍历可采用该 page_token 获取查询结果。
form: llm

View File

@ -0,0 +1,19 @@
from typing import Any
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.utils.feishu_api_utils import FeishuRequest
class CreateDocumentTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
app_id = self.runtime.credentials.get('app_id')
app_secret = self.runtime.credentials.get('app_secret')
client = FeishuRequest(app_id, app_secret)
document_id = tool_parameters.get('document_id')
content = tool_parameters.get('content')
position = tool_parameters.get('position')
res = client.write_document(document_id, content, position)
return self.create_json_message(res)

View File

@ -0,0 +1,56 @@
identity:
name: write_document
author: Doug Lea
label:
en_US: Write Document
zh_Hans: 在飞书文档中新增内容
description:
human:
en_US: Adding new content to Lark documents
zh_Hans: 在飞书文档中新增内容
llm: A tool for adding new content to Lark documents.
parameters:
- name: document_id
type: string
required: true
label:
en_US: document_id
zh_Hans: 飞书文档的唯一标识
human_description:
en_US: Unique ID of Feishu document document_id
zh_Hans: 飞书文档的唯一标识 document_id
llm_description: 飞书文档的唯一标识 document_id
form: llm
- name: content
type: string
required: true
label:
en_US: document content
zh_Hans: 文档内容
human_description:
en_US: Document content, supports markdown syntax, can be empty.
zh_Hans: 文档内容,支持 markdown 语法,可以为空。
llm_description:
form: llm
- name: position
type: select
required: true
default: start
label:
en_US: Choose where to add content
zh_Hans: 选择添加内容的位置
human_description:
en_US: Please fill in start or end to add content at the beginning or end of the document respectively.
zh_Hans: 请填入 start 或 end, 分别表示在文档开头(start)或结尾(end)添加内容。
form: llm
options:
- value: start
label:
en_US: start
zh_Hans: 在文档开头添加内容
- value: end
label:
en_US: end
zh_Hans: 在文档结尾添加内容

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve"> <image id="image0" width="64" height="64" x="0" y="0"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAAIGNIUk0AAHomAACAhAAA+gAAAIDo
AAB1MAAA6mAAADqYAAAXcJy6UTwAAAC9UExURf///////+bs/vL2/qa/+n+j+E1/9TNt9FmI9nOa
+Obt/sza/GaR97PI+9nk/aa/+5m2+oCk+Iyt+Yys+eXt/oCj+L/R+4yt+HOb+Ex/9TOA6jOi2jO8
zTPJxzPWwDOa3eb69zN67X/l2DOb3TPPw0DZxLPv55nq4LPw6DOB6vL9+0B29TOo16bt4zPCynPj
00zbyDN08WbgzzOH50DYxFmI9bLI+5nr34zn3OX699n384zo21ndyzTWwJnq37nAcdIAAAABdFJO
U/4a4wd9AAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAAd0SU1FB+gHEggfEk4D
XiUAAAFOSURBVFjD7dVZU8IwFAXgpq2NtFFRUVTKtYC4gCvu6///WcCMI9Cc3CR2fLLn/XyT3KRp
IComqIEa+GMgDMNfA1G8lsh51htx6g9kSi5HbfgBm6v1eZLUA9iSKE1nYFviqMgNMPVn44xcgB1p
jnIAmpLLrhVoST6ZDdizAMoCZNKWjAdsC8BLWACRtS9lygH7DkDMAW0H4IADlANwyAEJUzzq5F2i
bn5cMIC53svpJ/3CHxic0FKGp75Ah0o585uB1ic69zmFnt6nYQEBfA9yAFDf/SZeEMwIfgtjAFxi
4AoBcA/XGLiBAHoPcJ9uISAaWv/OABAGWuOKgIgrbgHM0TDEiQnQHnavY0Tfwz0GCgMA/kweVxm/
y2gJD4UJQJd5wE6gfIxlIXlsPz1rwIsRwNGFkR8gXicVASHe3j++u5+zfHlugU8N1MD/AQI2U2Cm
Yux2lsz2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI0LTA3LTE4VDA4OjMxOjE4KzAwOjAwPdC6HgAA
ACV0RVh0ZGF0ZTptb2RpZnkAMjAyNC0wNy0xOFQwODozMToxOCswMDowMEyNAqIAAAAodEVYdGRh
dGU6dGltZXN0YW1wADIwMjQtMDctMThUMDg6MzE6MTgrMDA6MDAbmCN9AAAAAElFTkSuQmCC" />
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,15 @@
from core.tools.errors import ToolProviderCredentialValidationError
from core.tools.provider.builtin_tool_provider import BuiltinToolProviderController
from core.tools.utils.feishu_api_utils import FeishuRequest
class FeishuMessageProvider(BuiltinToolProviderController):
def _validate_credentials(self, credentials: dict) -> None:
app_id = credentials.get('app_id')
app_secret = credentials.get('app_secret')
if not app_id or not app_secret:
raise ToolProviderCredentialValidationError("app_id and app_secret is required")
try:
assert FeishuRequest(app_id, app_secret).tenant_access_token is not None
except Exception as e:
raise ToolProviderCredentialValidationError(str(e))

View File

@ -0,0 +1,34 @@
identity:
author: Doug Lea
name: feishu_message
label:
en_US: Lark Message
zh_Hans: 飞书消息
description:
en_US: Lark Message
zh_Hans: 飞书消息
icon: icon.svg
tags:
- social
- productivity
credentials_for_provider:
app_id:
type: text-input
required: true
label:
en_US: APP ID
placeholder:
en_US: Please input your feishu app id
zh_Hans: 请输入你的飞书 app id
help:
en_US: Get your app_id and app_secret from Feishu
zh_Hans: 从飞书获取您的 app_id 和 app_secret
url: https://open.feishu.cn
app_secret:
type: secret-input
required: true
label:
en_US: APP Secret
placeholder:
en_US: Please input your app secret
zh_Hans: 请输入你的飞书 app secret

View File

@ -0,0 +1,20 @@
from typing import Any
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.utils.feishu_api_utils import FeishuRequest
class SendBotMessageTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) -> ToolInvokeMessage:
app_id = self.runtime.credentials.get('app_id')
app_secret = self.runtime.credentials.get('app_secret')
client = FeishuRequest(app_id, app_secret)
receive_id_type = tool_parameters.get('receive_id_type')
receive_id = tool_parameters.get('receive_id')
msg_type = tool_parameters.get('msg_type')
content = tool_parameters.get('content')
res = client.send_bot_message(receive_id_type, receive_id, msg_type, content)
return self.create_json_message(res)

View File

@ -0,0 +1,91 @@
identity:
name: send_bot_message
author: Doug Lea
label:
en_US: Send Bot Message
zh_Hans: 发送飞书应用消息
description:
human:
en_US: Send bot message
zh_Hans: 发送飞书应用消息
llm: A tool for sending Feishu application messages.
parameters:
- name: receive_id_type
type: select
required: true
options:
- value: open_id
label:
en_US: open id
zh_Hans: open id
- value: union_id
label:
en_US: union id
zh_Hans: union id
- value: user_id
label:
en_US: user id
zh_Hans: user id
- value: email
label:
en_US: email
zh_Hans: email
- value: chat_id
label:
en_US: chat id
zh_Hans: chat id
label:
en_US: User ID Type
zh_Hans: 用户 ID 类型
human_description:
en_US: User ID Type
zh_Hans: 用户 ID 类型,可选值有 open_id、union_id、user_id、email、chat_id。
llm_description: 用户 ID 类型,可选值有 open_id、union_id、user_id、email、chat_id。
form: llm
- name: receive_id
type: string
required: true
label:
en_US: Receive Id
zh_Hans: 消息接收者的 ID
human_description:
en_US: The ID of the message receiver. The ID type should correspond to the query parameter receive_id_type.
zh_Hans: 消息接收者的 IDID 类型应与查询参数 receive_id_type 对应。
llm_description: 消息接收者的 IDID 类型应与查询参数 receive_id_type 对应。
form: llm
- name: msg_type
type: string
required: true
options:
- value: text
label:
en_US: text
zh_Hans: 文本
- value: interactive
label:
en_US: message card
zh_Hans: 消息卡片
label:
en_US: Message type
zh_Hans: 消息类型
human_description:
en_US: Message type, optional values are, text (text), interactive (message card).
zh_Hans: 消息类型可选值有text(文本)、interactive(消息卡片)。
llm_description: 消息类型可选值有text(文本)、interactive(消息卡片)。
form: llm
- name: content
type: string
required: true
label:
en_US: Message content
zh_Hans: 消息内容
human_description:
en_US: Message content
zh_Hans: |
消息内容JSON 结构序列化后的字符串。不同 msg_type 对应不同内容,
具体格式说明参考https://open.larkoffice.com/document/server-docs/im-v1/message-content-description/create_json
llm_description: 消息内容JSON 结构序列化后的字符串。不同 msg_type 对应不同内容。
form: llm

View File

@ -0,0 +1,19 @@
from typing import Any
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool
from core.tools.utils.feishu_api_utils import FeishuRequest
class SendWebhookMessageTool(BuiltinTool):
def _invoke(self, user_id: str, tool_parameters: dict[str, Any]) ->ToolInvokeMessage:
app_id = self.runtime.credentials.get('app_id')
app_secret = self.runtime.credentials.get('app_secret')
client = FeishuRequest(app_id, app_secret)
webhook = tool_parameters.get('webhook')
msg_type = tool_parameters.get('msg_type')
content = tool_parameters.get('content')
res = client.send_webhook_message(webhook, msg_type, content)
return self.create_json_message(res)

View File

@ -0,0 +1,58 @@
identity:
name: send_webhook_message
author: Doug Lea
label:
en_US: Send Webhook Message
zh_Hans: 使用自定义机器人发送飞书消息
description:
human:
en_US: Send webhook message
zh_Hans: 使用自定义机器人发送飞书消息
llm: A tool for sending Lark messages using a custom robot.
parameters:
- name: webhook
type: string
required: true
label:
en_US: webhook
zh_Hans: webhook 的地址
human_description:
en_US: The address of the webhook
zh_Hans: webhook 的地址
llm_description: webhook 的地址
form: llm
- name: msg_type
type: string
required: true
options:
- value: text
label:
en_US: text
zh_Hans: 文本
- value: interactive
label:
en_US: message card
zh_Hans: 消息卡片
label:
en_US: Message type
zh_Hans: 消息类型
human_description:
en_US: Message type, optional values are, text (text), interactive (message card).
zh_Hans: 消息类型可选值有text(文本)、interactive(消息卡片)。
llm_description: 消息类型可选值有text(文本)、interactive(消息卡片)。
form: llm
- name: content
type: string
required: true
label:
en_US: Message content
zh_Hans: 消息内容
human_description:
en_US: Message content
zh_Hans: |
消息内容JSON 结构序列化后的字符串。不同 msg_type 对应不同内容,
具体格式说明参考https://open.larkoffice.com/document/server-docs/im-v1/message-content-description/create_json
llm_description: 消息内容JSON 结构序列化后的字符串。不同 msg_type 对应不同内容。
form: llm

View File

@ -0,0 +1,143 @@
import httpx
from extensions.ext_redis import redis_client
class FeishuRequest:
def __init__(self, app_id: str, app_secret: str):
self.app_id = app_id
self.app_secret = app_secret
@property
def tenant_access_token(self):
feishu_tenant_access_token = f"tools:{self.app_id}:feishu_tenant_access_token"
if redis_client.exists(feishu_tenant_access_token):
return redis_client.get(feishu_tenant_access_token).decode()
res = self.get_tenant_access_token(self.app_id, self.app_secret)
redis_client.setex(feishu_tenant_access_token, res.get("expire"), res.get("tenant_access_token"))
return res.get("tenant_access_token")
def _send_request(self, url: str, method: str = "post", require_token: bool = True, payload: dict = None,
params: dict = None):
headers = {
"Content-Type": "application/json",
"user-agent": "Dify",
}
if require_token:
headers["tenant-access-token"] = f"{self.tenant_access_token}"
res = httpx.request(method=method, url=url, headers=headers, json=payload, params=params, timeout=30).json()
if res.get("code") != 0:
raise Exception(res)
return res
def get_tenant_access_token(self, app_id: str, app_secret: str) -> dict:
"""
API url: https://open.feishu.cn/document/server-docs/authentication-management/access-token/tenant_access_token_internal
Example Response:
{
"code": 0,
"msg": "ok",
"tenant_access_token": "t-caecc734c2e3328a62489fe0648c4b98779515d3",
"expire": 7200
}
"""
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/access_token/get_tenant_access_token"
payload = {
"app_id": app_id,
"app_secret": app_secret
}
res = self._send_request(url, require_token=False, payload=payload)
return res
def create_document(self, title: str, content: str, folder_token: str) -> dict:
"""
API url: https://open.larkoffice.com/document/server-docs/docs/docs/docx-v1/document/create
Example Response:
{
"data": {
"title": "title",
"url": "https://svi136aogf123.feishu.cn/docx/VWbvd4fEdoW0WSxaY1McQTz8n7d",
"type": "docx",
"token": "VWbvd4fEdoW0WSxaY1McQTz8n7d"
},
"log_id": "021721281231575fdbddc0200ff00060a9258ec0000103df61b5d",
"code": 0,
"msg": "创建飞书文档成功,请查看"
}
"""
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/create_document"
payload = {
"title": title,
"content": content,
"folder_token": folder_token,
}
res = self._send_request(url, payload=payload)
return res.get("data")
def write_document(self, document_id: str, content: str, position: str = "start") -> dict:
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/write_document"
payload = {
"document_id": document_id,
"content": content,
"position": position
}
res = self._send_request(url, payload=payload)
return res.get("data")
def get_document_raw_content(self, document_id: str) -> dict:
"""
API url: https://open.larkoffice.com/document/server-docs/docs/docs/docx-v1/document/raw_content
Example Response:
{
"code": 0,
"msg": "success",
"data": {
"content": "云文档\n多人实时协同,插入一切元素。不仅是在线文档,更是强大的创作和互动工具\n云文档:专为协作而生\n"
}
}
"""
params = {
"document_id": document_id,
}
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/get_document_raw_content"
res = self._send_request(url, method="get", params=params)
return res.get("data").get("content")
def list_document_block(self, document_id: str, page_token: str, page_size: int = 500) -> dict:
"""
API url: https://open.larkoffice.com/document/server-docs/docs/docs/docx-v1/document/list
"""
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/list_document_block"
params = {
"document_id": document_id,
"page_size": page_size,
"page_token": page_token,
}
res = self._send_request(url, method="get", params=params)
return res.get("data")
def send_bot_message(self, receive_id_type: str, receive_id: str, msg_type: str, content: str) -> dict:
"""
API url: https://open.larkoffice.com/document/server-docs/im-v1/message/create
"""
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/message/send_bot_message"
params = {
"receive_id_type": receive_id_type,
}
payload = {
"receive_id": receive_id,
"msg_type": msg_type,
"content": content,
}
res = self._send_request(url, params=params, payload=payload)
return res.get("data")
def send_webhook_message(self, webhook: str, msg_type: str, content: str) -> dict:
url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/message/send_webhook_message"
payload = {
"webhook": webhook,
"msg_type": msg_type,
"content": content,
}
res = self._send_request(url, require_token=False, payload=payload)
return res