关于企业微信
This commit is contained in:
@@ -118,6 +118,31 @@ namespace Ramitta.lib
|
||||
#endregion
|
||||
|
||||
#region 文件解析
|
||||
public static string? GetExeVersion(string exePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(exePath))
|
||||
{
|
||||
return null; // 文件不存在时返回null
|
||||
}
|
||||
|
||||
var versionInfo = FileVersionInfo.GetVersionInfo(exePath);
|
||||
string? version = versionInfo.FileVersion;
|
||||
|
||||
// 如果FileVersion为空,尝试使用ProductVersion
|
||||
if (string.IsNullOrEmpty(version))
|
||||
{
|
||||
version = versionInfo.ProductVersion;
|
||||
}
|
||||
|
||||
return string.IsNullOrEmpty(version) ? null : version;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null; // 出现任何异常都返回null
|
||||
}
|
||||
}
|
||||
public static bool IsPathExist(string databasePath)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(databasePath))
|
||||
|
||||
259
Ramitta/WeComRobot.cs
Normal file
259
Ramitta/WeComRobot.cs
Normal file
@@ -0,0 +1,259 @@
|
||||
using HelixToolkit.Maths;
|
||||
using NPOI.HPSF;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
namespace Ramitta
|
||||
{
|
||||
public class WeComRobot
|
||||
{
|
||||
private readonly string _webhookUrl;
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public WeComRobot(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<WeComResponse>(responseContent);
|
||||
return result?.errcode == 0;
|
||||
}
|
||||
|
||||
Console.WriteLine($"发送失败: {responseContent}");
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"发送消息异常: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 上传文件到企业微信并获取media_id (修正版)
|
||||
/// </summary>
|
||||
public async Task<string> UploadFileAsync(string filePath,string? fileName=null)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 1. 从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";
|
||||
|
||||
// 2. 准备文件和边界
|
||||
if(fileName==null) fileName = Path.GetFileName(filePath);
|
||||
var fileBytes = await File.ReadAllBytesAsync(filePath);
|
||||
string boundary = "------------------------" + DateTime.Now.Ticks.ToString("x"); // 随机边界字符串
|
||||
string startBoundary = "--" + boundary;
|
||||
string endBoundary = "--" + boundary + "--";
|
||||
|
||||
// 3. 创建并配置HttpWebRequest
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uploadUrl);
|
||||
request.Method = "POST";
|
||||
request.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||
request.Timeout = 30000; // 可根据需要调整超时
|
||||
|
||||
// 4. 手动构建并写入请求体(关键步骤)
|
||||
using (Stream requestStream = await request.GetRequestStreamAsync())
|
||||
{
|
||||
using (var writer = new StreamWriter(requestStream, Encoding.UTF8, 1024, true))
|
||||
{
|
||||
// 4.1 写入开始边界 (必须有回车换行)
|
||||
await writer.WriteAsync(startBoundary + "\r\n");
|
||||
await writer.FlushAsync();
|
||||
|
||||
// 4.2 写入文件头信息 (注意格式中的双引号)
|
||||
string header = $"Content-Disposition: form-data; name=\"media\"; filename=\"{fileName}\"\r\n";
|
||||
header += "Content-Type: application/octet-stream\r\n";
|
||||
header += "\r\n"; // 文件头结束后需要一个额外的空行(即两个连续的\r\n)
|
||||
await writer.WriteAsync(header);
|
||||
await writer.FlushAsync();
|
||||
|
||||
// 4.3 直接写入文件字节
|
||||
await requestStream.WriteAsync(fileBytes, 0, fileBytes.Length);
|
||||
await writer.WriteAsync("\r\n"); // 文件内容后需要一个回车换行
|
||||
await writer.FlushAsync();
|
||||
|
||||
// 4.4 写入结束边界
|
||||
await writer.WriteAsync(endBoundary + "\r\n");
|
||||
await writer.FlushAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 获取并解析响应
|
||||
using (HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
|
||||
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
|
||||
{
|
||||
string responseContent = await reader.ReadToEndAsync();
|
||||
Console.WriteLine($"上传响应: {responseContent}");
|
||||
|
||||
using (var doc = JsonDocument.Parse(responseContent))
|
||||
{
|
||||
if (doc.RootElement.TryGetProperty("media_id", out var mediaIdElement))
|
||||
{
|
||||
return mediaIdElement.GetString();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 解析错误信息
|
||||
var errcode = doc.RootElement.GetProperty("errcode").GetInt32();
|
||||
var errmsg = doc.RootElement.GetProperty("errmsg").GetString();
|
||||
Console.WriteLine($"文件上传失败: errcode={errcode}, errmsg={errmsg}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
// 尝试读取错误响应体
|
||||
if (ex.Response is HttpWebResponse errorResponse)
|
||||
{
|
||||
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
|
||||
{
|
||||
string errorContent = await reader.ReadToEndAsync();
|
||||
Console.WriteLine($"HTTP请求失败 ({errorResponse.StatusCode}): {errorContent}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"网络请求异常: {ex.Message}");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"文件上传过程异常: {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <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 WeComResponse
|
||||
{
|
||||
public int errcode { get; set; }
|
||||
public string errmsg { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user