以下是针对前文《【高精度监控】C#上位机开发实战:多设备联动与日志存储》中实时报警机制的企业微信推送实现完整扩展方案。
企业微信推送在工业上位机场景中非常实用,常用于:
- 严重/急停报警即时通知运维人员
- 夜间无人值守时的关键异常提醒
- 生产报表/日报自动推送给管理层
1. 方案对比(2025–2026 年主流方式)
| 方式 | 优点 | 缺点 | 推荐场景 | 开发难度 |
|---|---|---|---|---|
| 企业微信群机器人(Webhook) | 最简单、无需认证、最快上线 | 只能发群消息、样式较简单 | 车间/值班群报警推送 | ★☆☆☆☆ |
| 企业微信应用消息(API) | 支持个人/群/部门、富文本、卡片 | 需要创建应用 + Secret + AccessToken | 精准推送给特定人员/角色 | ★★★☆☆ |
| 企业微信客服消息 | 支持会话式交互、历史记录 | 主要用于客服场景,不适合报警 | 不推荐 | — |
| 第三方平台(飞书/钉钉桥接) | 一套代码多平台 | 增加依赖、延迟可能更高 | 多平台统一推送需求 | ★★☆☆☆ |
工业监控推荐:企业微信群机器人(Webhook)(最稳、最快、最低成本),严重报警再结合应用消息精准推送给负责人。
2. 企业微信群机器人推送(最常用方式)
步骤1:创建群机器人
- 打开企业微信 → 群聊 → 右键群 → 添加群机器人
- 设置机器人名称(如“生产线报警机器人”)
- 复制生成的Webhook 地址(格式如下):
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
步骤2:C# 推送实现(推荐 HttpClient + Json)
usingSystem.Net.Http;usingSystem.Text;usingSystem.Text.Json;usingSystem.Threading.Tasks;publicclassWeComWebhookNotifier{privatereadonlystring_webhookUrl;privatereadonlyHttpClient_httpClient;publicWeComWebhookNotifier(stringwebhookUrl){_webhookUrl=webhookUrl;_httpClient=newHttpClient{Timeout=TimeSpan.FromSeconds(10)};}/// <summary>/// 发送文本消息(最常用)/// </summary>publicasyncTask<bool>SendTextAsync(stringcontent,string[]?mentionedList=null,string[]?mobileList=null){varpayload=new{msgtype="text",text=new{content,mentioned_list=mentionedList??Array.Empty<string>(),mentioned_mobile_list=mobileList??Array.Empty<string>()}};returnawaitSendJsonAsync(payload);}/// <summary>/// 发送 Markdown 消息(支持颜色、加粗、链接)/// </summary>publicasyncTask<bool>SendMarkdownAsync(stringtitle,stringcontent,AlarmLevellevel=AlarmLevel.Warning){stringcolor=levelswitch{AlarmLevel.Info=>"info",AlarmLevel.Warning=>"warning",AlarmLevel.Serious=>"comment",AlarmLevel.Emergency=>"red",_=>"info"};varmarkdown=$"""### {title}**级别**:{level}**描述**:{content}**时间**:{DateTime.Now:yyyy-MM-ddHH:mm:ss}""";varpayload=new{msgtype="markdown",markdown=new{content=markdown}};returnawaitSendJsonAsync(payload);}/// <summary>/// 发送卡片消息(更美观,推荐严重报警)/// </summary>publicasyncTask<bool>SendCardAsync(AlarmEventalarm){stringcolor=alarm.Levelswitch{AlarmLevel.Emergency=>"#FF0000",AlarmLevel.Serious=>"#FF6600",AlarmLevel.Warning=>"#FFCC00",_=>"#0066CC"};varpayload=new{msgtype="template_card",template_card=new{card_type="text_notice",source=new{icon_url="https://example.com/alarm-icon.png",desc="生产线监控"},main_title=new{title=$"【{alarm.Level}】{alarm.Description}"},emphasis_content=new{title=alarm.CurrentValue?.ToString("F2")??"异常",desc=alarm.TagName},sub_title_text=$"设备:{alarm.DeviceId}| 时间:{alarm.TriggerTime:yyyy-MM-dd HH:mm:ss}",card_action=new{type=1,url="https://your-monitor-url/alarm?id="+alarm.Id,title="查看详情"},horizontal_content_list=new[]{new{keyname="当前值",value=alarm.CurrentValue?.ToString("F2")??"—"},new{keyname="阈值",value=alarm.Threshold.ToString("F2")}},card_menu=new{desc="已确认",actionkey="confirm_"+alarm.Id}}};returnawaitSendJsonAsync(payload);}privateasyncTask<bool>SendJsonAsync(objectpayload){try{varjson=JsonSerializer.Serialize(payload);varcontent=newStringContent(json,Encoding.UTF8,"application/json");varresponse=await_httpClient.PostAsync(_webhookUrl,content);varresponseContent=awaitresponse.Content.ReadAsStringAsync();if(response.IsSuccessStatusCode){varresult=JsonDocument.Parse(responseContent).RootElement;if(result.GetProperty("errcode").GetInt32()==0)returntrue;}Log.Error("企业微信推送失败: {Status} - {Content}",response.StatusCode,responseContent);returnfalse;}catch(Exceptionex){Log.Error(ex,"企业微信推送异常");returnfalse;}}}3. 集成到报警通知器(前文 IAlarmNotifier)
publicclassWeComAlarmNotifier:IAlarmNotifier{privatereadonlyWeComWebhookNotifier_webhook;publicWeComAlarmNotifier(stringwebhookUrl){_webhook=newWeComWebhookNotifier(webhookUrl);}publicasyncTaskNotifyAsync(AlarmEventalarm){stringtitle=$"【{alarm.Level}】{alarm.Description}";stringcontent=$"设备:{alarm.DeviceId}\n标签:{alarm.TagName}\n触发值:{alarm.Threshold:F2}\n当前值:{alarm.CurrentValue:F2}\n时间:{alarm.TriggerTime:yyyy-MM-dd HH:mm:ss}";// 不同级别不同样式boolsuccess=alarm.Levelswitch{AlarmLevel.Emergency=>await_webhook.SendCardAsync(alarm),AlarmLevel.Serious=>await_webhook.SendMarkdownAsync(title,content,alarm.Level),_=>await_webhook.SendTextAsync(content)};if(!success){Log.Warning("企业微信推送失败,报警未送达: {@Alarm}",alarm);}}}4. DI 注册(Program.cs)
// 在服务注册中stringwecomWebhook=builder.Configuration["WeCom:WebhookUrl"]??"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=你的key";builder.Services.AddSingleton<IAlarmNotifier>(sp=>newWeComAlarmNotifier(wecomWebhook));5. 生产注意事项
- Webhook 安全性:key 泄露会导致群被刷屏,建议:
- 存入 User Secrets / Azure Key Vault / 环境变量
- 每个产线/车间用不同群机器人
- 限流:企业微信 webhook 每分钟 20 条,建议严重报警才发卡片,普通报警合并后发文本
- 重试机制:可加 Polly 策略(重试 3 次,指数退避)
- 富文本增强:卡片支持跳转到你的监控系统详情页(带 alarm.Id 参数)
如果需要更高级的应用消息推送(支持@指定人、接收人列表、消息卡片模板)、Polly 重试包装、多群分级推送(严重→运维群,急停→领导群),或者结合 TTS 语音播报的完整代码,直接告诉我你的具体需求,我继续补充。