news 2026/6/8 16:00:19

手把手教你用C#对接爱发电API:Afdian.Sdk保姆级教程(含Webhook通知实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
手把手教你用C#对接爱发电API:Afdian.Sdk保姆级教程(含Webhook通知实战)

手把手教你用C#对接爱发电API:Afdian.Sdk保姆级教程(含Webhook通知实战)

在独立开发者和小团队的项目中,赞助功能往往是维持项目可持续发展的重要途径。爱发电作为国内知名的创作者赞助平台,为开发者提供了便捷的赞助接入方案。而Afdian.Sdk这个非官方.NET库,则让C#开发者能够以更优雅的方式集成爱发电功能。本文将带你从零开始,以一个开源工具项目为例,完整实现从SDK集成到Webhook处理的全流程。

1. 环境准备与基础配置

在开始之前,确保你的开发环境满足以下要求:

  • .NET 6.0或更高版本
  • Visual Studio 2022或Rider最新版
  • 一个已注册的爱发电创作者账号

首先通过NuGet安装Afdian.Sdk:

dotnet add package Afdian.Sdk

接下来需要获取爱发电API的必要凭证:

  1. 登录爱发电开发者后台
  2. 进入"应用管理"→"API密钥"
  3. 记录下你的userIdtoken

建议将这些敏感信息存储在安全的地方,而不是硬编码在项目中。对于.NET项目,可以使用secrets.json

{ "SecretsKeys": { "AfdianToken": "你的token", "AfdianUserId": "你的userId" } }

2. 核心API调用实战

2.1 初始化客户端

创建AfdianClient实例是使用SDK的第一步:

using Afdian.Sdk; var afdianClient = new AfdianClient( userId: Configuration["SecretsKeys:AfdianUserId"], token: Configuration["SecretsKeys:AfdianToken"] );

2.2 基础功能测试

在正式开发前,建议先进行连通性测试:

// 测试API连通性 string pingResult = afdianClient.Ping(); Console.WriteLine($"API连通性测试结果: {pingResult}"); // 或者使用异步版本 var pingResultAsync = await afdianClient.PingAsync();

2.3 查询订单与赞助者

获取赞助数据是核心需求,SDK提供了多种查询方式:

// 查询第一页订单(返回原始JSON字符串) string ordersJson = afdianClient.QueryOrder(page: 1); // 查询赞助者(返回强类型模型) var sponsors = afdianClient.QuerySponsorModel(page: 1); // 异步查询示例 var recentOrders = await afdianClient.QueryOrderModelAsync(page: 1, pageSize: 20);

实际项目中,你可能需要处理分页和错误情况:

try { int currentPage = 1; bool hasMore = true; var allOrders = new List<Order>(); while (hasMore) { var pageResult = await afdianClient.QueryOrderModelAsync(currentPage); allOrders.AddRange(pageResult.Data.List); hasMore = pageResult.Data.TotalPage > currentPage; currentPage++; // 避免频繁调用 await Task.Delay(500); } Console.WriteLine($"共获取到{allOrders.Count}条订单记录"); } catch (Exception ex) { Console.WriteLine($"查询订单时出错: {ex.Message}"); }

3. Webhook通知集成

Webhook是实时获取赞助通知的最佳方式。下面我们实现一个完整的Webhook处理流程。

3.1 配置Webhook端点

首先在爱发电后台设置Webhook地址:

  1. 进入开发者后台→Webhook设置
  2. 添加一个新的Webhook端点
  3. 设置一个强密码用于验证签名

3.2 实现Webhook控制器

创建一个ASP.NET Core控制器处理Webhook通知:

[ApiController] [Route("api/webhook")] public class AfdianWebhookController : ControllerBase { private readonly IConfiguration _config; private readonly TelegramService _telegram; public AfdianWebhookController(IConfiguration config, TelegramService telegram) { _config = config; _telegram = telegram; } [HttpPost] public async Task<IActionResult> HandleNotification([FromBody] AfdianWebhookPayload payload) { // 1. 验证签名 string secret = _config["AfdianWebhookSecret"]; if (!VerifySignature(payload, secret)) { return Unauthorized(); } // 2. 处理不同类型的事件 switch (payload.Data.Type) { case "order.new": await HandleNewOrder(payload.Data.Order); break; case "order.changed": await HandleOrderUpdate(payload.Data.Order); break; default: Console.WriteLine($"未知事件类型: {payload.Data.Type}"); break; } return Ok(new { ec = 200, em = "success" }); } private bool VerifySignature(AfdianWebhookPayload payload, string secret) { // 实现签名验证逻辑 } private async Task HandleNewOrder(Order order) { string message = $"🎉 新赞助: {order.Sponsor.Name} 赞助了 {order.Amount}元"; await _telegram.SendMessageAsync(message); // 这里可以添加更多处理逻辑,如更新数据库等 } }

3.3 发送Telegram通知

集成Telegram通知可以让开发者实时获知赞助情况:

public class TelegramService { private readonly HttpClient _httpClient; private readonly string _botToken; private readonly string _chatId; public TelegramService(IConfiguration config) { _botToken = config["TelegramBotToken"]; _chatId = config["TelegramChatId"]; _httpClient = new HttpClient(); } public async Task SendMessageAsync(string text) { var url = $"https://api.telegram.org/bot{_botToken}/sendMessage"; var content = new FormUrlEncodedContent(new Dictionary<string, string> { ["chat_id"] = _chatId, ["text"] = text, ["parse_mode"] = "Markdown" }); await _httpClient.PostAsync(url, content); } }

4. 进阶技巧与最佳实践

4.1 错误处理与重试机制

API调用可能会遇到各种网络问题,实现健壮的错误处理很重要:

public async Task<T> ExecuteWithRetry<T>(Func<Task<T>> action, int maxRetries = 3) { int retryCount = 0; while (true) { try { return await action(); } catch (HttpRequestException ex) when (retryCount < maxRetries) { retryCount++; var delay = Math.Pow(2, retryCount) * 100; // 指数退避 await Task.Delay((int)delay); } } } // 使用示例 var sponsors = await ExecuteWithRetry(() => afdianClient.QuerySponsorModelAsync(1));

4.2 性能优化建议

当处理大量数据时,考虑以下优化:

  • 使用IAsyncEnumerable流式处理分页数据
  • 实现本地缓存减少API调用
  • 批量处理Webhook通知
public async IAsyncEnumerable<Order> GetAllOrdersAsync() { int page = 1; while (true) { var result = await afdianClient.QueryOrderModelAsync(page); foreach (var order in result.Data.List) { yield return order; } if (page >= result.Data.TotalPage) break; page++; } } // 使用示例 await foreach (var order in GetAllOrdersAsync()) { // 处理每个订单 }

4.3 安全注意事项

在处理赞助数据时,安全至关重要:

  • 始终验证Webhook签名
  • 不要在前端暴露API密钥
  • 定期轮换凭证
  • 记录所有API调用和Webhook事件
private bool VerifySignature(AfdianWebhookPayload payload, string secret) { var paramsToSign = new Dictionary<string, string> { ["ts"] = payload.Ts.ToString(), ["body"] = JsonSerializer.Serialize(payload.Data) }; var sortedParams = paramsToSign.OrderBy(x => x.Key); var stringToSign = string.Join("", sortedParams.Select(x => $"{x.Key}{x.Value}")) + secret; using var sha256 = SHA256.Create(); var computedHash = sha256.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)); var computedSignature = BitConverter.ToString(computedHash).Replace("-", "").ToLower(); return computedSignature == payload.Signature; }

5. 项目集成示例

让我们以一个开源Markdown编辑器项目为例,展示如何完整集成爱发电功能。

5.1 添加赞助徽章

在项目README中添加爱发电赞助徽章:

[![爱发电赞助](https://img.shields.io/badge/爱发电-支持作者-946CE6?logo=afdian&logoColor=white)](https://afdian.net/a/yourname)

5.2 实现赞助者致谢页面

创建一个ASP.NET Core页面展示赞助者:

public class SponsorsModel : PageModel { private readonly AfdianClient _afdian; public List<Sponsor> TopSponsors { get; set; } public SponsorsModel(AfdianClient afdian) { _afdian = afdian; } public async Task OnGetAsync() { var result = await _afdian.QuerySponsorModelAsync(page: 1, pageSize: 10); TopSponsors = result.Data.List .OrderByDescending(s => s.AllSumAmount) .Take(5) .ToList(); } }

对应的Razor页面:

@page @model SponsorsModel <h2>特别感谢以下赞助者</h2> <div class="sponsor-grid"> @foreach (var sponsor in Model.TopSponsors) { <div class="sponsor-card"> <img src="@sponsor.Avatar" alt="@sponsor.Name" /> <h3>@sponsor.Name</h3> <p>累计赞助: @sponsor.AllSumAmount 元</p> <p>@sponsor.Message</p> </div> } </div>

5.3 自动化赞助者福利发放

对于提供赞助者专属功能的项目,可以实现自动化福利发放:

public class SponsorBenefitsService { private readonly AfdianClient _afdian; private readonly IUserRepository _userRepo; public SponsorBenefitsService(AfdianClient afdian, IUserRepository userRepo) { _afdian = afdian; _userRepo = userRepo; } public async Task UpdateBenefitsAsync() { var sponsors = await GetAllActiveSponsorsAsync(); foreach (var user in await _userRepo.GetAllAsync()) { var isSponsor = sponsors.Any(s => s.UserId == user.ExternalId); await _userRepo.UpdatePremiumStatusAsync(user.Id, isSponsor); } } private async Task<List<Sponsor>> GetAllActiveSponsorsAsync() { // 实现获取所有活跃赞助者的逻辑 } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/8 15:56:55

Milvus 与 LLM 应用集成:构建 RAG 系统的向量检索层

系列导读 你现在看到的是《Milvus 向量检索平台从入门到生产实战:10 步构建高性能 AI 搜索系统》的第 9/10 篇,当前这篇会重点解决:让 Milvus 成为 LLM 的长期记忆,打造准确且实时的 AI 知识库。 上一篇回顾:第 8 篇《数据安全与灾备:Milvus 备份恢复、权限控制与多租户…

作者头像 李华
网站建设 2026/6/8 15:56:29

通义灵码VS插件太垃圾,太难用了,优缺点

通义灵码优缺点 优点&#xff1f;几乎不存在&#xff0c;说白了只是一个问答功能&#xff0c;远不如网页版豆包方便。 1&#xff0c;通义灵码只能生成代码无法插入文件 2&#xff0c;复制的内容是纯文本&#xff08;豆包可以复制到WORD或网页中&#xff0c;超文本支持彩色文字…

作者头像 李华
网站建设 2026/6/8 15:55:42

第19篇:高级语义与微数据

第19篇&#xff1a;高级语义与微数据 HTML5 不仅提供了结构标签&#xff0c;还提供了让机器"读懂"内容的工具。time、address、details/summary 等高级语义标签&#xff0c;以及微数据&#xff08;Microdata&#xff09;&#xff0c;让你的网页对搜索引擎和自动化工具…

作者头像 李华
网站建设 2026/6/8 15:55:34

如何高效管理数字内容:抖音批量下载工具的完整指南

如何高效管理数字内容&#xff1a;抖音批量下载工具的完整指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support.…

作者头像 李华