feishu_api.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import json
  2. import requests
  3. class Feishu:
  4. # 服务号分组群发监测机器人
  5. server_account_publish_monitor_bot = "https://open.feishu.cn/open-apis/bot/v2/hook/380fdecf-402e-4426-85b6-7d9dbd2a9f59"
  6. # 外部服务号投流监测机器人
  7. outside_gzh_monitor_bot = "https://open.feishu.cn/open-apis/bot/v2/hook/0899d43d-9f65-48ce-a419-f83ac935bf59"
  8. # 长文 daily 报警机器人
  9. # long_articles_bot = "https://open.feishu.cn/open-apis/bot/v2/hook/b44333f2-16c0-4cb1-af01-d135f8704410"
  10. long_articles_bot = "https://open.feishu.cn/open-apis/bot/v2/hook/223b3d72-f2e8-40e0-9b53-6956e0ae7158"
  11. # 测试环境报警机器人
  12. long_articles_bot_dev = "https://open.feishu.cn/open-apis/bot/v2/hook/f32c0456-847f-41f3-97db-33fcc1616bcd"
  13. def __init__(self):
  14. self.token = None
  15. self.headers = {"Content-Type": "application/json"}
  16. self.mention_all = {
  17. "content": "<at id=all></at>\n",
  18. "tag": "lark_md",
  19. }
  20. self.not_mention = {}
  21. def fetch_token(self):
  22. url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/"
  23. post_data = {
  24. "app_id": "cli_a51114cf8bf8d00c",
  25. "app_secret": "cNoTAqMpsAm7mPBcpCAXFfvOzCNL27fe",
  26. }
  27. response = requests.request("POST", url=url, data=post_data)
  28. tenant_access_token = response.json()["tenant_access_token"]
  29. self.token = tenant_access_token
  30. class FeishuSheetApi(Feishu):
  31. def prepend_value(self, sheet_token, sheet_id, ranges, values):
  32. insert_value_url = "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{}/values_prepend".format(
  33. sheet_token
  34. )
  35. headers = {
  36. "Authorization": "Bearer " + self.token,
  37. "contentType": "application/json; charset=utf-8",
  38. }
  39. body = {
  40. "valueRange": {"range": "{}!{}".format(sheet_id, ranges), "values": values}
  41. }
  42. response = requests.request(
  43. "POST", url=insert_value_url, headers=headers, json=body
  44. )
  45. print(response.json())
  46. def insert_value(self, sheet_token, sheet_id, ranges, values):
  47. insert_value_url = (
  48. "https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{}/values".format(
  49. sheet_token
  50. )
  51. )
  52. headers = {
  53. "Authorization": "Bearer " + self.token,
  54. "contentType": "application/json; charset=utf-8",
  55. }
  56. body = {
  57. "valueRange": {"range": "{}!{}".format(sheet_id, ranges), "values": values}
  58. }
  59. response = requests.request(
  60. "PUT", url=insert_value_url, headers=headers, json=body
  61. )
  62. print(response.json())
  63. class FeishuBotApi(Feishu):
  64. @classmethod
  65. def create_feishu_columns_sheet(
  66. cls,
  67. sheet_type,
  68. sheet_name,
  69. display_name,
  70. width="auto",
  71. vertical_align="top",
  72. horizontal_align="left",
  73. number_format=None,
  74. ):
  75. match sheet_type:
  76. case "plain_text":
  77. return {
  78. "name": sheet_name,
  79. "display_name": display_name,
  80. "width": width,
  81. "data_type": "text",
  82. "vertical_align": vertical_align,
  83. "horizontal_align": horizontal_align,
  84. }
  85. case "lark_md":
  86. return {
  87. "name": sheet_name,
  88. "display_name": display_name,
  89. "data_type": "lark_md",
  90. }
  91. case "number":
  92. return {
  93. "name": sheet_name,
  94. "display_name": display_name,
  95. "data_type": "number",
  96. "format": number_format,
  97. "width": width,
  98. }
  99. case "date":
  100. return {
  101. "name": sheet_name,
  102. "display_name": display_name,
  103. "data_type": "date",
  104. "date_format": "YYYY/MM/DD",
  105. }
  106. case "options":
  107. return {
  108. "name": sheet_name,
  109. "display_name": display_name,
  110. "data_type": "options",
  111. }
  112. case _:
  113. return {
  114. "name": sheet_name,
  115. "display_name": display_name,
  116. "width": width,
  117. "data_type": "text",
  118. "vertical_align": vertical_align,
  119. "horizontal_align": horizontal_align,
  120. }
  121. # 表格形式
  122. def create_feishu_table(self, title, columns, rows, mention):
  123. table_base = {
  124. "header": {
  125. "template": "blue",
  126. "title": {"content": title, "tag": "plain_text"},
  127. },
  128. "elements": [
  129. self.mention_all if mention else self.not_mention,
  130. {
  131. "tag": "table",
  132. "page_size": len(rows) + 1,
  133. "row_height": "low",
  134. "header_style": {
  135. "text_align": "left",
  136. "text_size": "normal",
  137. "background_style": "grey",
  138. "text_color": "default",
  139. "bold": True,
  140. "lines": 1,
  141. },
  142. "columns": columns,
  143. "rows": rows,
  144. },
  145. ],
  146. }
  147. return table_base
  148. def create_feishu_bot_obj(self, title, mention, detail):
  149. """
  150. create feishu bot object
  151. """
  152. return {
  153. "elements": [
  154. {
  155. "tag": "div",
  156. "text": self.mention_all if mention else self.not_mention,
  157. },
  158. {
  159. "tag": "div",
  160. "text": {
  161. "content": json.dumps(detail, ensure_ascii=False, indent=4),
  162. "tag": "lark_md",
  163. },
  164. },
  165. ],
  166. "header": {"title": {"content": title, "tag": "plain_text"}},
  167. }
  168. # bot
  169. def bot(self, title, detail, mention=True, table=False, env="prod"):
  170. match env:
  171. case "dev":
  172. url = self.long_articles_bot_dev
  173. case "prod":
  174. url = self.long_articles_bot
  175. case "outside_gzh_monitor":
  176. url = self.outside_gzh_monitor_bot
  177. case "server_account_publish_monitor":
  178. url = self.server_account_publish_monitor_bot
  179. case _:
  180. url = self.long_articles_bot_dev
  181. headers = {"Content-Type": "application/json"}
  182. if table:
  183. card = self.create_feishu_table(
  184. title=title,
  185. columns=detail["columns"],
  186. rows=detail["rows"],
  187. mention=mention,
  188. )
  189. else:
  190. card = self.create_feishu_bot_obj(
  191. title=title, mention=mention, detail=detail
  192. )
  193. payload = {"msg_type": "interactive", "card": card}
  194. res = requests.request(
  195. "POST", url=url, headers=headers, data=json.dumps(payload), timeout=10
  196. )
  197. return res