From 89ec00e2fb87b086c6c80ad004735e0f9c7ca585 Mon Sep 17 00:00:00 2001 From: InfinityPacer Date: Sat, 30 Mar 2024 16:38:04 +0800 Subject: [PATCH] =?UTF-8?q?feature:=20#125=20=E5=A2=9E=E5=8A=A0=E9=A3=9E?= =?UTF-8?q?=E4=B9=A6=E6=9C=BA=E5=99=A8=E4=BA=BA=E6=B6=88=E6=81=AF=E9=80=9A?= =?UTF-8?q?=E7=9F=A5=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- icons/FeiShu_A.png | Bin 0 -> 13812 bytes package.json | 8 ++ plugins/feishumsg/__init__.py | 263 ++++++++++++++++++++++++++++++++++ 3 files changed, 271 insertions(+) create mode 100644 icons/FeiShu_A.png create mode 100644 plugins/feishumsg/__init__.py diff --git a/icons/FeiShu_A.png b/icons/FeiShu_A.png new file mode 100644 index 0000000000000000000000000000000000000000..c0b0446c8396fbb6cb63bbfd2eab46efac8626cc GIT binary patch literal 13812 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 p`1K$I0{j2?KYaclvi30GP&4 bool: + return self._enabled and (True if self._webhookurl else False) + + @staticmethod + def get_command() -> List[Dict[str, Any]]: + pass + + def get_api(self) -> List[Dict[str, Any]]: + pass + + def get_form(self) -> Tuple[List[dict], Dict[str, Any]]: + """ + 拼装插件配置页面,需要返回两块数据:1、页面配置;2、数据结构 + """ + # 遍历 NotificationType 枚举,生成消息类型选项 + msg_type_options = [] + default_msg_type_values = [] + for item in NotificationType: + msg_type_options.append({ + "title": item.value, + "value": item.name + }) + default_msg_type_values.append(item.name) + return [ + { + 'component': 'VForm', + 'content': [ + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12, + 'md': 6 + }, + 'content': [ + { + 'component': 'VSwitch', + 'props': { + 'model': 'enabled', + 'label': '启用插件', + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'webhookurl', + 'label': 'WebHook地址', + 'placeholder': 'https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxxxxxx', + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12 + }, + 'content': [ + { + 'component': 'VTextField', + 'props': { + 'model': 'secret', + 'label': '密钥', + 'placeholder': '如设置了签名校验,请输入密钥', + } + } + ] + } + ] + }, + { + 'component': 'VRow', + 'content': [ + { + 'component': 'VCol', + 'props': { + 'cols': 12 + }, + 'content': [ + { + 'component': 'VSelect', + 'props': { + 'multiple': True, + 'chips': True, + 'model': 'msgtypes', + 'label': '消息类型', + 'items': msg_type_options + } + } + ] + } + ] + }, + ] + } + ], { + "enabled": False, + 'webhookurl': '', + 'msgtypes': default_msg_type_values, + 'secret': '', + } + + def get_page(self) -> List[dict]: + pass + + @eventmanager.register(EventType.NoticeMessage) + def send(self, event: Event): + """ + 消息发送事件 + """ + if not self.get_state(): + return + + if not event.event_data: + return + + msg_body = event.event_data + # 渠道 + channel = msg_body.get("channel") + if channel: + logger.info(f"channel: {channel} 不进行消息推送") + return + # 类型 + msg_type: NotificationType = msg_body.get("type") + # 标题 + title = msg_body.get("title") + # 文本 + text = msg_body.get("text") + # 图像 + image = msg_body.get("image") + + if not title and not text: + logger.warn("标题和内容不能同时为空") + return + + if (msg_type and self._msgtypes + and msg_type.name not in self._msgtypes): + logger.info(f"消息类型 {msg_type.value} 未开启消息发送") + return + + try: + payload = { + "msg_type": "post", + "content": { + "post": { + "zh_cn": { + "title": title, + "content": [ + [{ + "tag": "text", + "text": text + }] + ] + } + } + } + } + + # 如果存在密钥时,还需要进行签名处理 + if self._secret: + timestamp = str(int(time.time())) + sign = self.gen_sign(timestamp, self._secret) + payload.update({ + "timestamp": timestamp, + "sign": sign + }) + + res = RequestUtils(content_type="application/json").post_res(url=self._webhookurl, json=payload) + if res and res.status_code == 200: + ret_json = res.json() + errno = ret_json.get('code') + error = ret_json.get('msg') + if errno == 0: + logger.info("飞书机器人消息发送成功") + else: + logger.warn(f"飞书机器人消息发送失败,错误码:{errno},错误原因:{error}") + elif res is not None: + logger.warn(f"飞书机器人消息发送失败,错误码:{res.status_code},错误原因:{res.reason}") + else: + logger.warn("飞书机器人消息发送失败,未获取到返回信息") + except Exception as msg_e: + logger.error(f"飞书机器人消息发送失败,{str(msg_e)}") + + def stop_service(self): + """ + 退出插件 + """ + pass + + @staticmethod + def gen_sign(timestamp, secret): + # 拼接timestamp和secret + string_to_sign = '{}\n{}'.format(timestamp, secret) + hmac_code = hmac.new(string_to_sign.encode("utf-8"), digestmod=hashlib.sha256).digest() + # 对结果进行base64处理 + sign = base64.b64encode(hmac_code).decode('utf-8') + return sign