using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace CampusErrand.Services;
///
/// 腾讯 IM 服务,负责生成 UserSig
///
public class TencentIMService
{
private readonly long _sdkAppId;
private readonly string _secretKey;
public TencentIMService(IConfiguration configuration)
{
var config = configuration.GetSection("TencentIM");
_sdkAppId = config.GetValue("SDKAppId");
_secretKey = config["SecretKey"]!;
}
public long SDKAppId => _sdkAppId;
///
/// 生成 UserSig
///
/// 用户标识
/// 有效期(秒),默认7天
public string GenerateUserSig(string userId, int expireSeconds = 604800)
{
var now = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
var obj = new Dictionary
{
["TLS.ver"] = "2.0",
["TLS.identifier"] = userId,
["TLS.sdkappid"] = _sdkAppId,
["TLS.expire"] = expireSeconds,
["TLS.time"] = now
};
var contentToSign = $"TLS.identifier:{userId}\nTLS.sdkappid:{_sdkAppId}\nTLS.time:{now}\nTLS.expire:{expireSeconds}\n";
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(_secretKey));
var sig = hmac.ComputeHash(Encoding.UTF8.GetBytes(contentToSign));
obj["TLS.sig"] = Convert.ToBase64String(sig);
var jsonBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(obj));
// zlib 压缩
using var output = new MemoryStream();
using (var zlib = new System.IO.Compression.ZLibStream(output, System.IO.Compression.CompressionLevel.Optimal))
{
zlib.Write(jsonBytes, 0, jsonBytes.Length);
}
// Base64 URL 安全编码
return Convert.ToBase64String(output.ToArray())
.Replace('+', '*')
.Replace('/', '-')
.Replace('=', '_');
}
}