企微内部应用发消息,和向客户发消息是两套逻辑。内部应用面向的是企业成员,消息类型更丰富,支持卡片、按钮、跳转链接。这篇讲清楚内部应用消息怎么发。先分清内部应用和外部联系人内部应用消息发给的是企业成员(员工),不是外部客户。成员的标识是uin(int64),和外部客户的 uin 范围不同。发送接口还是message/sendText,但conversationId指向的是成员的单聊会话。关键问题变成:怎么从成员 uin 拿到单聊会话 id。从成员到会话没有"给 uin 返回会话 id"的直接接口。实际做法:本地缓存:之前发过消息,会话 id 已存历史消息捞:调message/getHistoryMessageList传 uin,挑messageType=0的记录def get_conv_id(uin): cached = redis.get(f"conv:{uin}") if cached: return int(cached) resp = call("message", "getHistoryMessageList", {"uin": uin}) for item in resp["data"]["list"]: if item["messageType"] == 0: redis.set(f"conv:{uin}", item["conversationId"]) return item["conversationId"] return None发文本消息拿到会话 id 后发文本:resp = requests.post( f"{BASE}/wx-api/api/message/sendText", headers=HEADERS, json={ "appid": APPID, "conversationId": conv_id, "content": "审批已通过,请查收", } )发卡片消息企微的卡片消息比纯文本体验好得多。支持标题、摘要、封面图、跳转链接:content = { "title": "新工单提醒", "description": "您有一条新工单待处理", "url": "https://your-system.com/ticket/123", "picurl": "https://cdn.example.com/cover.png", } resp = requests.post( f"{BASE}/wx-api/api/message/sendRichText", headers=HEADERS, json={"appid": APPID, "conversationId": conv_id, "content": content} )卡片消息的字段和企微后台的"应用消息"格式对应,url是点击跳转的地址。批量发送向多个成员发同一条消息,循环调单发接口:def batch_send(uins, content): for uin in uins: conv_id = get_conv_id(uin) if conv_id: send_text(conv_id, content)注意限流。批量发送时加间隔,或提前预热好所有会话 id。发送回执消息发出去后,调message/getMessageReceipt查送达状态:resp = call("message", "getMessageReceipt", {"msgId": msg_id}) # 返回里带 status 字段回执用于确认消息真的到了,重要通知建议核对。内部应用消息的典型场景场景消息类型说明审批结果通知卡片带跳转链接,点进去看详情工单派单富文本高亮工单号、优先级日报提醒文本简单直接系统告警富文本红色高亮关键指标小结内部应用消息的核心是"从成员到会话"这一步。会话 id 拿到后,文本、卡片、富文本都是同一个接口的不同参数。批量发送时注意限流,重要消息核对回执。接口用的是Eyun 平台的企业微信 API,路径统一是/wx-api/api/<模块>/<动作>,鉴权Bearer eyk_xxxx。凭证在官网开通实例时拿到,消息类型和字段在开发文档里有完整说明。
企微内部应用发消息,和向客户发消息是两套逻辑。内部应用面向的是企业成员,消息类型更丰富,支持卡片、按钮、跳转链接。这篇讲清楚内部应用消息怎么发。先分清内部应用和外部联系人内部应用消息发给的是企业成员(员工),不是外部客户。成员的标识是uin(int64),和外部客户的 uin 范围不同。发送接口还是message/sendText,但conversationId指向的是成员的单聊会话。关键问题变成:怎么从成员 uin 拿到单聊会话 id。从成员到会话没有"给 uin 返回会话 id"的直接接口。实际做法:本地缓存:之前发过消息,会话 id 已存历史消息捞:调message/getHistoryMessageList传 uin,挑messageType=0的记录def get_conv_id(uin): cached = redis.get(f"conv:{uin}") if cached: return int(cached) resp = call("message", "getHistoryMessageList", {"uin": uin}) for item in resp["data"]["list"]: if item["messageType"] == 0: redis.set(f"conv:{uin}", item["conversationId"]) return item["conversationId"] return None发文本消息拿到会话 id 后发文本:resp = requests.post( f"{BASE}/wx-api/api/message/sendText", headers=HEADERS, json={ "appid": APPID, "conversationId": conv_id, "content": "审批已通过,请查收", } )发卡片消息企微的卡片消息比纯文本体验好得多。支持标题、摘要、封面图、跳转链接:content = { "title": "新工单提醒", "description": "您有一条新工单待处理", "url": "https://your-system.com/ticket/123", "picurl": "https://cdn.example.com/cover.png", } resp = requests.post( f"{BASE}/wx-api/api/message/sendRichText", headers=HEADERS, json={"appid": APPID, "conversationId": conv_id, "content": content} )卡片消息的字段和企微后台的"应用消息"格式对应,url是点击跳转的地址。批量发送向多个成员发同一条消息,循环调单发接口:def batch_send(uins, content): for uin in uins: conv_id = get_conv_id(uin) if conv_id: send_text(conv_id, content)注意限流。批量发送时加间隔,或提前预热好所有会话 id。发送回执消息发出去后,调message/getMessageReceipt查送达状态:resp = call("message", "getMessageReceipt", {"msgId": msg_id}) # 返回里带 status 字段回执用于确认消息真的到了,重要通知建议核对。内部应用消息的典型场景场景消息类型说明审批结果通知卡片带跳转链接,点进去看详情工单派单富文本高亮工单号、优先级日报提醒文本简单直接系统告警富文本红色高亮关键指标小结内部应用消息的核心是"从成员到会话"这一步。会话 id 拿到后,文本、卡片、富文本都是同一个接口的不同参数。批量发送时注意限流,重要消息核对回执。接口用的是Eyun 平台的企业微信 API,路径统一是/wx-api/api/<模块>/<动作>,鉴权Bearer eyk_xxxx。凭证在官网开通实例时拿到,消息类型和字段在开发文档里有完整说明。