Cloud Mashup: SaaS (Twilio) + PaaS (Google AppEngine) + IaaS (Amazon WS)

This application is an effort to lower my phone bill by using Cloud for my SMS needs.  I text less than 50 messages a month, so I really didn’t want to shell out $10 a month for  my T-Mobile account or paying 20c per message.  Twilio has SMS service which costs me 2c per message, so I figured out a solution to send/receive text messages with my Twilio account.  The application I am talking about here solves half of the problem, and there’s another Android application I wrote which solves the other half.  I will post about that Android application when I get a chance later.

This is basically a Google AppEngine(GAE) application which receives Twilio’s request, and then forwards to SNS at Amazon WS(AWS).  I created a email subscription to the SNS topic which finally sends the text message to my Yahoo email.  The solution can certainly be simplified, but it is more interesting for me to be able to exercise Cloud services in different layers doing this way.   You will find all codes mentioned in this post at https://github.com/barryku/SpringCloud/tree/master/GaeApp.

You can have Twilio to trigger any HTTP request whenever a SMS message is received, so I created a Spring MVC application on GAE which will handle the callback.  The controller code is quite simple since the dependent service will be injected automatically by Srping.

	@Autowired
	private AmazonSnsService amazonSns;

	@RequestMapping(value="/twilio", method = RequestMethod.POST)
	public void processCallback(@ModelAttribute("twilio") TwilioCallback msg) throws IOException  {
		String msgId = amazonSns.sendTwilioMessage(msg);
		log.info("SNS ID: " + msgId);
	}

Amazon did a great job on AWS Java library, so using SNS is also quite straightfoward.

public class AmazonSnsService {

	private AmazonSNSClient sns;
	private String topicArn;

	public AmazonSnsService(AmazonSNSClient sns) {
		this.sns = sns;
	}

	public String sendTwilioMessage(TwilioCallback msg) {
		PublishRequest request = new PublishRequest(topicArn, msg.getBody(), msg.getFrom());
		PublishResult result = sns.publish(request);
		return result.getMessageId();
	}

	public void setTopicArn(String topicArn) {
		this.topicArn = topicArn;
	}

	public String getTopicArn() {
		return topicArn;
	}

}

The Spring configuration for AmazonSnsService can be found in mvc-servlet.xml. You will modify spring.properties to include your AWS information there.

<bean id="amazonSns" class="com.barryku.gae.service.AmazonSnsService">
	<constructor-arg>
		<bean class="com.amazonaws.services.sns.AmazonSNSClient">
			<constructor-arg>
				<bean class="com.amazonaws.auth.BasicAWSCredentials">
					<constructor-arg value="${amazon.accessKey}"/>
					<constructor-arg value="${amazon.accessSecret}"/>
				</bean>
			</constructor-arg>
		</bean>
	</constructor-arg>
	<property name="topicArn" value="${amazon.topicArn}"/>
</bean>

There’s one caveat with using AWS on GAE though. GAE is running on a sandbox environment, so you will get a security error at Apache’s HttpClient when using AWS directly. I found a good workaround at https://github.com/apcj/aws-sdk-for-java-on-gae. It overwrites com.amazonaws.http.HttpClient using GAE’s UrlFetch which works beautifully with my application.

This entry was posted in Amazon WS, Cloud and tagged , , , , . Bookmark the permalink.

4 Responses to Cloud Mashup: SaaS (Twilio) + PaaS (Google AppEngine) + IaaS (Amazon WS)

  1. Pingback: Alexander4

  2. Pingback: Alexander7

  3. Pingback: harvey

  4. Pingback: terrance

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>