如何通过React+C#开发的MS Teams自定义应用发送定时推送通知?
需求可行性及实现方案
这个需求完全可行,结合你的React前端+C#后端技术栈,搭配Teams平台的通知能力,就能实现定时推送提醒的功能。以下是具体实现方案:
一、整体实现逻辑
- 用户在前端完成事件操作(如餐厅预订)后,将事件核心信息(目标时间、用户Teams标识、通知内容等)提交到C#后端
- 后端存储事件数据,并创建定时任务,在事件时间提前1小时的节点触发通知逻辑
- 触发时,后端调用Teams官方API向指定用户推送通知
二、具体实现步骤
1. 前端:提交事件数据到后端
当用户完成预订操作后,React前端需收集关键信息并调用后端接口提交,核心是获取当前用户的Teams身份标识:
import { microsoftTeams } from "@microsoft/teams-js"; // 预订完成后的处理函数 const handleBookingSubmit = async (bookingDetails) => { // 通过Teams SDK获取当前用户上下文 microsoftTeams.getContext((context) => { const submitData = { eventTime: bookingDetails.eventTime, // 格式示例:"2024-05-20T20:30:00" userId: context.userObjectId, // 用户在Teams中的唯一标识 notificationContent: `您预订的${bookingDetails.restaurantName}20:30的座位即将开始,请提前到场` }; // 调用后端接口提交数据 fetch('/api/bookings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(submitData) }); }); };
2. 后端:存储事件并创建定时任务
C#后端需完成事件存储与定时任务调度,推荐使用轻量级的Hangfire库实现定时逻辑:
(1)存储事件数据
用数据库(如SQL Server)存储事件记录,核心字段示例:
| 字段名 | 类型 | 说明 |
|---|---|---|
| Id | Guid | 事件唯一ID |
| UserId | String | 用户Teams标识 |
| EventTime | DateTime | 事件目标时间 |
| NotificationTime | DateTime | 通知触发时间(提前1小时) |
| Content | String | 通知内容 |
| Status | Enum | 通知状态(未发送/已发送) |
(2)配置并创建定时任务
- 安装Hangfire依赖:
Install-Package Hangfire Install-Package Hangfire.SqlServer
- 在Startup中配置Hangfire:
using Hangfire; public void ConfigureServices(IServiceCollection services) { // 配置Hangfire使用SQL Server存储任务 services.AddHangfire(config => config.UseSqlServerStorage(Configuration.GetConnectionString("HangfireConn"))); services.AddHangfireServer(); } public void Configure(IApplicationBuilder app) { // 启用Hangfire仪表盘(可选,用于监控任务) app.UseHangfireDashboard("/hangfire"); }
- 处理前端提交的事件并创建定时任务:
[ApiController] [Route("api/bookings")] public class BookingController : ControllerBase { private readonly IBackgroundJobClient _jobClient; private readonly AppDbContext _dbContext; public BookingController(IBackgroundJobClient jobClient, AppDbContext dbContext) { _jobClient = jobClient; _dbContext = dbContext; } [HttpPost] public async Task<IActionResult> CreateBooking([FromBody] BookingSubmitModel model) { // 计算通知触发时间:提前1小时 var triggerTime = model.EventTime.AddHours(-1); // 存储事件到数据库 var bookingEvent = new BookingEvent { UserId = model.UserId, EventTime = model.EventTime, NotificationTime = triggerTime, Content = model.NotificationContent, Status = NotificationStatus.Unsent }; _dbContext.BookingEvents.Add(bookingEvent); await _dbContext.SaveChangesAsync(); // 创建定时任务,到触发时间执行通知逻辑 _jobClient.Schedule( () => SendTeamsNotification(bookingEvent.Id), triggerTime ); return Ok(); } }
3. 后端:调用Teams API发送通知
通过Microsoft Graph API实现Teams消息推送,需先在Azure AD中注册应用并申请ChatMessage.Send、User.Read.All权限:
using Microsoft.Graph; using Azure.Identity; public async Task SendTeamsNotification(Guid eventId) { var bookingEvent = await _dbContext.BookingEvents.FindAsync(eventId); if (bookingEvent == null || bookingEvent.Status == NotificationStatus.Sent) return; // 初始化Graph客户端(使用客户端凭据流认证) var graphClient = new GraphServiceClient( new ClientSecretCredential( Configuration["AzureAd:TenantId"], Configuration["AzureAd:ClientId"], Configuration["AzureAd:ClientSecret"] ) ); // 构建通知消息 var message = new ChatMessage { Body = new ItemBody { ContentType = BodyType.Html, Content = bookingEvent.Content } }; try { // 发送到用户的个人聊天 await graphClient.Users[bookingEvent.UserId] .Chats["{user-chat-id}"] .Messages .Request() .AddAsync(message); // 更新通知状态为已发送 bookingEvent.Status = NotificationStatus.Sent; await _dbContext.SaveChangesAsync(); } catch (Exception ex) { // 记录发送失败日志,可添加重试逻辑 Console.WriteLine($"通知发送失败:{ex.Message}"); } }
注:若需要更丰富的通知样式,可使用Teams自适应卡片替换普通文本内容。
4. 测试与验证
- 验证前端提交的数据是否正确写入数据库
- 测试定时任务是否在指定时间触发
- 确认通知是否成功推送至用户Teams客户端
三、关键注意事项
- 时区统一:所有时间需使用UTC存储,避免时区差异导致通知时间错误
- 重试机制:针对通知发送失败的情况,添加重试逻辑(如Hangfire的重试特性)
- 权限管控:确保Azure AD应用拥有足够的Graph API权限,认证方式符合场景需求
- 性能优化:若事件量较大,需考虑定时任务的并发处理能力,避免数据库压力过大
内容的提问来源于stack exchange,提问作者Croicco
相关产品推荐
相关产品推荐

