通过电子邮件创建Web条目

Many web applications (asana, basecamp, highrisehq, etc) have this feature. For example: If any user create a task for other user then The task notified to related user.

If task owner reply this email. Replay adress similar to the following:

todo-151280554-ed5b3379c735a9673a469b6b@basecamp.com

this is a virtual email address. When Web application (basecamp) receive this email. Task owner's email will comment for task.

My question is: How to, The web application create a virtual email address and read this mailbox?

How to, I will create a similar feature on my symfony2 based web application?

The regular way is to forward inbound email to a program that parses the email and updates your database appropriately. You symfony2-based web application sees the new state when it's accessed.

Most MTAs can support that, typically by enabling subaddresses and adding an account. For example, if you use Postfix you could create an account called todo set recipient_delimiter to - as in this recipe and write |/home/todo/bin/add-todo-from-email in /home/todo/.forward. Once that is done, sending mail to todo-whatever@example.com or just todo@example.com makes /home/todo/bin/add-todo-from-email be executed.

Programs such as formail/procmail and mailman are examples of open source programs that act on email. If you google for formail you'll find a few examples.

Parsing email is fun, though...

This is typically done by piping inbound email to your PHP scripts. How that's done depends on your server's MTA (Mail Transfer Agent), but tutorials should be available for all the major ones.

If you don't want to do the work of running a MTA, many third-party email providers like Mandrill, Sendgrid, and Postmark will handle the inbound email and make API calls to your server when one is received. I've used Mandrill's and their docs are at http://help.mandrill.com/entries/21699367-Inbound-Email-Processing-Overview

You can achieve this using SendGrid via the Inbound Parse Webhook.

Once set up, any email received on your domain, even virtual addresses, are passed as JSON via a POST request to your app, and any endpoint within the app that you specify, for example to:

http://myappliveshere.com/receive

The JSON you receive is the whole message broken down (list of all fields is here) so you can grab particular fields. In this case you would grab the to field as this would have the virtual address you need.

Then you can lookup the user you need to notify in your DB using that virtual address.

Creating the virtual address could be done in a number of ways, if you're using a model to create users then you could do this using a lifecycle callback before the user is inserted into the DB.

You could create the address using an MD5 hash of the user's first name, last name and a random number, like so:

randomNumber = mt_rand(10,100);
virtualAddress = md5(user.firstname+user.lastname+randomNumber);

You would insert virtualAddress into your User record when they are created in the first instance.

As you can see from how Basecamp do it, they also prepend a type to each virtual address, such as todo in the address: todo-151280554-ed5b3379c735a9673a469b6b@basecamp.com, you could do the same in your app to help with classifying what type of email notification to send the other user.

There is a lot you can do with just the one address, if you break down how they do it:

todo-151280554-ed5b3379c735a9673a469b6b@basecamp.com breaks down as:

todo = type of notification

151280554 = the ID of the todo this is referencing

ed5b3379c735a9673a469b6b = the virtual address of the user