我带着一个问题来找你,在谷歌搜索了几个小时之后,我在谷歌上找不到解决办法。
我希望能够通过使用不同的SMTP电子邮件配置发送电子邮件,我可以添加或更改在运行时。我正在建设一个网站,其中托管了许多项目,为许多客户,我们需要能够发送电子邮件代表他们。我知道我可以在.env文件中设置不同的配置,但是这个解决方案还不够好,因为我希望将配置保存在数据库中,这样就可以轻松地查询/更新它们了。
一种解决方案是从本教程中使用此方法。它使用Swift Mailer创建一个返回新mailer对象的方法,但在Laravel 9中似乎不起作用。显然,Swift mailer不再维护,已经由Symfony mailer继承。不幸的是,我无法以我刚才描述的方式使用新的Symfony Mailer,不过如果我能让它工作的话,我肯定会更喜欢它。
我想知道是否可以在Symfony Mailer中使用同样的方法?当我使用与本教程中相同的代码时,会出现以下错误:
Class "Swift_SmtpTransport" not found我将类添加到命名空间中,并将语法从new Swift_SmtpTransport更改为\Swift_SmtpTransport::newInstance,但这不能解决错误。
如果有人有任何想法/建议,我会非常感激的!我真没想到这么简单的事情会这么难。
发布于 2022-11-15 19:06:34
背景故事
在我公司的网站上,几乎每个用户(雇员)都有自己的电子邮件配置,有些模型也有自己的电子邮件配置。所有配置都保存到数据库表中,以便在运行时更改/添加配置。所有电子邮件都被发送到队列中,并由队列工作人员处理。
我将尝试提供一个清晰的示例,说明如何在运行时更改配置。我删掉了大部分不必要的代码,并修改了一些变量和文本,使其易于阅读。
逻辑
例如,如果我希望从经过身份验证的用户的电子邮件中发送电子邮件,在他们提交了某个表单之后,我会这样做:
$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类:
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函数和其他不相关的东西一样,只生成这样的新作业:
function sendEmailFromConfig($data, $config_id) {
$config = EmailConfiguration::find($config_id);
dispatch(new SendEmailJob($data, $config));
}注意,$data值来自作为第一个参数传递的mailable。
SendEmailJob语法就像在laravel文档中可以找到的任何其他工作一样,但神奇之处在于:
$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的初学者,我认为可能有一个更好的解决方案,我只是找不到它。我还想说,我遗漏了很多代码(例如,一些尝试捕获、记录函数调用、一些特定于应用程序的功能等),我只想展示核心逻辑。
发布于 2022-07-25 20:44:12
这对我有用..。
在config/mail.php文件中,可以按以下方式定义不同的帐户:
'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。
Mail::mailer('otherMailer')->to('person@something.com')->send(new SendLetter($sendMail));希望这能有所帮助。
发布于 2022-04-19 11:13:25
Laravel9.x正在使用可能导致这种冲突的symfony/mailer。相反,您可以使用mailer()选项动态更改邮件驱动程序。
Mail::mailer('postmark')
->to($request->user())
->send(new OrderShipped($order));您可以在文档上找到详细信息。
更新的
我查了一下symfony/mailer 文档,我想这就是你想要的。您也可以使用动态SMTP详细信息动态构建自己的传输。
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);https://stackoverflow.com/questions/71923673
复制相似问题