Outlook Web Add-in:调用event.completed(true)后Send按钮不触发事件
这并不是Outlook 365加载项的已知Bug,而是你对event.completed()方法的参数使用场景产生了误解,导致后续On Send事件无法正常触发。我来帮你拆解问题并给出修正方案:
核心误解点
event.completed({allowEvent: true})这个写法,仅适用于需要拦截用户操作的系统事件上下文(比如On Send、On Save这类触发后会暂停用户操作的事件),用来告知Outlook是否允许执行用户发起的操作(比如发送邮件)。但你在自定义无UI命令按钮的逻辑里调用这个方法,相当于错误地把当前命令事件和On Send事件的上下文混淆了——自定义按钮的event.completed()不需要allowEvent参数,它只是用来标记当前命令执行完成,和后续的发送操作没有关联。
具体修正步骤
修改自定义按钮的事件处理代码
当你通过自定义按钮完成item.body的修改后,只需要调用无参数的event.completed()即可,不需要传递allowEvent配置:// 自定义按钮的事件处理函数 function addContentToBody(event) { // 执行修改item.body的逻辑 Office.context.mailbox.item.body.setAsync( '<p>添加的自定义内容</p>', { coercionType: Office.CoercionType.Html }, function(asyncResult) { if (asyncResult.status === Office.AsyncResultStatus.Succeeded) { // 仅调用无参数的completed,标记当前命令执行完成 event.completed(); } else { // 处理错误后仍需调用completed结束命令 console.error('修改邮件内容失败:', asyncResult.error); event.completed(); } } ); }确保On Send事件的独立配置
你的On Send功能需要在manifest中单独声明,并且有独立的处理函数,和自定义按钮的逻辑完全分开:- 在manifest.xml中添加事件声明:
<ExtensionPoint xsi:type="Events"> <Event Type="ItemSend" FunctionName="handleSendEvent" /> </ExtensionPoint> - 在JS代码中实现On Send的处理函数,这里才是使用
allowEvent参数的正确场景:function handleSendEvent(event) { // 这里可以添加发送前的校验、处理逻辑 // 允许发送 event.completed({ allowEvent: true }); // 如果要阻止发送,就传false:event.completed({ allowEvent: false }); }
- 在manifest.xml中添加事件声明:
测试流程验证
按照以下步骤测试:- 点击自定义按钮,修改邮件内容,此时命令执行完成后调用无参的
event.completed(),UI无错误提示。 - 点击Send按钮,此时会正常触发
handleSendEvent函数,在该函数中调用event.completed({ allowEvent: true })即可完成发送。
- 点击自定义按钮,修改邮件内容,此时命令执行完成后调用无参的
为什么之前不调用event.completed()就正常?
当你不调用event.completed()时,自定义按钮的事件上下文处于未完成状态,但Outlook并没有强制拦截后续操作,所以On Send事件仍能触发。但这不是正确的做法——所有自定义命令的事件处理函数都必须调用event.completed()来告知Outlook命令执行完毕,否则可能导致其他异常行为。
内容的提问来源于stack exchange,提问作者Jaydev Solanki

