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
相关产品推荐
相关产品推荐

