从python应用app向微软Microsoft Teams Channel发送消息message

一、简介

有这样的需求,web app需要提供功能可以发送消息到Teams来提醒用户。所以需要将发消息到Teams功能集成到web app中。由于我们的web app是python开发的,所以使用pyteams库。

先看效果:有标题、内容、链接、@用户

二、步骤

2.1 首先在Teams channel中建一个webhook

直接参考官方文档:Create an Incoming Webhook - Teams | Microsoft Learn

建好之后把webhook的url复制保存好,这个url用来发送消息到指定的Teams channel

2.2 然后在web app中写代码来实现发送消息功能

参考pyteams官方文档,用法很简单:

​​​​​pymsteams · PyPI / ​​​​​​​https://github.com/rveachkc/pymsteams

这个库虽然用起来很方便,但没有提供一个统一的类来实现我的一些需求,需要写繁琐的代码。因此我对这个库做了二次封装,可以轻松实现发送消息(标题、正文、链接、@某人等)

代码如下:这个模块可以命名为messenger.py

python 复制代码
from pymsteams import connectorcard, TeamsWebhookException
import logging
from typing import List, Optional
import copy
from pydantic import BaseModel

# 初始化日志记录
logger = logging.getLogger(__name__)

# 定义发送到Teams的默认消息有效载荷模板
DEFAULT_PAYLOAD_TEMPLATE = {
    "type": "message",
    "attachments": [
        {
            "contentType": "application/vnd.microsoft.card.adaptive",
            "content": {
                "type": "AdaptiveCard",
                "body": [],
                "actions": [],
                "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                "version": "1.0",
                "msteams": {"width": "Full"}
            }
        }]
}


class User(BaseModel):
    """
    用户类,表示要在消息中提及的用户,具有可选的电子邮件和OID字段
    """
    name: str
    email: Optional[str] = ""
    oid: Optional[str] = ""


class MessageDTO(BaseModel):
    """
    MessageDTO类是数据传输对象,用于封装消息的详细信息
    """
    text: str
    title: Optional[str] = None
    mention_users: Optional[List[User]] = None
    link_title: Optional[str] = None
    link_url: Optional[str] = None


class TeamsMessenger:
    """
    Microsoft Teams的Messenger实现
    """

    def __init__(self, webhook_url, messageDTO: MessageDTO):
        self.messageDTO = messageDTO
        self.my_messenger = connectorcard(hookurl=webhook_url)  # 使用Webhook URL初始化Teams连接器

    def send_message(self):
        """构造并发送消息到Teams,使用连接卡"""
        try:
            # 初始化默认有效载荷模板
            self.my_messenger.payload = copy.deepcopy(DEFAULT_PAYLOAD_TEMPLATE)

            # 添加消息标题(如果提供)
            if self.messageDTO.title:
                self.my_messenger.payload["attachments"][0]["content"]["body"].append({
                    "type": "TextBlock",
                    "size": "Large",
                    "weight": "Bolder",
                    "text": self.messageDTO.title
                })

            # 添加消息文本
            self.my_messenger.payload["attachments"][0]["content"]["body"].append({
                "type": "TextBlock",
                "size": "Medium",
                "text": self.messageDTO.text,
                "wrap": True
            })

            # 根据提供的用户添加提及
            if self.messageDTO.mention_users:
                mentions_entities = []  # 存储提及实体的列表
                mention_text = ""  # 累积用于在消息中显示的提及文本

                for mention_user in self.messageDTO.mention_users:
                    mentions_entities.append({
                        "type": "mention",
                        "text": f"<at>{mention_user.name}</at>",  # 使用markdown格式进行提及
                        "mentioned": {
                            "id": mention_user.email,  # 用户的标识符(假定为电子邮件)
                            "name": mention_user.name
                        }
                    })

                    # 格式化提及文本
                    mention_text += f"@<at>{mention_user.name}</at> "
                self.my_messenger.payload["attachments"][0]["content"]["body"].append({
                    "type": "TextBlock",
                    "text": mention_text
                })
                self.my_messenger.payload["attachments"][0]["content"]["msteams"]["entities"] = mentions_entities

            # 如果提供了标题和链接,则添加操作链接
            if self.messageDTO.link_title and self.messageDTO.link_url:
                self.my_messenger.payload["attachments"][0]["content"]["actions"].append({
                    "type": "Action.OpenUrl",
                    "title": self.messageDTO.link_title,
                    "url": self.messageDTO.link_url
                })

            # 发送构造的消息到Microsoft Teams
            self.my_messenger.send()

        except TeamsWebhookException as e:  # 处理特定的Teams Webhook异常
            logger.error(f"发送Teams消息时发生错误。 {e}")

        except Exception as e:  # 处理其他任何异常
            logger.error(f"处理发送Teams消息时发生错误。 {e}")

调用时,只需要初始化messenger这个类,然后就可以轻松调用了。示例如下:

python 复制代码
from msteams.messenger import TeamsMessenger, MessageDTO, User  # 导入TeamsMessenger、MessageDTO和User类  

if __name__ == '__main__':  
    TEST_MESSENGER_WEBHOOK_URL = "你的webhook url"  # 设置测试用的Webhook URL  

    # 创建MessageDTO实例,用于封装要发送的消息内容  
    messageDTO = MessageDTO(  
        title="This is title",  # 消息标题  
        text="This is content",  # 消息内容  
        link_title="Visit xxx",  # 链接标题  
        link_url="xxx",          # 链接URL  
        mention_users=[User(name="lerry", email="xxx")]  # 提及的用户列表,这里包含一个用户  
    )  

    # 创建TeamsMessenger实例,传入Webhook URL和消息DTO  
    my_messenger = TeamsMessenger(webhook_url=TEST_MESSENGER_WEBHOOK_URL,  
                                  messageDTO=messageDTO)  

    # 发送消息  
    my_messenger.send_message()

三、总结

本文基于python应用和Teams工具,实现了发送消息到Teams的功能,对pyteams进行了二次封装,如果可能的话,有考虑把这个封装模块贡献到pyteams仓库。

相关推荐
数据智能老司机35 分钟前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机2 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机2 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机2 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
c8i2 小时前
drf初步梳理
python·django
每日AI新事件2 小时前
python的异步函数
python
这里有鱼汤3 小时前
miniQMT下载历史行情数据太慢怎么办?一招提速10倍!
前端·python
databook12 小时前
Manim实现脉冲闪烁特效
后端·python·动效
程序设计实验室12 小时前
2025年了,在 Django 之外,Python Web 框架还能怎么选?
python
倔强青铜三14 小时前
苦练Python第46天:文件写入与上下文管理器
人工智能·python·面试