1. 创建消息推送机器人
首先在企业微信中创建群聊,然后添加群机器人,获取webhook地址。


2. 基础实现代码
cs
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
public class EnterpriseWeChatRobot
{
private readonly string _webhookUrl;
private readonly HttpClient _httpClient;
public EnterpriseWeChatRobot(string webhookUrl)
{
_webhookUrl = webhookUrl;
_httpClient = new HttpClient();
}
/// <summary>
/// 发送文本消息
/// </summary>
public async Task<bool> SendTextMessageAsync(string content, string[] mentionedList = null, string[] mentionedMobileList = null)
{
var message = new
{
msgtype = "text",
text = new
{
content = content,
mentioned_list = mentionedList,
mentioned_mobile_list = mentionedMobileList
}
};
return await SendMessageAsync(message);
}
/// <summary>
/// 发送Markdown消息
/// </summary>
public async Task<bool> SendMarkdownMessageAsync(string content)
{
var message = new
{
msgtype = "markdown",
markdown = new
{
content = content
}
};
return await SendMessageAsync(message);
}
/// <summary>
/// 发送图片消息
/// </summary>
public async Task<bool> SendImageMessageAsync(string base64, string md5)
{
var message = new
{
msgtype = "image",
image = new
{
base64 = base64,
md5 = md5
}
};
return await SendMessageAsync(message);
}
/// <summary>
/// 发送图文消息
/// </summary>
public async Task<bool> SendNewsMessageAsync(Article[] articles)
{
var message = new
{
msgtype = "news",
news = new
{
articles = articles
}
};
return await SendMessageAsync(message);
}
/// <summary>
/// 发送文件消息
/// </summary>
public async Task<bool> SendFileMessageAsync(string mediaId)
{
var message = new
{
msgtype = "file",
file = new
{
media_id = mediaId
}
};
return await SendMessageAsync(message);
}
private async Task<bool> SendMessageAsync(object message)
{
try
{
var json = JsonSerializer.Serialize(message);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync(_webhookUrl, content);
var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var result = JsonSerializer.Deserialize<WeChatResponse>(responseContent);
return result?.errcode == 0;
}
Console.WriteLine($"发送失败: {responseContent}");
return false;
}
catch (Exception ex)
{
Console.WriteLine($"发送消息异常: {ex.Message}");
return false;
}
}
}
/// <summary>
/// 图文消息文章
/// </summary>
public class Article
{
public string title { get; set; }
public string description { get; set; }
public string url { get; set; }
public string picurl { get; set; }
}
/// <summary>
/// 企业微信响应
/// </summary>
public class WeChatResponse
{
public int errcode { get; set; }
public string errmsg { get; set; }
}
3. 使用示例
cs
class Program
{
static async Task Main(string[] args)
{
// 替换为你的webhook地址
string webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY";
var robot = new EnterpriseWeChatRobot(webhookUrl);
// 发送文本消息
bool success1 = await robot.SendTextMessageAsync(
"Hello, 这是一条测试消息!",
mentionedList: new[] { "@all" } // @所有人
);
// 发送Markdown消息
bool success2 = await robot.SendMarkdownMessageAsync(
"### 项目通知\n" +
"> **项目**: 企业微信机器人测试\n" +
"> **状态**: 运行正常\n" +
"> **时间**: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
"> **详情**: [点击查看详情](https://work.weixin.qq.com/)"
);
// 发送图文消息
var articles = new[]
{
new Article
{
title = "企业微信官方文档",
description = "查看详细的使用文档",
url = "https://work.weixin.qq.com/api/doc/90000/90136/91770",
picurl = "https://res.wx.qq.com/a/wx_fed/assets/res/NTI4MWU5.ico"
}
};
bool success3 = await robot.SendNewsMessageAsync(articles);
Console.WriteLine($"文本消息发送: {success1}");
Console.WriteLine($"Markdown消息发送: {success2}");
Console.WriteLine($"图文消息发送: {success3}");
}
}
4. 高级功能 - 文件上传
如果需要发送文件消息,需要先上传文件获取media_id:
cs
/// <summary>
/// 上传文件到企业微信并获取media_id
/// </summary>
public async Task<string> UploadFileAsync(string filePath)
{
try
{
// 从webhook地址中提取key
var uri = new Uri(_webhookUrl);
var key = System.Web.HttpUtility.ParseQueryString(uri.Query)["key"];
string uploadUrl = $"https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key={key}&type=file";
using var form = new MultipartFormDataContent();
using var fileContent = new ByteArrayContent(await File.ReadAllBytesAsync(filePath));
fileContent.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/octet-stream");
form.Add(fileContent, "media", Path.GetFileName(filePath));
var response = await _httpClient.PostAsync(uploadUrl, form);
var responseContent = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
using var doc = JsonDocument.Parse(responseContent);
if (doc.RootElement.TryGetProperty("media_id", out var mediaIdElement))
{
return mediaIdElement.GetString();
}
}
Console.WriteLine($"文件上传失败: {responseContent}");
return null;
}
catch (Exception ex)
{
Console.WriteLine($"文件上传异常: {ex.Message}");
return null;
}
}
5. 完整使用示例
cs
class Program
{
static async Task Main(string[] args)
{
string webhookUrl = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY";
var robot = new EnterpriseWeChatRobot(webhookUrl);
// 1. 发送文本消息并@特定用户
await robot.SendTextMessageAsync(
"任务执行完成,请相关同事查看结果。",
mentionedList: new[] { "张三", "李四" }
);
// 2. 发送Markdown格式的告警消息
await robot.SendMarkdownMessageAsync(
"🚨 **系统告警**\n" +
"---\n" +
"**服务**: API Gateway\n" +
"**级别**: CRITICAL\n" +
"**时间**: " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\n" +
"**描述**: 服务响应时间超过阈值\n" +
"**建议**: 请立即检查服务器状态"
);
// 3. 如果有文件需要发送
// string mediaId = await robot.UploadFileAsync("report.pdf");
// if (!string.IsNullOrEmpty(mediaId))
// {
// await robot.SendFileMessageAsync(mediaId);
// }
}
}
注意事项
bash
Webhook地址:确保使用正确的webhook地址,包含有效的key
消息频率限制:企业微信机器人有发送频率限制,请勿频繁发送
安全性:webhook地址包含敏感信息,请妥善保管
异常处理:在实际使用中建议添加更完善的异常处理机制
HTTP客户端:建议使用IHttpClientFactory来管理HttpClient实例