diff --git a/appengine/analytics/pom.xml b/appengine/analytics/pom.xml
new file mode 100644
index 00000000000..57c775a3b73
--- /dev/null
+++ b/appengine/analytics/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+ war
+ 1.0-SNAPSHOT
+ com.example.appengine
+ appengine-analytics
+
+
+ doc-samples
+ com.google.cloud
+ 1.0.0
+ ../..
+
+
+
+
+ com.google.appengine
+ appengine-api-1.0-sdk
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.1
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ jar
+ provided
+
+
+
+
+ ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
+
+
+
+ com.google.appengine
+ appengine-maven-plugin
+ ${appengine.sdk.version}
+
+
+ org.apache.maven.plugins
+ 3.3
+ maven-compiler-plugin
+
+
+ 1.7
+
+
+
+
+
diff --git a/appengine/analytics/src/main/java/com/example/appengine/analytics/AnalyticsServlet.java b/appengine/analytics/src/main/java/com/example/appengine/analytics/AnalyticsServlet.java
new file mode 100644
index 00000000000..ee8f5a678c4
--- /dev/null
+++ b/appengine/analytics/src/main/java/com/example/appengine/analytics/AnalyticsServlet.java
@@ -0,0 +1,64 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.analytics;
+
+import com.google.appengine.api.urlfetch.URLFetchService;
+import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
+
+import org.apache.http.client.utils.URIBuilder;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START example]
+@SuppressWarnings("serial")
+public class AnalyticsServlet extends HttpServlet {
+
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ ServletException {
+ String trackingId = System.getenv("GA_TRACKING_ID");
+ URIBuilder builder = new URIBuilder();
+ builder.setScheme("http").setHost("www.google-analytics.com").setPath("/collect")
+ .addParameter("v", "1") // API Version.
+ .addParameter("tid", trackingId) // Tracking ID / Property ID.
+ // Anonymous Client Identifier. Ideally, this should be a UUID that
+ // is associated with particular user, device, or browser instance.
+ .addParameter("cid", "555")
+ .addParameter("t", "event") // Event hit type.
+ .addParameter("ec", "example") // Event category.
+ .addParameter("ea", "test action"); // Event action.
+ URI uri = null;
+ try {
+ uri = builder.build();
+ } catch (URISyntaxException e) {
+ throw new ServletException("Problem building URI", e);
+ }
+ URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
+ URL url = uri.toURL();
+ fetcher.fetch(url);
+ resp.getWriter().println("Event tracked.");
+ }
+}
+// [END example]
diff --git a/appengine/analytics/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/analytics/src/main/webapp/WEB-INF/appengine-web.xml
new file mode 100644
index 00000000000..efa1efaa42f
--- /dev/null
+++ b/appengine/analytics/src/main/webapp/WEB-INF/appengine-web.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ YOUR-PROJECT-ID
+ YOUR-VERSION-ID
+ true
+
+
+
+
+
diff --git a/appengine/analytics/src/main/webapp/WEB-INF/web.xml b/appengine/analytics/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..1565774bf96
--- /dev/null
+++ b/appengine/analytics/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ analytics
+ com.example.appengine.analytics.AnalyticsServlet
+
+
+ analytics
+ /
+
+
+
diff --git a/appengine/helloworld/pom.xml b/appengine/helloworld/pom.xml
index fc4dd0842d4..ebb478cf799 100644
--- a/appengine/helloworld/pom.xml
+++ b/appengine/helloworld/pom.xml
@@ -1,4 +1,3 @@
-
-
+4.0.0war1.0-SNAPSHOTcom.example.appengineappengine-helloworld
-
com.google.clouddoc-samples
@@ -32,7 +29,6 @@ Copyright 2015 Google Inc. All Rights Reserved.
javax.servletservlet-api
- 2.5jarprovided
@@ -50,6 +46,7 @@ Copyright 2015 Google Inc. All Rights Reserved.
1.7
+
com.google.appengineappengine-maven-plugin
diff --git a/appengine/memcache/pom.xml b/appengine/memcache/pom.xml
new file mode 100644
index 00000000000..b10bb793e3d
--- /dev/null
+++ b/appengine/memcache/pom.xml
@@ -0,0 +1,73 @@
+
+
+ 4.0.0
+ war
+ 1.0-SNAPSHOT
+ com.example.appengine
+ appengine-memcache
+
+
+ doc-samples
+ com.google.cloud
+ 1.0.0
+ ../..
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ jar
+ provided
+
+
+
+
+
+ com.google.appengine
+ appengine-api-1.0-sdk
+
+
+ com.googlecode.xmemcached
+ xmemcached
+ 2.0.0
+
+
+
+
+
+ ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
+
+
+
+ com.google.appengine
+ appengine-maven-plugin
+ ${appengine.sdk.version}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.3
+
+
+ 1.7
+
+
+
+
+
diff --git a/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheServlet.java b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheServlet.java
new file mode 100644
index 00000000000..0d817e25af8
--- /dev/null
+++ b/appengine/memcache/src/main/java/com/example/appengine/memcache/MemcacheServlet.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.memcache;
+
+import com.google.appengine.api.memcache.ErrorHandlers;
+import com.google.appengine.api.memcache.MemcacheService;
+import com.google.appengine.api.memcache.MemcacheServiceFactory;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.util.logging.Level;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START example]
+@SuppressWarnings("serial")
+public class MemcacheServlet extends HttpServlet {
+
+ @Override
+ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ ServletException {
+ MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService();
+ syncCache.setErrorHandler(ErrorHandlers.getConsistentLogAndContinue(Level.INFO));
+ String key = "count";
+ byte[] value;
+ long count = 1;
+ value = (byte[]) syncCache.get(key);
+ if (value == null) {
+ value = BigInteger.valueOf(count).toByteArray();
+ syncCache.put(key, value);
+ } else {
+ // Increment value
+ count = new BigInteger(value).longValue();
+ count++;
+ value = BigInteger.valueOf(count).toByteArray();
+ // Put back in cache
+ syncCache.put(key, value);
+ }
+
+ // Output content
+ resp.setContentType("text/plain");
+ resp.getWriter().print("Value is " + count + "\n");
+ }
+}
+// [END example]
diff --git a/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml
new file mode 100644
index 00000000000..ad825e10799
--- /dev/null
+++ b/appengine/memcache/src/main/webapp/WEB-INF/appengine-web.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+ YOUR-PROJECT-ID
+ YOUR-VERSION-ID
+ true
+
+
diff --git a/appengine/memcache/src/main/webapp/WEB-INF/web.xml b/appengine/memcache/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..de381555233
--- /dev/null
+++ b/appengine/memcache/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ memcache
+ com.example.appengine.memcache.MemcacheServlet
+
+
+ memcache
+ /
+
+
+
diff --git a/appengine/sendgrid/README.md b/appengine/sendgrid/README.md
new file mode 100644
index 00000000000..4a76dd9fd2b
--- /dev/null
+++ b/appengine/sendgrid/README.md
@@ -0,0 +1,13 @@
+# Java SendGrid email sample for Google Managed VMs
+This sample demonstrates how to use [SendGrid](https://www.sendgrid.com) on Google Managed VMs
+For more information about SendGrid, see their [documentation](https://sendgrid.com/docs/User_Guide/index.html).
+## Setup
+Before you can run or deploy the sample, you will need to do the following:
+1. [Create a SendGrid Account](http://sendgrid.com/partner/google). As of September 2015, Google users start with 25,000 free emails per month.
+1. Configure your SendGrid settings in the environment variables section in ``src/main/appengine/app.yaml``.
+## Running locally
+You can run the application locally and send emails from your local machine. You
+will need to set environment variables before starting your application:
+ $ export SENDGRID_API_KEY=[your-sendgrid-api-key]
+ $ export SENDGRID_SENDER=[your-sendgrid-sender-email-address]
+ $ mvn clean jetty:run
diff --git a/appengine/sendgrid/pom.xml b/appengine/sendgrid/pom.xml
new file mode 100644
index 00000000000..e3566810891
--- /dev/null
+++ b/appengine/sendgrid/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+ war
+ 1.0-SNAPSHOT
+ com.example.appengine
+ appengine-sendgrid
+
+
+ doc-samples
+ com.google.cloud
+ 1.0.0
+ ../..
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ jar
+ provided
+
+
+
+ com.sendgrid
+ sendgrid-java
+ 2.2.2
+
+
+
+
+
+ ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
+
+
+
+ com.google.appengine
+ appengine-maven-plugin
+ ${appengine.sdk.version}
+
+
+ org.apache.maven.plugins
+ 3.3
+ maven-compiler-plugin
+
+
+ 1.7
+
+
+
+
+
diff --git a/appengine/sendgrid/src/main/java/com/example/appengine/sendgrid/SendEmailServlet.java b/appengine/sendgrid/src/main/java/com/example/appengine/sendgrid/SendEmailServlet.java
new file mode 100644
index 00000000000..63a9cbd5434
--- /dev/null
+++ b/appengine/sendgrid/src/main/java/com/example/appengine/sendgrid/SendEmailServlet.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.sendgrid;
+
+import com.sendgrid.SendGrid;
+import com.sendgrid.SendGridException;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START example]
+@SuppressWarnings("serial")
+@WebServlet(name = "sendemail", value = "/send/email")
+public class SendEmailServlet extends HttpServlet {
+
+ @Override
+ public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ ServletException {
+ final String sendgridApiKey = System.getenv("SENDGRID_API_KEY");
+ final String sendgridSender = System.getenv("SENDGRID_SENDER");
+ final String toEmail = req.getParameter("to");
+ if (toEmail == null) {
+ resp.getWriter()
+ .print("Please provide an email address in the \"to\" query string parameter.");
+ return;
+ }
+
+ SendGrid sendgrid = new SendGrid(sendgridApiKey);
+ SendGrid.Email email = new SendGrid.Email();
+ email.addTo(toEmail);
+ email.setFrom(sendgridSender);
+ email.setSubject("This is a test email");
+ email.setText("Example text body.");
+
+ try {
+ SendGrid.Response response = sendgrid.send(email);
+ if (response.getCode() != 200) {
+ resp.getWriter().print(String.format("An error occured: %s", response.getMessage()));
+ return;
+ }
+ resp.getWriter().print("Email sent.");
+ } catch (SendGridException e) {
+ throw new ServletException("SendGrid error", e);
+ }
+ }
+}
+// [END example]
diff --git a/appengine/sendgrid/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/sendgrid/src/main/webapp/WEB-INF/appengine-web.xml
new file mode 100644
index 00000000000..1e2b8457676
--- /dev/null
+++ b/appengine/sendgrid/src/main/webapp/WEB-INF/appengine-web.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ YOUR-PROJECT-ID
+ YOUR-VERSION-ID
+ true
+
+
+
+
+
+
diff --git a/appengine/sendgrid/src/main/webapp/WEB-INF/web.xml b/appengine/sendgrid/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..ad56ea9c2e4
--- /dev/null
+++ b/appengine/sendgrid/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+ sendemail
+ com.example.appengine.sendgrid.SendEmailServlet
+
+
+ sendemail
+ /send/email
+
+
+
diff --git a/appengine/static-files/pom.xml b/appengine/static-files/pom.xml
new file mode 100644
index 00000000000..a3eaf7d2f8f
--- /dev/null
+++ b/appengine/static-files/pom.xml
@@ -0,0 +1,60 @@
+
+
+ 4.0.0
+ war
+ 1.0-SNAPSHOT
+ com.example.appengine
+ appengine-staticfiles
+
+
+ doc-samples
+ com.google.cloud
+ 1.0.0
+ ../..
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ jar
+ provided
+
+
+
+
+ ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
+
+
+
+ com.google.appengine
+ appengine-maven-plugin
+ ${appengine.sdk.version}
+
+
+ org.apache.maven.plugins
+ 3.3
+ maven-compiler-plugin
+
+
+ 1.7
+
+
+
+
+
diff --git a/appengine/static-files/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/static-files/src/main/webapp/WEB-INF/appengine-web.xml
new file mode 100644
index 00000000000..ad825e10799
--- /dev/null
+++ b/appengine/static-files/src/main/webapp/WEB-INF/appengine-web.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+ YOUR-PROJECT-ID
+ YOUR-VERSION-ID
+ true
+
+
diff --git a/appengine/static-files/src/main/webapp/WEB-INF/web.xml b/appengine/static-files/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..e7fce53fed5
--- /dev/null
+++ b/appengine/static-files/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ index.html
+
+
+
diff --git a/appengine/static-files/src/main/webapp/index.html b/appengine/static-files/src/main/webapp/index.html
new file mode 100644
index 00000000000..d1643e9a6b1
--- /dev/null
+++ b/appengine/static-files/src/main/webapp/index.html
@@ -0,0 +1,10 @@
+
+
+
+Static Files
+
+
+
+
This is a static file serving example.
+
+
diff --git a/appengine/static-files/src/main/webapp/stylesheets/styles.css b/appengine/static-files/src/main/webapp/stylesheets/styles.css
new file mode 100644
index 00000000000..573f441093f
--- /dev/null
+++ b/appengine/static-files/src/main/webapp/stylesheets/styles.css
@@ -0,0 +1,4 @@
+body {
+ font-family: Verdana, Helvetica, sans-serif;
+ background-color: #CCCCFF;
+}
diff --git a/appengine/twilio/README.md b/appengine/twilio/README.md
new file mode 100644
index 00000000000..d9da6335902
--- /dev/null
+++ b/appengine/twilio/README.md
@@ -0,0 +1,17 @@
+# Java Twilio voice and SMS sample for Google Managed VMs
+This sample demonstrates how to use [Twilio](https://www.twilio.com) on Google Managed VMs
+For more information about Twilio, see their [Java quickstart tutorials](https://www.twilio.com/docs/quickstart/java).
+## Setup
+Before you can run or deploy the sample, you will need to do the following:
+1. [Create a Twilio Account](http://ahoy.twilio.com/googlecloudplatform). Google App Engine
+customers receive a complimentary credit for SMS messages and inbound messages.
+1. Create a number on twilio, and configure the voice request URL to be ``https://your-app-id.appspot.com/call/receive``
+and the SMS request URL to be ``https://your-app-id.appspot.com/sms/receive``.
+1. Configure your Twilio settings in the environment variables section in ``src/main/appengine/app.yaml``.
+## Running locally
+You can run the application locally to test the callbacks and SMS sending. You
+will need to set environment variables before starting your application:
+ $ export TWILIO_ACCOUNT_SID=[your-twilio-accoun-sid]
+ $ export TWILIO_AUTH_TOKEN=[your-twilio-auth-token]
+ $ export TWILIO_NUMBER=[your-twilio-number]
+ $ mvn clean jetty:run
diff --git a/appengine/twilio/pom.xml b/appengine/twilio/pom.xml
new file mode 100644
index 00000000000..b24c86b2d99
--- /dev/null
+++ b/appengine/twilio/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+ war
+ 1.0-SNAPSHOT
+ com.example.appengine
+ appengine-twilio
+
+
+ doc-samples
+ com.google.cloud
+ 1.0.0
+ ../..
+
+
+
+
+
+ com.twilio.sdk
+ twilio-java-sdk
+ 6.3.0
+
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+ jar
+ provided
+
+
+
+
+ ${project.build.directory}/${project.build.finalName}/WEB-INF/classes
+
+
+
+ com.google.appengine
+ appengine-maven-plugin
+ ${appengine.sdk.version}
+
+
+ org.apache.maven.plugins
+ 3.3
+ maven-compiler-plugin
+
+
+ 1.7
+
+
+
+
+
diff --git a/appengine/twilio/src/main/java/com/example/appengine/twilio/ReceiveCallServlet.java b/appengine/twilio/src/main/java/com/example/appengine/twilio/ReceiveCallServlet.java
new file mode 100644
index 00000000000..1332a62b08f
--- /dev/null
+++ b/appengine/twilio/src/main/java/com/example/appengine/twilio/ReceiveCallServlet.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.twilio;
+
+import com.twilio.sdk.verbs.Say;
+import com.twilio.sdk.verbs.TwiMLException;
+import com.twilio.sdk.verbs.TwiMLResponse;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START example]
+@SuppressWarnings("serial")
+public class ReceiveCallServlet extends HttpServlet {
+
+ @Override
+ public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ ServletException {
+ TwiMLResponse twiml = new TwiMLResponse();
+ Say say = new Say("Hello from Twilio!");
+ try {
+ twiml.append(say);
+ } catch (TwiMLException e) {
+ throw new ServletException("Twilio error", e);
+ }
+
+ resp.setContentType("application/xml");
+ resp.getWriter().print(twiml.toXML());
+ }
+}
+// [END example]
diff --git a/appengine/twilio/src/main/java/com/example/appengine/twilio/ReceiveSmsServlet.java b/appengine/twilio/src/main/java/com/example/appengine/twilio/ReceiveSmsServlet.java
new file mode 100644
index 00000000000..cd99f8f083c
--- /dev/null
+++ b/appengine/twilio/src/main/java/com/example/appengine/twilio/ReceiveSmsServlet.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.twilio;
+
+import com.twilio.sdk.verbs.Message;
+import com.twilio.sdk.verbs.TwiMLException;
+import com.twilio.sdk.verbs.TwiMLResponse;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START example]
+@SuppressWarnings("serial")
+public class ReceiveSmsServlet extends HttpServlet {
+
+ @Override
+ public void service(HttpServletRequest request, HttpServletResponse response) throws IOException,
+ ServletException {
+ String fromNumber = request.getParameter("From");
+ String body = request.getParameter("Body");
+ String message = String.format("Hello, %s, you said %s", fromNumber, body);
+
+ TwiMLResponse twiml = new TwiMLResponse();
+ Message sms = new Message(message);
+ try {
+ twiml.append(sms);
+ } catch (TwiMLException e) {
+ throw new ServletException("Twilio error", e);
+ }
+
+ response.setContentType("application/xml");
+ response.getWriter().print(twiml.toXML());
+ }
+}
+// [END example]
diff --git a/appengine/twilio/src/main/java/com/example/appengine/twilio/SendSmsServlet.java b/appengine/twilio/src/main/java/com/example/appengine/twilio/SendSmsServlet.java
new file mode 100644
index 00000000000..5270acb5a84
--- /dev/null
+++ b/appengine/twilio/src/main/java/com/example/appengine/twilio/SendSmsServlet.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.appengine.twilio;
+
+import com.twilio.sdk.TwilioRestClient;
+import com.twilio.sdk.TwilioRestException;
+import com.twilio.sdk.resource.factory.MessageFactory;
+import com.twilio.sdk.resource.instance.Account;
+import com.twilio.sdk.resource.instance.Message;
+import org.apache.http.NameValuePair;
+import org.apache.http.message.BasicNameValuePair;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.servlet.ServletException;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+// [START example]
+@SuppressWarnings("serial")
+@WebServlet(name = "sendsms", value = "/sms/send")
+public class SendSmsServlet extends HttpServlet {
+
+ @Override
+ public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException,
+ ServletException {
+ final String twilioAccountSid = System.getenv("TWILIO_ACCOUNT_SID");
+ final String twilioAuthToken = System.getenv("TWILIO_AUTH_TOKEN");
+ final String twilioNumber = System.getenv("TWILIO_NUMBER");
+ final String toNumber = (String) req.getParameter("to");
+ if (toNumber == null) {
+ resp.getWriter()
+ .print("Please provide the number to message in the \"to\" query string parameter.");
+ return;
+ }
+ TwilioRestClient client = new TwilioRestClient(twilioAccountSid, twilioAuthToken);
+ Account account = client.getAccount();
+ MessageFactory messageFactory = account.getMessageFactory();
+ List params = new ArrayList();
+ params.add(new BasicNameValuePair("To", toNumber));
+ params.add(new BasicNameValuePair("From", twilioNumber));
+ params.add(new BasicNameValuePair("Body", "Hello from Twilio!"));
+ try {
+ Message sms = messageFactory.create(params);
+ resp.getWriter().print(sms.getBody());
+ } catch (TwilioRestException e) {
+ throw new ServletException("Twilio error", e);
+ }
+ }
+}
+// [END example]
diff --git a/appengine/twilio/src/main/webapp/WEB-INF/appengine-web.xml b/appengine/twilio/src/main/webapp/WEB-INF/appengine-web.xml
new file mode 100644
index 00000000000..f5e97bb8452
--- /dev/null
+++ b/appengine/twilio/src/main/webapp/WEB-INF/appengine-web.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+ YOUR-PROJECT-ID
+ YOUR-VERSION-ID
+ true
+
+
+
+
+
+
+
diff --git a/appengine/twilio/src/main/webapp/WEB-INF/web.xml b/appengine/twilio/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 00000000000..38e4ad35048
--- /dev/null
+++ b/appengine/twilio/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+ receivecall
+ com.example.appengine.twilio.ReceiveCallServlet
+
+
+ receivecall
+ /call/receive
+
+
+ receivesms
+ com.example.appengine.twilio.ReceiveSmsServlet
+
+
+ receivesms
+ /sms/receive
+
+
+ sendsms
+ com.example.appengine.twilio.SendSmsServlet
+
+
+ sendsms
+ /sms/send
+
+
+
diff --git a/pom.xml b/pom.xml
index 8ff178a7a56..21c270794d4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -43,9 +43,14 @@
+ appengine/analyticsappengine/appidentityappengine/helloworldappengine/mailgun
+ appengine/memcache
+ appengine/sendgrid
+ appengine/static-files
+ appengine/twiliobigquerydatastorelogging