解决Salesforce无法向外发送邮件

问题

有时,我们想在Salesforce组织(Org)中自动对外发送邮件。例如,我们可以使用下面的Apex代码实现。

首先,创建一个方便我们快速发送邮件至单个收件人地址的类。

java 复制代码
// 创建一个方便复用,负责发送单个邮件的功能类
public class EmailManager {
	
	// 主要的发送邮件方法
    public void sendMail(String address, String subject, String body) {
        // 创建一个新邮件消息对象
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        // 设置邮件消息的收件地址、主题和正文内容
        mail.setToAddresses(new String[] { address }); // 尽管目标地址只有一个,但因Salesforce默认设计为方便批量发送,必须以列表(数组)形式传参
        mail.setSubject(subject);
        mail.setPlainTextBody(body);
        // 因默认方便批量发送,`发送结果`对象也必须用列表(数组)捕捉
        Messaging.SendEmailResult[] results = Messaging.sendEmail(
            new Messaging.SingleEmailMessage[] {mail}
        );
        inspectResults(results);
    }

    // 一个仅供内部使用的私有方法,用于快速检查邮件是否全部发送成功
    private static Boolean inspectResults(Messaging.SendEmailResult[] results) {
        // 默认所有邮件都发送成功
        Boolean sendResult = true;
        
        for (Messaging.SendEmailResult res : results) {
            // 对于每个发送结果,检查是否成功
            if (res.isSuccess()) {
                System.debug('Email sent successfully');
            }
            else {
                // 如果失败,将`所有邮件都发送成功`设置为否,并在运行日志中提示
                sendResult = false;
                System.debug('The following errors occurred: ' + res.getErrors());
            }
        }
        
        return sendResult;
    }
}

之后,调用我们自己编写的类------创建一个对象,并用其发送邮件。

java 复制代码
EmailManager em = new EmailManager();
em.sendMail(
    'someone@gmail.com',
    'Test Email',
    'This is a test body'
);

现象

然而,过了很久,我们的Gmail邮箱中都并无邮件显示,哪怕是垃圾邮件分类中。

故障排查

检查日志

这一现象非常反常。我们首先应检查日志,检查是否发送成功。

log 复制代码
66.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DATA_ACCESS,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
Execute Anonymous: EmailManager em = new EmailManager();
Execute Anonymous: em.sendMail(
Execute Anonymous:     'someone@gmail.com',
Execute Anonymous:     'Test Emaill',
Execute Anonymous:     'This is a test body'
Execute Anonymous: );
19:08:22.1 (1715616)|USER_INFO|[EXTERNAL]|...

然而,我们程序打印消息,声称发送成功。

log 复制代码
...
19:08:22.1 (85500107)|USER_DEBUG|[18]|DEBUG|Email sent successfully
...

而且,日志也显示邮件被成功加入邮件发送队列。

log 复制代码
19:08:22.1 (83919155)|EMAIL_QUEUE|[8]|subject: Test Email, bccSender: false, saveAsActivity: true, useSignature: true, toAddresses: [someone@gmail.com], plainTextBody: This is a test body, 
...

这十分诡异。让我们检查一下组织(Org)设置。

检查可交付性设置

每个组织中都有一处可以设置可交付性Deliverability)------控制是否允许邮件发出。

然而,当前设置已经允许向任何邮件发送出站(outbound)邮件。

这十分反常。为了进一步测试,我们直接用系统的测试功能向邮箱发送测试邮件。

然而我们却未曾收到任何内容。

检查邮箱端

也许这是Gmail的问题?让我们更换到Hotmail (Outlook) 试试。将目标邮箱更改为一Outlook邮箱,再次发送测试邮件。

我们立刻收到了邮件,尽管位于垃圾邮件中。

既然如此,让我们重新运行匿名Apex代码,发送调用之前编写的类邮件。

java 复制代码
EmailManager em = new EmailManager();
em.sendMail(
    'someone@hotmail.com',
    'Test Email',
    'This is a test body'
);

我们立刻收到了Apex代码发送的邮件。问题解决。

结论

有时,Gmail的垃圾邮件屏蔽策略过于激进,反而导致了不必要的问题。问题可能出在接收端,而非发送端(Apex)。

相关推荐
Java搬码工34 分钟前
CompletableFuture 完整详解 + 全场景使用案例
java
许心月40 分钟前
Java学习资料网站汇总
java
程序员JerrySUN42 分钟前
Jetson 刷机深度解析:flash.sh vs l4t_initrd_flash.sh(含安全与磁盘加密对比)
linux·网络·arm开发·安全·系统安全
c238561 小时前
第二篇:《测试指挥官:可视化单题自测框架(含 assert 实操)》
java·数据库·c++·算法·安全性测试
辞旧 lekkk1 小时前
【Redis初阶】常见数据类型
开发语言·数据库·c++·redis·学习·缓存·bootstrap
视觉AI1 小时前
VS Code Remote-SSH 连接Jetson踩坑完整解决记录(网段不通+主机密钥变更双重故障)
运维·网络·人工智能·windows·ssh·边缘计算
帅次2 小时前
Kotlin 与 Java 互操作:混合工程里的平台类型与 API 边界
java·开发语言·kotlin·suspend·nullable
明志数科2 小时前
人形机器人格斗场景下的技术挑战:动力学控制、感知融合与实时决策
网络·数据库
酉鬼女又兒2 小时前
零基础入门 DeepSeek V4 Pro API 开发:从环境搭建、消息格式规范到翻译函数实战、少样本提示、多轮对话聊天机器人与常见报错全流程详解指南
大数据·网络·数据库·人工智能·macos·机器人·github
X-⃢_⃢-X2 小时前
一、第一阶段:认识 Spring Boot
java·spring boot·后端