如何从Web服务器向Outlook加载项发送Push通知?
Outlook加载项推送通知实现方案
最佳实现方式
1. 定时轮询 + 后端存储(官方推荐替代方案)
- 核心逻辑:服务器将待推送的通知数据存入后端数据库,加载项在激活时或按固定间隔(建议5-15分钟)调用自定义API拉取未读通知,通过
Office.context.document.settings或localStorage记录已读状态。 - 优势:兼容性覆盖所有支持OfficeJS的Outlook版本,无需依赖第三方服务,实现成本低。
- 注意点:避免过短的轮询间隔,防止频繁请求影响性能;加载项切换至后台时可暂停轮询,激活后恢复。
2. Azure SignalR Service + WebSockets(实时性最优方案)
这是目前实现实时推送的可行方案,尽管官方未提供专门的OfficeJS教程,但实际适配性良好:
- 实现步骤:
- 后端部署Azure SignalR Service,搭建WebSocket通信枢纽。
- 加载项初始化时,通过
Office.context.mailbox.userProfile.emailAddress获取用户唯一标识,将其作为SignalR的分组ID,发送至后端完成分组加入。 - 服务器需要推送通知时,调用SignalR的分组推送接口,向目标用户的连接分组发送消息。
- 加载端监听消息事件,收到通知后通过OfficeJS的UI能力(如
displayDialogAsync弹出提示、更新任务窗格通知徽章)展示内容。
- 关键处理:必须实现连接断开后的自动重连逻辑,比如加载项从后台激活时重新发起连接。
Push API(含FCM)的支持情况
Outlook加载项的运行环境决定了Push API的支持局限性:
- 桌面端Outlook(Windows/macOS):嵌入式浏览器虽基于支持Push API的内核,但受Office安全策略限制,无法获取Service Worker的注册权限,无法正常使用FCM或原生Push API。
- 网页版Outlook(Outlook on the Web):运行在用户原生浏览器中,支持Push API和FCM,但需满足两个条件:加载项部署在HTTPS环境下,Service Worker的注册路径符合浏览器要求。不过网页版加载项的生命周期依赖浏览器标签页,标签页关闭后无法接收推送。
WebSockets实现代码示例
前端(加载项任务窗格)
// 初始化SignalR连接 const connection = new signalR.HubConnectionBuilder() .withUrl("https://your-signalr-hub-endpoint") .build(); // 监听服务器推送的通知 connection.on("ReceiveNotification", (notificationData) => { // 弹出通知对话框展示内容 Office.context.ui.displayDialogAsync( `./notification.html?data=${encodeURIComponent(JSON.stringify(notificationData))}`, { height: 30, width: 40, displayInIframe: true }, (result) => { if (result.error) console.error(result.error); } ); }); // 启动连接并处理重连 async function initSignalR() { try { await connection.start(); // 将用户邮箱作为分组标识,加入对应分组 await connection.invoke("JoinUserGroup", Office.context.mailbox.userProfile.emailAddress); } catch (err) { console.error("SignalR连接失败:", err); setTimeout(initSignalR, 5000); // 5秒后尝试重连 } } // 加载项就绪时初始化连接 Office.onReady(() => { initSignalR(); });
后端(ASP.NET Core SignalR示例)
using Microsoft.AspNetCore.SignalR; public class NotificationHub : Hub { // 接收加载端的分组加入请求 public async Task JoinUserGroup(string userEmail) { await Groups.AddToGroupAsync(Context.ConnectionId, userEmail); } // 服务器调用此方法向指定用户推送通知 public async Task SendNotification(string userEmail, object notification) { await Clients.Group(userEmail).SendAsync("ReceiveNotification", notification); } }
内容的提问来源于stack exchange,提问作者p6l-richard
相关产品推荐
相关产品推荐

