Receiving Email

Email messages are sent to your app as HTTP requests. To process incoming email messages, you must associate email addresses with servlets in your application configuration, and then include the servlet code with your app. The incoming email generates HTTP requests that are passed to the appropriate servlets for handling.

Configuring your application to receive email

When you create a new application, incoming email is disabled by default. If you don't explicitly enable incoming email messages sent to your app are ignored.

To enable the incoming email service, modify the appengine-web.xml and web.xml configuration files:

Enabling email in appengine-web.xml

Modify appengine-web.xml by adding an inbound-services section that enables the incoming email service:

 <inbound-services>  
<!--  
Used  
to  
handle  
incoming  
mail.  
-->  
<service>mail</service>  
<!--  
Used  
to  
handle  
bounced  
mail  
notifications.  
-->  
<service>mail_bounce</service>
</inbound-services> 

Email messages are sent to your app as HTTP POST requests using the following URL:

  / 
 _ah 
 / 
 mail 
 / 
< ADDRESS 
> 

where <ADDRESS> is a full email address, including domain name. Note that even if your app is deployed on a custom domain, your app can't receive email sent to addresses in that domain.

Enabling email in web.xml

Modify web.xml by mapping email URLs to servlets:

 <servlet>  
<servlet-name>mailhandler</servlet-name>  
<servlet-class>com.example.appengine.mail.MailHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>  
<servlet-name>mailhandler</servlet-name>  
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
<security-constraint>  
<web-resource-collection>  
<web-resource-name>mail</web-resource-name>  
<url-pattern>/_ah/mail/*</url-pattern>  
</web-resource-collection>  
<auth-constraint>  
<role-name>admin</role-name>  
</auth-constraint>
</security-constraint> 

In the above snippets, /_ah/mail/* matches all email addressed to the app. Mail servlets run in the currently serving version of your app in App Engine.

Pattern-based dispatching of incoming messages

If your app uses pattern matching, consider using a filter-based approach based on the following code snippets.

Concrete handler

  public 
  
 class 
 HandleDiscussionEmail 
  
 extends 
  
 MailHandlerBase 
  
 { 
  
 private 
  
 static 
  
 final 
  
 Logger 
  
 log 
  
 = 
  
 Logger 
 . 
 getLogger 
 ( 
 HandleDiscussionEmail 
 . 
 class 
 . 
 getName 
 ()); 
  
 public 
  
 HandleDiscussionEmail 
 () 
  
 { 
  
 super 
 ( 
 "discuss-(.*)@(.*)" 
 ); 
  
 } 
  
 @Override 
  
 protected 
  
 boolean 
  
 processMessage 
 ( 
 HttpServletRequest 
  
 req 
 , 
  
 HttpServletResponse 
  
 res 
 ) 
  
 throws 
  
 ServletException 
  
 { 
  
 log 
 . 
 info 
 ( 
 "Received e-mail sent to discuss list." 
 ); 
  
 MimeMessage 
  
 msg 
  
 = 
  
 getMessageFromRequest 
 ( 
 req 
 ); 
  
 Matcher 
  
 match 
  
 = 
  
 getMatcherFromRequest 
 ( 
 req 
 ); 
  
 // ... 
  
 return 
  
 true 
 ; 
  
 } 
 } 
 

The above concrete handler is registered using the following snippet in web.xml :

 <filter>  
<filter-name>HandleDiscussionEmail</filter-name>  
<filter-class>com.example.appengine.mail.HandleDiscussionEmail</filter-class>
</filter>
<filter-mapping>  
<filter-name>HandleDiscussionEmail</filter-name>  
<url-pattern>/_ah/mail/*</url-pattern>
</filter-mapping> 

Note that security-constraint directives are not possible on filters; security policies on the handler will have to be introduced some other way.

Abstract handler

  public 
  
 abstract 
  
 class 
 MailHandlerBase 
  
 implements 
  
 Filter 
  
 { 
  
 private 
  
 Pattern 
  
 pattern 
  
 = 
  
 null 
 ; 
  
 protected 
  
 MailHandlerBase 
 ( 
 String 
  
 pattern 
 ) 
  
 { 
  
 if 
  
 ( 
 pattern 
  
 == 
  
 null 
  
 || 
  
 pattern 
 . 
 trim 
 (). 
 length 
 () 
  
 == 
  
 0 
 ) 
  
 { 
  
 throw 
  
 new 
  
 IllegalArgumentException 
 ( 
 "Expected non-empty regular expression" 
 ); 
  
 } 
  
 this 
 . 
 pattern 
  
 = 
  
 Pattern 
 . 
 compile 
 ( 
 "/_ah/mail/" 
 + 
 pattern 
 ); 
  
 } 
  
 @Override 
  
 public 
  
 void 
  
 init 
 ( 
 FilterConfig 
  
 config 
 ) 
  
 throws 
  
 ServletException 
  
 { 
  
 } 
  
 @Override 
  
 public 
  
 void 
  
 destroy 
 () 
  
 { 
  
 } 
  
 /** 
 * Process the message. A message will only be passed to this method 
 * if the servletPath of the message (typically the recipient for 
 * appengine) satisfies the pattern passed to the constructor. If 
 * the implementation returns false, control is passed 
 * to the next filter in the chain. If the implementation returns 
 * true, the filter chain is terminated. 
 * 
 * The Matcher for the pattern can be retrieved via 
 * getMatcherFromRequest (e.g. if groups are used in the pattern). 
 */ 
  
 protected 
  
 abstract 
  
 boolean 
  
 processMessage 
 ( 
 HttpServletRequest 
  
 req 
 , 
  
 HttpServletResponse 
  
 res 
 ) 
  
 throws 
  
 ServletException 
 ; 
  
 @Override 
  
 public 
  
 void 
  
 doFilter 
 ( 
 ServletRequest 
  
 sreq 
 , 
  
 ServletResponse 
  
 sres 
 , 
  
 FilterChain 
  
 chain 
 ) 
  
 throws 
  
 IOException 
 , 
  
 ServletException 
  
 { 
  
 HttpServletRequest 
  
 req 
  
 = 
  
 ( 
 HttpServletRequest 
 ) 
  
 sreq 
 ; 
  
 HttpServletResponse 
  
 res 
  
 = 
  
 ( 
 HttpServletResponse 
 ) 
  
 sres 
 ; 
  
 MimeMessage 
  
 message 
  
 = 
  
 getMessageFromRequest 
 ( 
 req 
 ); 
  
 Matcher 
  
 m 
  
 = 
  
 applyPattern 
 ( 
 req 
 ); 
  
 if 
  
 ( 
 m 
  
 != 
  
 null 
 && 
 processMessage 
 ( 
 req 
 , 
  
 res 
 )) 
  
 { 
  
 return 
 ; 
  
 } 
  
 chain 
 . 
 doFilter 
 ( 
 req 
 , 
  
 res 
 ); 
  
 // Try the next one 
  
 } 
  
 private 
  
 Matcher 
  
 applyPattern 
 ( 
 HttpServletRequest 
  
 req 
 ) 
  
 { 
  
 Matcher 
  
 m 
  
 = 
  
 pattern 
 . 
 matcher 
 ( 
 req 
 . 
 getServletPath 
 ()); 
  
 if 
  
 ( 
 ! 
 m 
 . 
 matches 
 ()) 
  
 m 
  
 = 
  
 null 
 ; 
  
 req 
 . 
 setAttribute 
 ( 
 "matcher" 
 , 
  
 m 
 ); 
  
 return 
  
 m 
 ; 
  
 } 
  
 protected 
  
 Matcher 
  
 getMatcherFromRequest 
 ( 
 ServletRequest 
  
 req 
 ) 
  
 { 
  
 return 
  
 ( 
 Matcher 
 ) 
  
 req 
 . 
 getAttribute 
 ( 
 "matcher" 
 ); 
  
 } 
  
 protected 
  
 MimeMessage 
  
 getMessageFromRequest 
 ( 
 ServletRequest 
  
 req 
 ) 
  
 throws 
  
 ServletException 
  
 { 
  
 MimeMessage 
  
 message 
  
 = 
  
 ( 
 MimeMessage 
 ) 
  
 req 
 . 
 getAttribute 
 ( 
 "mimeMessage" 
 ); 
  
 if 
  
 ( 
 message 
  
 == 
  
 null 
 ) 
  
 { 
  
 try 
  
 { 
  
 Properties 
  
 props 
  
 = 
  
 new 
  
 Properties 
 (); 
  
 Session 
  
 session 
  
 = 
  
 Session 
 . 
 getDefaultInstance 
 ( 
 props 
 , 
  
 null 
 ); 
  
 message 
  
 = 
  
 new 
  
 MimeMessage 
 ( 
 session 
 , 
  
 req 
 . 
 getInputStream 
 ()); 
  
 req 
 . 
 setAttribute 
 ( 
 "mimeMessage" 
 , 
  
 message 
 ); 
  
 } 
  
 catch 
  
 ( 
 MessagingException 
  
 e 
 ) 
  
 { 
  
 throw 
  
 new 
  
 ServletException 
 ( 
 "Error processing inbound message" 
 , 
  
 e 
 ); 
  
 } 
  
 catch 
  
 ( 
 IOException 
  
 e 
 ) 
  
 { 
  
 throw 
  
 new 
  
 ServletException 
 ( 
 "Error processing inbound message" 
 , 
  
 e 
 ); 
  
 } 
  
 } 
  
 return 
  
 message 
 ; 
  
 } 
 } 
 

Handling incoming email

The JavaMail API includes the MimeMessage class which you can use to parse incoming email messages. MimeMessage has a constructor that accepts a java.io.InputStream and a JavaMail session, which can have an empty configuration.

Create a MimeMessage instance like this:

  import 
  
 java.io.IOException 
 ; 
 import 
  
 java.util.logging.Logger 
 ; 
 import 
  
 java.util.Properties 
 ; 
 import 
  
 javax.mail.MessagingException 
 ; 
 import 
  
 javax.mail.Session 
 ; 
 import 
  
 javax.mail.internet.MimeMessage 
 ; 
 import 
  
 javax.servlet.http.HttpServlet 
 ; 
 import 
  
 javax.servlet.http.HttpServletRequest 
 ; 
 import 
  
 javax.servlet.http.HttpServletResponse 
 ; 
 public 
  
 class 
 MailHandlerServlet 
  
 extends 
  
 HttpServlet 
  
 { 
  
 private 
  
 static 
  
 final 
  
 Logger 
  
 log 
  
 = 
  
 Logger 
 . 
 getLogger 
 ( 
 MailHandlerServlet 
 . 
 class 
 . 
 getName 
 ()); 
  
 @Override 
  
 public 
  
 void 
  
 doPost 
 ( 
 HttpServletRequest 
  
 req 
 , 
  
 HttpServletResponse 
  
 resp 
 ) 
  
 throws 
  
 IOException 
  
 { 
  
 Properties 
  
 props 
  
 = 
  
 new 
  
 Properties 
 (); 
  
 Session 
  
 session 
  
 = 
  
 Session 
 . 
 getDefaultInstance 
 ( 
 props 
 , 
  
 null 
 ); 
  
 try 
  
 { 
  
 MimeMessage 
  
 message 
  
 = 
  
 new 
  
 MimeMessage 
 ( 
 session 
 , 
  
 req 
 . 
 getInputStream 
 ()); 
  
 log 
 . 
 info 
 ( 
 "Received mail message." 
 ); 
  
 } 
  
 catch 
  
 ( 
 MessagingException 
  
 e 
 ) 
  
 { 
  
 // ... 
  
 } 
  
 // ... 
  
 } 
 } 
 

You can then use various methods to parse the message object:

  • Call getFrom() to return the sender of the message.
  • Call getContentType() to extract the message content type. The getContent() method returns an object that implements the Multipart interface.
  • Call getCount() to determine the number of parts
  • Call getBodyPart(int index) to return a particular body part.

After you set up your app to handle incoming email, you can use the development server console to simulate incoming email messages. To learn more, including how to start the development server, see The Java Development Server . After you start your application in the local development server, you can access your application by visiting the URL http://localhost:8888/_ah/admin/ , replacing the value 8888 with whatever port you are using if you don't use the default port for the local development server.

In the development server, click Inbound Mail on the left side, fill out the form that appears, and click Send Email.

Create a Mobile Website
View Site in Mobile | Classic
Share by: