feishu_api.py 6.2 KB

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