头图

前言

在现代企业运作中,及时响应告警信息对保障系统的稳定性和业务的连续性至关重要。随着业务的数字化转型,越来越多的企业依赖于复杂的技术架构,这使得故障和异常事件的及时处理变得愈发重要。传统的告警通知方式往往存在响应不及时、信息传递不准确等问题,导致潜在风险未能及时识别和处理。

为了解决这些问题,我们借助飞书应用的强大功能,开发了一种新的告警消息发送机制。该机制不仅能够将告警信息迅速传递给指定的接收人,还可以根据事件的紧急程度实现加急处理。这一功能的实现,不仅提升了告警处理的效率,还增强了团队协作,确保关键事件能够在第一时间获得关注和解决。

在接下来的文章中,我们将详细介绍如何通过飞书应用实现这一功能,包括技术实现、代码示例以及应用场景分析。希望能够为广大开发者和运维人员提供实用的参考和指导。

前置条件

如需实现飞书应用告警,首先我们需要为观测云通知到用户配置一个飞书应用。该配置是在飞书应用后台完成创建,首先我们需要登录飞书后台并使用飞书账号登录。

创建新应用

  • 进入飞书开发者控制台后,点击左侧菜单中的“应用管理”。
  • 点击右上角的“创建应用”按钮。
  • 在弹出的窗口中,输入应用的名称、图标和描述,然后点击“创建”。

图片

配置应用信息

在应用设置页面,可以编辑应用的基本信息,如名称、描述和图标。之后点击“权限管理”选项卡,选择您的应用所需的权限。例如,发送消息、获取用户信息等。并确保选择的权限符合您的应用需求,并点击“保存”。

图片

图片

配置应用的安全设置

在“安全设置”选项卡中设置应用的密钥和其他安全参数。注意需要记录下应用的 App ID 和 App Secret,后续开发调用时需要用到这两个字段。

图片

提交审核

当您完成所有配置后,点击“提交审核”按钮。按照系统提示填写审核信息,确保信息准确无误。提交后,等待后台管理员的审核。这个审核完成后就可以实现应用上线。点击“上线”按钮,将应用发布到飞书平台。

管理应用权限

如需通过 Func 平台正确发送消息到飞书平台,您需要为这个应用开启"获取用户 user_id"、"通过手机号或邮箱获取用户 ID"、"获取与发送单聊、群组消息"、"以应用的身份发消息"、"发送应用内加急消息"这几个权限。如果没有这些权限,在消息完成发送后 Func 脚本无法基于返回的消息对指定用户进行加急。

Func 脚本开发

发送前准备

在向指定用户发送消息前,需要首先获取飞书应用的相关访问权限,获取租户 token 的接口如下:

AUTH_TOKEN_URL="https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"

def _get_feishu_tenant_token():
    body = {
        "app_id": "cli_<your-app-id>",
        "app_secret": "<your-app-secret>"
    }

    rsp = _send_post_request(AUTH_TOKEN_URL,json=body,headers=HEADERS)
    print(rsp.text)
    return json.loads(rsp.text).get("tenant_access_token")

接口响应体说明:

名称类型描述
codeint错误码,0 表示成功,非 0 表示失败
msgstring错误描述
tenant_access_tokenstring获取的 Tenant Access Token,有效期为 2 小时
expireintToken 的有效期,单位为秒

这个接口需要使用我们上面申请创建应用时保存的 app_id 和 app_secret 用作请求体。平台会在调用接口后返回对应应用的租户 token,用于发起下面的获取用户信息请求。

获取用户信息请求的接口如下:

GET_USER_FEISHU_OPENID="https://open.feishu.cn/open-apis/contact/v3/users/batch_get_id"

def _get_feishu_user_open_id(t_token):
    headers = HEADERS
    headers['Authorization'] = "Bearer "+t_token

    print(headers)
    body = {
        "user_id_type":"open_id",
        "emails": [
            "your_employee@somesite.com"
        ],
        "include_resigned":False
    }
    rsp = _send_post_request(GET_USER_FEISHU_OPENID,json=body,headers=headers)
    print(rsp.text)

接口响应体说明:

名称类型描述
codeint错误码,非 0 表示失败
msgstring错误描述
data--
user_listuser_contact_info[]手机号或者邮箱对应的用户 ID 信息。
- user_idstring用户 ID,ID 类型与查询参数 user_id_type 的取值保持一致。例如,user_id_type 取值为 open_id,则该参数的用户 ID 值为用户的 open_id。
- mobilestring手机号,通过手机号查询时会返回该值。
- emailstring邮箱,通过邮箱查询时会返回该值。

获取到用户信息后,我们将比对观测云告警消息中收到的用户列表,在上述用户元数据中获取对应的 open_id,发起本次消息加急通知。

消息发送接口

完成用户信息的发送前准备后,调用飞书的发送消息接口,首先生成本次需要发送的告警消息。

SEND_MESSAGE_TO_USER="https://open.feishu.cn/open-apis/im/v1/messages"

def send_feishu_messages(open_id,t_token,alart_message):
    url = SEND_MESSAGE_TO_USER

    headers = HEADERS
    headers['Authorization'] = "Bearer "+t_token

    # 设置查询参数
    params = {
        'receive_id_type': 'open_id',
    }

    # 设置请求体
    body = {
        'receive_id': open_id,
        'msg_type': 'text',
        'content':alart_message
    }

    # 发起 POST 请求
    response = requests.post(
        url,
        headers=headers,
        params=params,
        json=body  # 使用 json 参数来发送请求体
    )

    # 检查响应状态码
    if response.status_code == 0:
        # 请求成功,处理响应
        print(data)
        return response.get("data").get("message_id")
    else:
        # 请求失败,输出错误信息
        print(f'Error: {response.status_code}, {response.text}')
        return None

接口参数如下:

名称类型必填描述
receive_idstring消息接收者的 ID,ID 类型与查询参数 receive_id_type 的取值一致。注意事项:给用户发送消息时,用户需要在机器人的可用范围内。例如,你需要给企业全员发送消息,则需要将应用的可用范围设置为全体员工。给群组发送消息时,机器人需要在该群组中,且在群组内拥有发言权限。如果消息接收者为用户,推荐使用用户的 open_id。示例值:"ou_7d8a6e6df7621556ce0d21922b676706ccs"
msg_typestring消息类型。可选值有:
-text:文本
-post:富文本
-image:图片
-file:文件
-audio:语音
-media:视频
-sticker:表情包
-interactive:卡片
-share_chat:分享群名片
-share_user:分享个人名片
-system:系统消息
contentstring消息内容,JSON 结构序列化后的字符串。该参数的取值与 msg_type 对应,例如 msg_type 取值为 text,则该参数需要传入文本类型的内容。
注意:
1、JSON 字符串需进行转义。例如,换行符 \n 转义后为 \n。文本消息请求体最大不能超过 150 KB。
2、卡片消息、富文本消息请求体最大不能超过 30 KB。如果使用卡片模板(template_id)发送消息,实际大小也包含模板对应的卡片数据大小。
3、如果消息中包含样式标签,会使实际消息体长度大于您输入的请求体长度。图片需要先上传图片,然后使用图片的 Key 发消息。音频、视频、文件需要先上传文件,然后使用文件的 Key 发消息。

需要注意的是,如您希望重新组织飞书消息通知的卡片格式,例如输出为富文本方式,则需要首先将观测云告警消息清洗为富文本格式,再传递给对应的参数。

应用内消息加急接口

消息发送成功并获取到消息回执的id后,就可以进一步启用应用内消息加急了。这里需要调用的接口和调用方式示例如下。该接口的调用,需要将刚刚获取的消息 id 作为路径参数的一部分,添加到 url 中。这和之前的接口增加为请求参数的方式不一样,使用的时候请注意。

SEND_MESSAGE_URGENT_TIP="https://open.feishu.cn/open-apis/im/v1/messages/{}/urgent_app"

def send_alart_message(message_id,t_token,u_id_list):
    url = SEND_MESSAGE_URGENT_TIP.format(message_id)

    headers = HEADERS
    headers['Authorization'] = "Bearer "+t_token

    # 设置查询参数
    params = {
        'user_id_type': 'open_id',
    }

    # 设置请求体
    body = {
        'user_id_list': u_id_list,
    }
    
    # 发起 POST 请求
    response = requests.post(
        url,
        headers=headers,
        params=params,
        json=body  # 使用 json 参数来发送请求体
    )

    # 检查响应状态码
    if response.status_code == 0:
        # 请求成功,处理响应
        print(data)
        return response.get("data").get("message_id")
    else:
        # 请求失败,输出错误信息
        print(f'Error: {response.status_code}, {response.text}')
        return None

接口发布

在 Func 平台中,点击「管理」-「同步 API」,将上述开发的飞书消息加急接口发布为 webhook,该接口最终提供给工作空间进行调用,将收到的告警信息转换为飞书加急消息。

图片

工作空间配置

登录工作空间,在「告警」-「通知对象管理」中增加创建一个通知通道,将上面发布的 Webhook 地址填写到工作空间中形成一个新的通知通道。在该通道的成员中,填写当前消息加急需要通知的人员,需要注意的是这里的人员信息应至少包含飞书邮箱或手机等联系方式中的一个,否则 Func 接口将无法匹配需要加急的人员。

图片

完成配置后就可以在告警监控器的配置中使用该通道,对相应的告警信息进行加急发送了。发送效果如下:

图片

需要注意的是,应用机器人仅能对自身发布的消息进行加急,因此请务必使用webhook类通知对象,通过Func发布的飞书消息加急接口进行告警消息的发送和加急操作。

总结

通过观测云 DataFlux Func 可观测开发平台,我们可以灵活的将观测云包括告警在内的各种功能,同外部第三方系统进行对接,实现观测云功能的扩展。


观测云
21 声望86 粉丝

云时代的系统可观测平台