首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel 9动态电子邮件配置

Laravel 9动态电子邮件配置
EN

Stack Overflow用户
提问于 2022-04-19 10:48:19
回答 3查看 1.3K关注 0票数 0

我带着一个问题来找你,在谷歌搜索了几个小时之后,我在谷歌上找不到解决办法。

我希望能够通过使用不同的SMTP电子邮件配置发送电子邮件,我可以添加或更改在运行时。我正在建设一个网站,其中托管了许多项目,为许多客户,我们需要能够发送电子邮件代表他们。我知道我可以在.env文件中设置不同的配置,但是这个解决方案还不够好,因为我希望将配置保存在数据库中,这样就可以轻松地查询/更新它们了。

一种解决方案是从本教程中使用此方法。它使用Swift Mailer创建一个返回新mailer对象的方法,但在Laravel 9中似乎不起作用。显然,Swift mailer不再维护,已经由Symfony mailer继承。不幸的是,我无法以我刚才描述的方式使用新的Symfony Mailer,不过如果我能让它工作的话,我肯定会更喜欢它。

我想知道是否可以在Symfony Mailer中使用同样的方法?当我使用与本教程中相同的代码时,会出现以下错误:

代码语言:javascript
复制
Class "Swift_SmtpTransport" not found

我将类添加到命名空间中,并将语法从new Swift_SmtpTransport更改为\Swift_SmtpTransport::newInstance,但这不能解决错误。

如果有人有任何想法/建议,我会非常感激的!我真没想到这么简单的事情会这么难。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-11-15 19:06:34

背景故事

在我公司的网站上,几乎每个用户(雇员)都有自己的电子邮件配置,有些模型也有自己的电子邮件配置。所有配置都保存到数据库表中,以便在运行时更改/添加配置。所有电子邮件都被发送到队列中,并由队列工作人员处理。

我将尝试提供一个清晰的示例,说明如何在运行时更改配置。我删掉了大部分不必要的代码,并修改了一些变量和文本,使其易于阅读。

逻辑

例如,如果我希望从经过身份验证的用户的电子邮件中发送电子邮件,在他们提交了某个表单之后,我会这样做:

代码语言:javascript
复制
$email_data = array(
    'header'=>__('Info') , 
    'subheader'=>__('This is an automated email. Do not reply.'),
    'mail_to'=> 'test@test.test'
    'content'=>   ...
     );
    
    sendEmailFromConfig(new mailTemplate($email_data), $auth_user->email_config_id);

sendEmailFromConfig is函数来自helper类,因此它是我在mailTemplate中传递的第一个参数的可以在任何地方打电话。,该参数是从mailable派生的,带有我希望它使用的自定义数据。第二个参数是电子邮件配置id。

mailtemplate类:

代码语言:javascript
复制
class mailTemplate extends Mailable
{
    use Queueable, SerializesModels;

    public $data;
    
    public function __construct($data)
    {
        $this->data = $data; 

    }

    public function build()
    {   
        // optional data (for view)
        $email_data['url'] = $this->data['url'];
        
        $email_data['data1'] = $this->data['data1'];
        $email_data['data2'] = $this->data['data2'];
        $email_data['data3'] = $this->data['data3'];


        // required
        $email_data['view_name'] = 'emails.content.mailTemplate'; 
        $email_data['reply_to'] = isset($this->data['reply_to']) ? $this->data['reply_to'] : '';
        $email_data['cc'] = [];
        $email_data['bcc'] = [];
        $email_data['email_to'] = isset($this->data['email_to']);
        $email_data['email_subject'] = $this->data['email_subject'];
        
        
        logEmail($this->data); // Another helper function to log sent emails
        
        return $this
            ->subject($email_data['email_subject'])
            ->to($email_data['email_to'])
            ->cc($email_data['cc'])
            ->bcc($email_data['bcc'])
            ->replyTo($email_data['reply_to'])
            ->view($email_data['view_name'], ['email_data' => $email_data]);
    }
    
}

sendEmailFromConfig函数和其他不相关的东西一样,只生成这样的新作业:

代码语言:javascript
复制
function sendEmailFromConfig($data, $config_id) {
    $config = EmailConfiguration::find($config_id); 
    dispatch(new SendEmailJob($data, $config));
}

注意,$data值来自作为第一个参数传递的mailable。

SendEmailJob语法就像在laravel文档中可以找到的任何其他工作一样,但神奇之处在于:

代码语言:javascript
复制
    $temp_config_name = 'smtp_rand_' . str::random(5); // every email is sent from different config to avoid weird bugs
    
    config()->set([
        'mail.mailers.' . $temp_config_name . '.transport' => 'smtp',
        'mail.mailers.' . $temp_config_name . '.host' => $config->host,
        'mail.mailers.' . $temp_config_name . '.port' => $config->port,
        'mail.mailers.' . $temp_config_name . '.username' => $config->username,
        'mail.mailers.' . $temp_config_name . '.password' => $config->password,
        'mail.mailers.' . $temp_config_name . '.encryption' => $config->encryption,
        'mail.mailers.' . $temp_config_name . '.from' => 
        [
            //FIXME TWO BOTTOM LINES MUST BE GIVEN A DO OVER PROBABLY
            'address' => $config->from_address,
            'name' => $config->from_name),
        ],
        'mail.mailers.' . $temp_config_name . '.auth_mode' => $config->auth_mode,
        ]);

Mail::mailer($temp_config_name)->send($data); // sends email

这将在将作业发送到辅助服务(它处理队列)之前在缓存中设置一个新的配置。在没有队列的情况下,这也应该有效--在这种情况下,您应该首先尝试不使用$temp_config_name变量。

这个解决方案可能被认为是错误的,它肯定不是很漂亮,但这是我设法使它正常工作的唯一方法。注意$temp_config_name在每个新作业中是如何变化的,即使相同的电子邮件配置发送相同的数据--这修复了一个错误。错误在于,在第一次从配置中成功发送电子邮件之后,下一封电子邮件就不会发送出去了。我不知道为什么会发生这个错误,但是每次设置一个不同的配置名称都会解决这个问题。

我应该提一下,每次你发邮件时,这些临时的吐露都会堆积在缓存里。我还没有时间找到一个好的解决方案,如果有人知道该做什么,那么请告诉(或者如果你有一个比我正在做的更好的解决方案)。我知道,重新启动员工服务将自动删除这些临时信任。我想一种方法是在每完成x个作业之后重新启动工人服务。

我也想说我是PHP和Laravel的初学者,我认为可能有一个更好的解决方案,我只是找不到它。我还想说,我遗漏了很多代码(例如,一些尝试捕获、记录函数调用、一些特定于应用程序的功能等),我只想展示核心逻辑。

票数 0
EN

Stack Overflow用户

发布于 2022-07-25 20:44:12

这对我有用..。

在config/mail.php文件中,可以按以下方式定义不同的帐户:

代码语言:javascript
复制
'mailers' => [
        'smtp' => [
            'transport' => 'smtp',
            'host' => 'smtp.google',
            'port' => 465,
            'encryption' => 'ssl',
            'username' => 'youraccount@something.com',
            'password' => 'password',
            'timeout' => null,
            'local_domain' => env('MAIL_EHLO_DOMAIN'),
        ],
        'OtherMailer' => [
            'transport' => 'smtp',
            'host' => 'smtp.gmail.com',
            'port' => '465',
            'encryption' => 'ssl',
            'username' => 'otheraccount@something.com',
            'password' => 'password',
            'timeout' => null,
            'local_domain' => env('MAIL_EHLO_DOMAIN'),
        ],

接下来,在控制器或模型中,您可以设置要使用的mailer。

代码语言:javascript
复制
Mail::mailer('otherMailer')->to('person@something.com')->send(new SendLetter($sendMail));

希望这能有所帮助。

票数 2
EN

Stack Overflow用户

发布于 2022-04-19 11:13:25

Laravel9.x正在使用可能导致这种冲突的symfony/mailer。相反,您可以使用mailer()选项动态更改邮件驱动程序。

代码语言:javascript
复制
Mail::mailer('postmark')
        ->to($request->user())
        ->send(new OrderShipped($order));

您可以在文档上找到详细信息。

更新的

我查了一下symfony/mailer 文档,我想这就是你想要的。您也可以使用动态SMTP详细信息动态构建自己的传输。

代码语言:javascript
复制
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;

$transport = Transport::fromDsn('smtp://localhost');
$mailer = new Mailer($transport);

$email = (new Email())
    ->from('hello@example.com')
    ->to('you@example.com')
    //->cc('cc@example.com')
    //->bcc('bcc@example.com')
    //->replyTo('fabien@example.com')
    //->priority(Email::PRIORITY_HIGH)
    ->subject('Time for Symfony Mailer!')
    ->text('Sending emails is fun again!')
    ->html('<p>See Twig integration for better HTML integration!</p>');

$mailer->send($email);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71923673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档