Posted by bollysite on August 2nd, 2010
Third party highly customizable email marketing infrastructure is quiet costly compared to owning dedicate email server. Companies providing low cost email marketing packages has limitation on daily/monthly mail count and bandwidth. Even there is no guaranty of any hosted mailing server, If internet users mark sent mail/IP as spam, server get black listed. So It’s wise to use trusted mailing infrastructure in budget cost.
Google App Engine allows daily 2000 mail resource usage for free. For more quota one can easily upgrade membership and have reliable and trustful emailing infrastructure.

Features
- Django template based mailer
- IP address validation/filtering.
- Generating PHP API on the fly for remote requests.
- Task Queue based mail sending module.
Summary of Application
- First of all it ask for admin’s google account credentials whenever we point browser to http://appid.appspot.com
- After successful login, It shows dashboard containing existing created mailer templates.

- Admin can add, edit, delete templates. It also allows python django template variables. i.e. Dear {{username}}

- To get Google App Engine request curl api address, one need to go inside edit mailer.

- It also allows admin to configure our app for limited IP addresses.

Here is a demo code for Google App Engine Mail task queue
app.yaml
application: your_app
version: 1
runtime: python
api_version: 1
handlers:
- url: /picknsend*
script: picknsend.py
queue.yaml
queue:
- name: limitedemail
rate: 2000/d
Setting up task queue
try:
from google.appengine.api.labs import taskqueue
except ImportError:
from google.appengine.api import taskqueue # for official inclusion of taskqueue.
# schedule task queue for sending mail
q = taskqueue.Queue('limitedemail')
t = taskqueue.Task(url='/picknsend', method='POST')
q.add(t)
picknsend.py
#!/usr/bin/env python
# /picknsend task queue job
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext import db
from google.appengine.api import mail
class MailQueue(db.Model):
mail_to = db.StringProperty(required=True)
mail_subject = db.StringProperty(required=True)
mail_body = db.TextProperty(required=True)
mail_datetime = db.DateTimeProperty(auto_now_add=True)
mail_sent = db.BooleanProperty(default=False)
class PickAndSendMail(webapp.RequestHandler):
def post(self):
self.sendmail()
def sendmail(self):
m = MailQueue.gql("WHERE mail_sent=False ORDER BY mail_datetime asc").fetch(1)
for i in m:
BODY = i.mail_body
TO = i.mail_to
SUBJECT = i.mail_subject
mail.send_mail('your_email@gmail.com',TO,SUBJECT,BODY)
for i in m:
i.mail_sent = True # marking... mail gone
i.put()
def main():
application = webapp.WSGIApplication([('/picknsend*', PickAndSendMail)], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
Above code is not our entire application. It’s just one of the sample module that Google App Engine developer can refer for development.
Posted by bollysite on February 8th, 2010
One of my client uses GoogleMini for search infrastructure. His entire site was coded in classic asp. I was hired for making some XSLT changes in frontend. GSA 6.0 has built in facility for query auto-completing. But googlemini doesn’t has such facility. So, Google Staff introduce SAYT (search as you type autocomplete) for googlemini and my client asked me to integrate SAYT with his googlemini. Google Mini SAYT is nothing but AJAX autocomplete script written in Javascript and PHP.

My client’s dedicated server is always heavily loaded with daily millions of page-views. So, SAYT was a kind of burden on his server by putting extra load as user keep sending request on every key stroke. Luckily I found Google App Engine, cloud computing infrastructure way cheaper as you can consume 1GB daily bandwidth free of cost. So then I converted GoogleMini SAYT php code into python and created a simple app engine code so we can host and run SAYT from Google Cloud Infrastructure.
# original file search-responder.php is Copyright (C) 2006 Google Inc. under Apache License, Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0
import os
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from django.utils import simplejson
class RPCHandler(webapp.RequestHandler):
def get(self):
self.response.headers["Content-Type"] = "text/html; charset=UTF-8"
self.response.headers["Cache-Control"] = "no-cache"
self.response.headers.add_header("Expires", "Thu, 01 Dec 1994 16:00:00 GMT")
# Get the data and the query
self.data = self.GetData()
self.query = self.request.get('query').strip().lower()
# Build Response
self.responseout = {}
self.responseout["query"] = self.query
self.responseout["results"] = self.GetResults()
if len(self.responseout["results"]) == 1:
self.responseout["autocompletedQuery"] = self.responseout['results'][0]['name']
# Output response
self.response.out.write("searchAsYouType.handleAjaxResponse(")
self.response.out.write(simplejson.dumps(self.responseout))
self.response.out.write(");")
def GetData(self):
data = []
data_index = 1
filedata = open("test-data.txt")
for line in filedata:
record = line.strip().split("|")
if len(record) == 4:
data.append(record)
return data
def GetResults(self):
results = []
data = self.data
queryLength = len(self.query)
for record in data:
if record[0].lower().find(self.query,0,queryLength) != -1:
result = {}
result['name'] = record[0]
result['type'] = record[1]
result['content'] = record[2]
result['moreDetailsUrl'] = record[3]
result['style'] = 'expanded' if self.query == record[0].lower() else 'normal'
results.append(result)
return results
def main():
application = webapp.WSGIApplication([('/rpc*', RPCHandler)], debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
Save this code as search-responder.py file, and rest of work is similar to existing setup. Now to run this code from Google App Engine and modify your googlemini custom xslt frontend by these steps.
Note the step:-
<script src="http://localhost/sayt/search-as-you-type.js"></script>
<script>searchAsYouType.initialize(document.getElementById('sayt'), true);</script>
Modify with them with
<script src="http://your-app-engine-path/static_dir/search-as-you-type.js"></script>
<script>searchAsYouType.initialize(document.getElementById('sayt'), true);</script>
Save the Frontend XSLT and you are done.
Recent Comments