laravel 邮件发送
In project management or support management tools, you will see this a lot: you can reply to an email message and it is automatically visible in a web application. Somehow, these tools were able to get those email messages right into their system.
在项目管理或支持管理工具中,您会看到很多事情:您可以回复电子邮件,并且该电子邮件会在Web应用程序中自动显示。 这些工具以某种方式能够将那些电子邮件直接输入他们的系统。
In this article, we are going to have a look at how we can pipe emails to our Laravel 4 application. For that, we start with a fresh Laravel 4 project, installed through Composer as seen here.
在本文中,我们将研究如何将电子邮件发送到Laravel 4应用程序。 为此,我们打开一个新的Laravel 4项目,通过作曲家安装所看到这里 。
composer create-project laravel/laravel your-project-name --prefer-dist
To be able to get our email into our application, we somehow have to pipe the email through the command line into our application. Luckily, Laravel has a command line tool called Artisan, which is able to perform multiple tasks. To see a list of all tasks that Artisan can run, you can run php artisan list
in the root of your project.
为了使我们的电子邮件进入我们的应用程序,我们必须以某种方式将电子邮件通过命令行传递到我们的应用程序中。 幸运的是,Laravel有一个称为Artisan的命令行工具,它能够执行多个任务。 要查看Artisan可以运行的所有任务的列表,您可以在项目的根目录中运行php artisan list
。
In this case, we want it to perform a very specific task: accept a raw email and use it within our application. Unfortunately, this is not one of the basic functions Artisan can handle. We can easily extend it with a new command: php artisan email:parse
. We’ll then just start up Artisan and perform a certain task, which, in this case, is called email:parse
.
在这种情况下,我们希望它执行非常具体的任务:接收原始电子邮件并在我们的应用程序中使用它。 不幸的是,这不是Artisan可以处理的基本功能之一。 我们可以使用新命令轻松扩展它: php artisan email:parse
。 然后,我们将启动Artisan并执行特定任务,在本例中,该任务称为email:parse
。
Our first step is to create this command. You can create new commands through Artisan’s own command for creating new commands. Just run the following in the root of your project:
我们的第一步是创建此命令。 您可以通过Artisan自己的命令来创建新命令,以创建新命令。 只需在项目的根目录中运行以下命令:
php artisan command:make EmailParserCommand
If everything went smoothly, you will now find a file called EmailParserCommand.php
in the directory app/commands
. Open it up in your favorite editor and have a look at the $name
and $description
properties. We can customize this to whatever we want. By giving it a clear name and description, the command will be listed nicely in the list of artisan commands.
如果一切顺利,您现在将在目录app/commands
找到一个名为EmailParserCommand.php
的文件。 在您最喜欢的编辑器中将其打开,然后查看$name
和$description
属性。 我们可以根据需要定制它。 通过给它一个明确的名称和描述,该命令将在工匠命令列表中很好地列出。
I changed it to this, for example:
我将其更改为此,例如:
/**
* The console command name.
*
* @var string
*/
protected $name = 'email:parse';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Parses an incoming email.';
When we run php artisan email:parse
in the root of our project, you will receive a message that this command is not yet registered. Our next step is to make sure this command is registered within Artisan. Let’s open up the file app/start/artisan.php
and add Artisan::add(new EmailParserCommand);
to the end of the file to register our newly created command. We can now actually run the list command again to see our email:parse
command listed. Notice that your just filled in name and description is displayed here.
当我们在项目的根目录中运行php artisan email:parse
时,您将收到一条消息,提示该命令尚未注册。 我们的下一步是确保此命令在Artisan中已注册。 让我们打开文件app/start/artisan.php
并添加Artisan::add(new EmailParserCommand);
到文件末尾以注册我们新创建的命令。 现在,我们实际上可以再次运行list命令,以查看列出的email:parse
命令。 请注意,您刚才填写的名称和说明将显示在此处。
Whenever the command is called through Artisan, it will always call the fire
method. So initially, we have to add our parsing of the email in here. The email is currently sitting in our IO stream which we can retrieve from php://stdin
. We open up this IO stream and then collect the email in small parts, until we have read the whole stream.
每当通过Artisan调用命令时,它将始终调用fire
方法。 因此,首先,我们必须在此处添加对电子邮件的解析。 该电子邮件当前位于我们的IO流中,我们可以从php://stdin
检索该电子邮件。 我们打开此IO流,然后按小部分收集电子邮件,直到我们阅读了整个流。
/**
* Execute the console command.
*
* @return void
*/
public function fire()
{
// read from stdin
$fd = fopen("php://stdin", "r");
$rawEmail = "";
while (!feof($fd)) {
$rawEmail .= fread($fd, 1024);
}
fclose($fd);
}
The email that was sent to our Artisan command is now residing in the $rawEmail
variable. It is the whole email, containing headers, body and any attachments.
发送给Artisan命令的电子邮件现在位于$rawEmail
变量中。 它是整个电子邮件,包含标题,正文和所有附件。
We have our raw email now, but I would prefer to have the email in multiple parts. I would like to retrieve the headers like subject and the body of the message. We could write our own code which splits all these parts, but someone already created a package which we can use within our application. This package is able to split our entire email into logical parts. Add the following line to your composer.json
file and run composer update
我们现在有原始电子邮件,但我希望将电子邮件分为多个部分。 我想检索标题,例如主题和邮件正文。 我们可以编写自己的代码来拆分所有这些部分,但是有人已经创建了一个包,可以在我们的应用程序中使用它。 该软件包能够将我们的整个电子邮件分为逻辑部分。 将以下行添加到您的composer.json
文件并运行composer update
"messaged/php-mime-mail-parser": "dev-master"
Now we need to make sure that we can actually use this package within our command, so we open up our app/command/EmailParserCommand.php
again and we add these lines to the top:
现在,我们需要确保可以在命令中实际使用此包,因此,我们再次打开app/command/EmailParserCommand.php
并将这些行添加到顶部:
use MimeMailParser\Parser;
Now we can parse our raw email into separate parts. Add the following lines of code to the end of the fire method.
现在,我们可以将原始电子邮件解析为单独的部分。 将以下代码行添加到fire方法的末尾。
$parser = new Parser();
$parser->setText($rawEmail);
$to = $parser->getHeader('to');
$from = $parser->getHeader('from');
$subject = $parser->getHeader('subject');
$text = $parser->getMessageBody('text');
We first create a new parser. Next, we set the raw email as the text of our parser and finally, we call all kinds of different methods to get data from the headers or the body.
我们首先创建一个新的解析器。 接下来,我们将原始电子邮件设置为解析器的文本,最后,我们调用各种不同的方法从标头或正文中获取数据。
You could now easily store your email within a database. For example, if you have an email entity, you could save the email like this to your database:
现在,您可以轻松地将电子邮件存储在数据库中。 例如,如果您有一个电子邮件实体,则可以将这样的电子邮件保存到数据库中:
$email = new Email;
$email->to = $parser->getHeader('to');
$email->from = $parser->getHeader('from');
$email->subject = $parser->getHeader('subject');
$email->text = $parser->getMessageBody('text');
$email->save();
You might even want to store any attachments which are attached to the email on your server. The email parser class can handle any attachments available. First, add the following lines again to the top of the app/command/EmailParserCommand.php
class.
您甚至可能要存储服务器上电子邮件附件中的所有附件。 电子邮件解析器类可以处理任何可用的附件。 首先,将以下几行再次添加到app/command/EmailParserCommand.php
类的顶部。
use Illuminate\Filesystem\Filesystem;
use MimeMailParser\Attachment;
Now we have to extend our fire method with some code which will handle attachments:
现在,我们必须使用一些可以处理附件的代码来扩展我们的fire方法:
$attachments = $parser->getAttachments();
$filesystem = new Filesystem;
foreach ($attachments as $attachment) {
$filesystem->put(public_path() . '/uploads/' . $attachment->getFilename(), $attachment->getContent());
}
Let’s have a look at what this part actually does. The first line retrieves the attachments from the email. The $attachments
variable is an array of attachment objects. Next, we make sure a new FileSystem object is created, which will handle the saving of the files on our server. Then we start to iterate over all attachments. We call the put
method of the FileSystem object, which accepts a path and the content of the file. In this case, we want to add the file to the public/uploads
directory and use the file name the attachment actually has. The second parameter is the content of the actual file.
让我们看看这部分实际上是做什么的。 第一行从电子邮件中检索附件。 $attachments
变量是附件对象的数组。 接下来,我们确保创建了一个新的FileSystem对象,该对象将处理文件在服务器上的保存。 然后,我们开始遍历所有附件。 我们调用FileSystem对象的put
方法,该方法接受路径和文件内容。 在这种情况下,我们希望将文件添加到public/uploads
目录,并使用附件实际具有的文件名。 第二个参数是实际文件的内容。
That’s it! Your files are now stored in public/uploads
. Just make sure that your mail server can actually add files to this directory by setting the correct permissions.
而已! 您的文件现在存储在public/uploads
。 只需通过设置正确的权限来确保您的邮件服务器可以将文件实际添加到此目录中即可。
Until now, we prepared our whole application to retrieve, split and save our email. The code is quite useless, however, if you don’t know how to actually send an email to your newly created Artisan command.
到目前为止,我们已经准备了整个应用程序以检索,拆分和保存我们的电子邮件。 但是,如果您不知道如何实际向新创建的Artisan命令发送电子邮件,该代码将毫无用处。
Below you’ll find different methods to pipe your emails to your application, depending on which tools or mail servers you use. As an example, I want to forward support@peternijssen.nl
to my application, which is located in /var/www/supportcenter
. Note that in the actual command you will see below, I have added --env=local
each time, to make sure Artisan is being run as if we were on a development machine. If you are in production, you can of course remove this part.
在下面,您将根据您使用的工具或邮件服务器找到将电子邮件发送到应用程序的不同方法。 例如,我想将support@peternijssen.nl
转发到位于/var/www/supportcenter
应用程序。 请注意,在下面您将看到的实际命令中,我每次都添加--env=local
,以确保像在开发机器上一样运行Artisan。 如果您正在生产中,当然可以删除此零件。
If you are using CPanel, you can click in the general menu on forwarders
. Add a new forwarder and define which address you would like to forward to your application. Click on advanced settings and choose the pipe to program
options. In the input field, you can insert the following line:
如果您使用的是CPanel,则可以单击forwarders
的常规菜单。 添加一个新的转发器并定义您要转发到您的应用程序的地址。 单击高级设置,然后选择pipe to program
选项。 在输入字段中,您可以插入以下行:
/usr/bin/php -q /var/www/supportcenter/artisan --env=local email:parse
Note that CPanel uses the path relative to your home directory.
请注意,CPanel使用相对于您的主目录的路径。
If on Exim, open up the file /etc/valiases/peternijssen.nl
. Make sure the following line is present within this file:
如果在Exim上 ,则打开文件/etc/valiases/peternijssen.nl
。 确保此文件中包含以下行:
support@peternijssen.nl: “| /usr/bin/php -q /var/www/supportcenter/artisan --env=local email:parse”
Run newaliases
to rebuild the aliases database.
运行newaliases
以重建别名数据库。
On Postfix, make sure that the following lines are present and are uncommented in your /etc/postfix/main.cf
file before continuing:
在Postfix上,请确保在/etc/postfix/main.cf
文件中存在以下行/etc/postfix/main.cf
进行注释:
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
If you had to change the file, reload postfix by running service postfix reload
如果必须更改文件,请通过运行service postfix reload
加载postfix。
We can now create a new alias, which will be piped to our application. Open up /etc/aliases
and add the following line:
现在,我们可以创建一个新别名,该别名将通过管道传递到我们的应用程序。 打开/etc/aliases
并添加以下行:
support@peternijssen.nl: "| /usr/bin/php -q /var/www/supportcenter/artisan --env=local email:parse"
Run newaliases
to rebuild the aliases database.
运行newaliases
以重建别名数据库。
With Sendmail you should first create an alias in the /etc/aliases
file:
使用Sendmail,首先应该在/etc/aliases
文件中创建一个别名:
support: "| /usr/bin/php -q /var/www/supportcenter/artisan --env=local email:parse"
Run newaliases
to rebuild the aliases database. Next, make sure the Artisan file is chmod
to 755, so it’s executable.
运行newaliases
以重建别名数据库。 接下来,确保Artisan文件的chmod
为755,因此它是可执行的。
Lastly, symlink the artisan file and php itself to /etc/smrsh
最后,将工匠文件和php本身符号链接到/ etc / smrsh
ln -s /usr/bin/php /etc/smrsh/php
ln -s /var/www/supportcenter/artisan /etc/smrsh/pipe.php
Depending on your installation, you have to make sure the following file is present:
根据您的安装,您必须确保存在以下文件:
/usr/local/qmail/mailnames/peternijssen.nl/support/.qmail
or:
要么:
/usr/local/qmail/mailnames/peternijssen.nl/.qmail-support
Open up either file and add the following line as content:
打开两个文件,然后添加以下行作为内容:
support@peternijssen.nl: "| /usr/bin/php -q /var/www/supportcenter/artisan --env=local email:parse"
Any framework that has a command line tool available will be able to process your emails. The code provided here is just a basic setup. Depending on your project, you might want to allow only certain email addresses to send an email to your application. Make sure you already filter emails in tools like postfix before piping to your application.
任何具有命令行工具可用的框架都将能够处理您的电子邮件。 此处提供的代码只是基本设置。 根据您的项目,您可能希望仅允许某些电子邮件地址向您的应用程序发送电子邮件。 在传送到应用程序之前,请确保已经使用后缀之类的工具过滤了电子邮件。
If you would like to work with some sort of ticket system, you could easily try to extract a support ticket id from the email subject and based on that, do multiple different actions with the email.
如果您想使用某种票证系统,则可以轻松地尝试从电子邮件主题中提取支持票证ID,然后在此基础上对电子邮件执行多种不同的操作。
Keep a close look on the log file of your mail server. It will give you some hints when the actual piping fails on how to solve it.
仔细查看邮件服务器的日志文件。 当实际管道无法解决时,它将给您一些提示。
翻译自: https://www.sitepoint.com/piping-emails-laravel-application/
laravel 邮件发送