feishu_api_utils.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import httpx
  2. from extensions.ext_redis import redis_client
  3. class FeishuRequest:
  4. def __init__(self, app_id: str, app_secret: str):
  5. self.app_id = app_id
  6. self.app_secret = app_secret
  7. @property
  8. def tenant_access_token(self):
  9. feishu_tenant_access_token = f"tools:{self.app_id}:feishu_tenant_access_token"
  10. if redis_client.exists(feishu_tenant_access_token):
  11. return redis_client.get(feishu_tenant_access_token).decode()
  12. res = self.get_tenant_access_token(self.app_id, self.app_secret)
  13. redis_client.setex(feishu_tenant_access_token, res.get("expire"), res.get("tenant_access_token"))
  14. return res.get("tenant_access_token")
  15. def _send_request(
  16. self, url: str, method: str = "post", require_token: bool = True, payload: dict = None, params: dict = None
  17. ):
  18. headers = {
  19. "Content-Type": "application/json",
  20. "user-agent": "Dify",
  21. }
  22. if require_token:
  23. headers["tenant-access-token"] = f"{self.tenant_access_token}"
  24. res = httpx.request(method=method, url=url, headers=headers, json=payload, params=params, timeout=30).json()
  25. if res.get("code") != 0:
  26. raise Exception(res)
  27. return res
  28. def get_tenant_access_token(self, app_id: str, app_secret: str) -> dict:
  29. """
  30. API url: https://open.feishu.cn/document/server-docs/authentication-management/access-token/tenant_access_token_internal
  31. Example Response:
  32. {
  33. "code": 0,
  34. "msg": "ok",
  35. "tenant_access_token": "t-caecc734c2e3328a62489fe0648c4b98779515d3",
  36. "expire": 7200
  37. }
  38. """
  39. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/access_token/get_tenant_access_token"
  40. payload = {"app_id": app_id, "app_secret": app_secret}
  41. res = self._send_request(url, require_token=False, payload=payload)
  42. return res
  43. def create_document(self, title: str, content: str, folder_token: str) -> dict:
  44. """
  45. API url: https://open.larkoffice.com/document/server-docs/docs/docs/docx-v1/document/create
  46. Example Response:
  47. {
  48. "data": {
  49. "title": "title",
  50. "url": "https://svi136aogf123.feishu.cn/docx/VWbvd4fEdoW0WSxaY1McQTz8n7d",
  51. "type": "docx",
  52. "token": "VWbvd4fEdoW0WSxaY1McQTz8n7d"
  53. },
  54. "log_id": "021721281231575fdbddc0200ff00060a9258ec0000103df61b5d",
  55. "code": 0,
  56. "msg": "创建飞书文档成功,请查看"
  57. }
  58. """
  59. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/create_document"
  60. payload = {
  61. "title": title,
  62. "content": content,
  63. "folder_token": folder_token,
  64. }
  65. res = self._send_request(url, payload=payload)
  66. return res.get("data")
  67. def write_document(self, document_id: str, content: str, position: str = "start") -> dict:
  68. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/write_document"
  69. payload = {"document_id": document_id, "content": content, "position": position}
  70. res = self._send_request(url, payload=payload)
  71. return res.get("data")
  72. def get_document_raw_content(self, document_id: str) -> dict:
  73. """
  74. API url: https://open.larkoffice.com/document/server-docs/docs/docs/docx-v1/document/raw_content
  75. Example Response:
  76. {
  77. "code": 0,
  78. "msg": "success",
  79. "data": {
  80. "content": "云文档\n多人实时协同,插入一切元素。不仅是在线文档,更是强大的创作和互动工具\n云文档:专为协作而生\n"
  81. }
  82. }
  83. """ # noqa: E501
  84. params = {
  85. "document_id": document_id,
  86. }
  87. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/get_document_raw_content"
  88. res = self._send_request(url, method="get", params=params)
  89. return res.get("data").get("content")
  90. def list_document_block(self, document_id: str, page_token: str, page_size: int = 500) -> dict:
  91. """
  92. API url: https://open.larkoffice.com/document/server-docs/docs/docs/docx-v1/document/list
  93. """
  94. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/document/list_document_block"
  95. params = {
  96. "document_id": document_id,
  97. "page_size": page_size,
  98. "page_token": page_token,
  99. }
  100. res = self._send_request(url, method="get", params=params)
  101. return res.get("data")
  102. def send_bot_message(self, receive_id_type: str, receive_id: str, msg_type: str, content: str) -> dict:
  103. """
  104. API url: https://open.larkoffice.com/document/server-docs/im-v1/message/create
  105. """
  106. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/message/send_bot_message"
  107. params = {
  108. "receive_id_type": receive_id_type,
  109. }
  110. payload = {
  111. "receive_id": receive_id,
  112. "msg_type": msg_type,
  113. "content": content,
  114. }
  115. res = self._send_request(url, params=params, payload=payload)
  116. return res.get("data")
  117. def send_webhook_message(self, webhook: str, msg_type: str, content: str) -> dict:
  118. url = "https://lark-plugin-api.solutionsuite.cn/lark-plugin/message/send_webhook_message"
  119. payload = {
  120. "webhook": webhook,
  121. "msg_type": msg_type,
  122. "content": content,
  123. }
  124. res = self._send_request(url, require_token=False, payload=payload)
  125. return res