You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apex调用邮件模板发邮件:合并字段不显示且setWhatId报错求助

问题描述

我通过Apex发送包含合并字段{{!Opportunity.custom__c}}的邮件模板,但该字段值始终不显示。代码如下:

Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    email.setTemplateId(et.Id); // Email Template ID
    email.setTargetObjectId(user.Id); // User ID to send
    //email.setWhatId(opp.Id); !Error!
    email.setSaveAsActivity(false);
    emails.add(email);  

尝试添加email.setWhatId(opportunity.Id)时,收到错误提示:INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.: [whatId, XXXXXXXXXXX]

想知道怎么把Opportunity的信息传递给模板?是不是不该用模板?

解决方案

Salesforce有明确规则:当邮件的TargetObjectId是User ID时,不能设置WhatId,这就是你报错的核心原因。要把Opportunity字段值传递到模板里,有以下几种可行方案:

方案1:改用Visualforce邮件模板+参数传递

创建Visualforce类型的邮件模板,通过在Apex中替换模板占位符的方式传入Opportunity字段值,无需依赖WhatId。

示例Visualforce模板结构:

<messaging:emailTemplate subject="Opportunity通知" recipientType="User">
    <messaging:htmlEmailBody>
        <p>自定义字段值:{{!oppCustomField}}</p>
    </messaging:htmlEmailBody>
</messaging:emailTemplate>

对应的Apex代码调整:

Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setTemplateId(et.Id); // 这里用Visualforce模板的ID
email.setTargetObjectId(user.Id);
// 替换模板中的占位符为实际Opportunity字段值
String htmlBody = email.getHtmlBody().replace('{{!oppCustomField}}', opp.custom__c);
email.setHtmlBody(htmlBody);
email.setSaveAsActivity(false);
emails.add(email);

方案2:直接在Apex中构造邮件内容

如果模板逻辑不复杂,完全可以放弃邮件模板,直接在代码里拼接包含Opportunity字段的正文和主题,绕开合并字段的限制:

Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
email.setSubject('你的Opportunity通知');
email.setToAddresses(new List<String>{user.Email}); // 直接指定收件人邮箱
email.setHtmlBody('<p>自定义字段值:' + opp.custom__c + '</p>');
email.setSaveAsActivity(false);
emails.add(email);

方案3:将收件人转为Contact(业务允许时)

如果该用户关联了Contact记录,可以把TargetObjectId换成Contact的ID,这时就能正常设置WhatId为Opportunity ID,模板里的合并字段会自动填充:

// 查询用户关联的Contact记录
Contact userContact = [SELECT Id FROM Contact WHERE OwnerId = :user.Id LIMIT 1];
if(userContact != null){
    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    email.setTemplateId(et.Id);
    email.setTargetObjectId(userContact.Id);
    email.setWhatId(opp.Id); // 此时WhatId可以正常设置
    email.setSaveAsActivity(false);
    emails.add(email);
}

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:40:14