Setting up App Engine to receive email addresses with ids in the address - google-app-engine

I am writing an App Engine app that is supposed to receive emails in this form:
addcontact.someID#my-app.appspotmail.com (someID is an alphanumeric ID that I generate).
I have this in my web.xml thinking it would catch emails that start
with 'addcontact.':
<servlet>
<servlet-name>addNewContactServlet</servlet-name>
<servlet-class>com.mycompany.server.AddNewContactServlet</servlet-
class>
</servlet>
<servlet-mapping>
<servlet-name>addNewContactServlet</servlet-name>
<url-pattern>/_ah/mail/addcontact.*</url-pattern>
</servlet-mapping>
However, both on my dev machine and on google's servers email is not
received. On the dev machine I get this message (I get a similar error
in the deployed log)
Message send failure
HTTP ERROR 404
Problem accessing /_ah/mail/
addcontact.z1vnq3p2bvtfsuzbxg13sfon#myapp.appspotmail.com.
Reason:
NOT_FOUND
I can receive email at fully specified addresses or when I use /_ah/mail/*
The google documentation made me believe it was possible to include partial email addresses in web.xml. Am I not using the wildcard correctly? Does the period have something to do with it? Can this be done somehow?
The reason why I think it should work is the google docs at: http://code.google.com/appengine/docs/java/mail/receiving.html
In it there is this example web.xml file:
<servlet>
<servlet-name>handleowner</servlet-name>
<servlet-class>HandleOwner</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>handleowner</servlet-name>
<url-pattern>/_ah/mail/owner*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>handlesupport</servlet-name>
<servlet-class>HandleSupport</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>handleowner</servlet-name>
<url-pattern>/_ah/mail/support*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>catchallhandler</servlet-name>
<servlet-class>MailCatchallServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>catchallhandler</servlet-name>
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
It looks like the support and owner email addresses are wildcarded to match any that begin with that address.

This should work. Are you sure it's not your handler returning the 404? I would suggest trying a couple of things to figure out the source of the problem:
Set up a catchall handler for /_ah/mail/* and check that works
If it does, set up one for a simpler prefix, or exact address.

Related

Does RemoteApiOption method useServiceAccountCredential works with P12 file?

Does useServiceAccountCredential works with P12 file. I am trying to use it in Java and get error com.google.appengine.repackaged.com.google.api.client.http.HttpResponseException‌​: 302 Found
Yes it does. You need to have an AppEngine app serving the remote API. E.g., you would have a python app, with the following lines in app.yaml:
- url: /remoteapi.*
script: google.appengine.ext.remote_api.handler.application
Or java app with the following in web.xml:
<servlet>
<display-name>Remote API Servlet</display-name>
<servlet-name>RemoteApiServlet</servlet-name>
<servlet-class>com.google.apphosting.utils.remoteapi.RemoteApiServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RemoteApiServlet</servlet-name>
<url-pattern>/remote_api</url-pattern>
</servlet-mapping>
Please note that depending on your client, it might call a bit different url, e.g. /remote_api
Also, if you have deployed the AppEngine app in a module, take that into account in the client code, you would have:
RemoteApiOptions raoptions = new RemoteApiOptions()
.server("my-module-dot-my-project.appspot.com", 443)
.useServiceAccountCredential("my-service-account-id", "my-p12-file.p12");
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(raoptions);
Hope that helps!

Map a servlet to a cron url?

How do I map a servlet to a cron url? This question results from the comment to the answer in the following post: Use Cron jobs with Appengine Endpoints API
In my project the cron job is called as shown in the log in Google App Engine and the url https://[url-commented-out].appspot.com/_ah/api/stocksApi/v1/stocks executes properly when tested in the web browser and returns the proper value.
But I am getting the error 405: HTTP method GET not supported by this URL, when I try to run it in GAE. I've read https://cloud.google.com/appengine/docs/java/config/cron My code in cron.xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<cronentries>
<cron>
<url>/_ah/api/stocksApi/v1/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
</cronentries>
My web.xml is:
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5">
<servlet>
<servlet-name>SystemServiceServlet</servlet-name>
<servlet-class>com.google.api.server.spi.SystemServiceServlet</servlet-class>
<init-param>
<param-name>services</param-name>
<param-value>
[package].StocksEndpoint</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/spi/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SystemServiceServlet</servlet-name>
<url-pattern>/_ah/api/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>cron</web-resource-name>
<url-pattern>/_ah/api/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
I am using Android Studio and have added a backend module by following HelloEndpoints and I have a StocksEndpoint.java
file with a getStocks(); method that returns stocks.
First add a servlet mapping for your cron to web.xml:
<!-- stock servlet -->
<servlet>
<servlet-name>StockServlet</servlet-name>
<servlet-class>YOUR.PACKAGE.HERE.StockServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StockServlet</servlet-name>
<url-pattern>/cron/stocks</url-pattern>
</servlet-mapping>
make sure to update the servlet class for your servlet!
Then finally put the new cron url in your cron.xml:
<cron>
<url>/cron/stocks</url>
<description>Backend Process Stocks</description>
<schedule>every 1 minutes from 11:10 to 11:30</schedule>
<timezone>America/New_York</timezone>
</cron>
Unfortunately urls under /_ah/api are restricted and cannot be called from within your App.
There are a couple of ways to go around this but the most accepted option is usually to use a regular servlet to serve Cron requests rather connecting to the endpoint.

Email bouncing when sending mail to appengine

I have set up appengine to allow incoming mail, and if I have my web.xml file with
<servlet>
<servlet-name>mailhandler</servlet-name>
<servlet-class>VerifyReply</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mailhandler</servlet-name>
<url-pattern>/_ah/mail/*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
it works and runs the VerifyReply servlet, but if I want to limit incoming emails to only those sent to the verifyreply#... email address with (notice the url-pattern is different than above)
<servlet>
<servlet-name>mailhandler</servlet-name>
<servlet-class>VerifyReply</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mailhandler</servlet-name>
<url-pattern>/_ah/mail/v*</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<url-pattern>/_ah/mail/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>admin</role-name>
</auth-constraint>
</security-constraint>
it stops working and I get an email bounce back to the sender. My logs page shows the server ran /_ah/mail/verifyreply#... but it doesn't run the servlet and bounces the email.
Any ideas, I think I am following the guide at https://developers.google.com/appengine/docs/java/mail/receiving
According to the docs, filtering on address is not supported:
When App Engine moved to a standard Java Web Server, the ability to specify richer matching patterns was lost (e.g. one used to be able to specify a url-pattern like /_ah/mail/support*). If such pattern matching is desired, consider using a filter-based approach based on the following code snippets.
It would consider it a bug that specifying the full address does work. The page contains an example on how to do address matching in a mail handler filter (a filter in the servlet sense). You should match the address there and return a 404 if you do not want to accept the message. Or you can just ignore messages you don't want if you don't care about bouncing them.

Remove appstats from web.xml (Java)

it seems ridicolous, but I am unable to remove appstats.
If I remove the following from the web.xml:
<filter>
<filter-name>appstats</filter-name>
<filter-
class>com.google.appengine.tools.appstats.AppstatsFilter</filter-
class>
<init-param>
<param-name>logMessage</param-name>
<param-value>Appstats available: /appstats/details?
time={ID}</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>appstats</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
my static content is not accessible any more and produces a 404 error.
I narrowed it down to the filter and filter-mapping tags, since I
removed the other tags from
http://code.google.com/appengine/docs/java/tools/appstats.html
step by step.
Only if those specific tags remain in the web.xml, the static content
becomes inaccessible after deployment.
Last night I had strange errors in the logs which are linked to source
files of appstats.
Hopefully you guys can help me.
Greets
upscale
Did you also delete the servlet definition :
<servlet>
<servlet-name>appstats</servlet-name>
<servlet-class>com.google.appengine.tools.appstats.AppstatsServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>appstats</servlet-name>
<url-pattern>/appstats/*</url-pattern>
</servlet-mapping>
Also, if you included it, you should clean up your appengine-web.xml :
<admin-console>
<page name="Appstats" url="/appstats" />
</admin-console>

BlobStore Redirects being ignored by ServletModule wired servlets

After the blobstore handles the upload request of a file it redirects to the url it is given, in this case "/upload". If I configure the UploadServlet url in web.xml like this:
<servlet>
<servlet-name>uploadServlet</servlet-name>
<servlet-class>com.....servlet.UploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadServlet</servlet-name>
<url-pattern>/upload</url-pattern>
</servlet-mapping>
It works. If I use Guice to wire the servlet:
serve("/upload").with(UploadServlet.class);
I get the error:
Problem accessing /upload. Reason:NOT_FOUND
It seems as though the com.google.inject.servlet.ServletModule does not handle redirects. Is there a way around this?
I have struggled with the same issue myself today. This solved my problem and may be related:
https://groups.google.com/forum/#!topic/google-appengine-java/oqfvEmZGrdw
In dev mode, the blobstore service uses
RequestDispatcher.forward() rather than an HTTP request:
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Of course, may be too late for you but for others it might help :-)

Resources