CollabMailBot
One of the issues with Googles' Wave service as it stands right now, is the lack of an email -> wave bridge. Such a bridge would allow people to more easily get used to the idea of using the Wave service in their every day life.
So seeing the lack, I thought I would have a crack at it myself. The idea was to build a reference bot that translated between GWave and GMail via imaplib.
However I very quickly hit an issue. Google App Engine (GAE) has turned off the ability to open sockets outside of its urlfetch library. I can see why they would do this (greatly reduces the chance that some nefarious cracker using Googles bandwidth to DoS sites off the net). However it means that imaplib while callable in GAE, is actually useless because it cannot communicate with the external imap server.
Luckily, GMail has a little known feature (well I didn't know about it until I started looking at the Bridge Bot). Each account has an atom feed of the last 20 emails recieved. While they don't contain the full email information they do contain the title and a link to the email in the GMail and so can be used to at least simulate the Bridging.
Source: http://code.google.com/p/collabmailbot/
Function of Note: mailcheck(properties, context, user, **kwargs)
def mailcheck(properties, context, user, **kwargs):
logging.debug("Wa hay and off we go")
url = "https://mail.google.com/mail/feed/atom"
logging.debug(url)
username = kwargs.get("USERNAME", None)
password = kwargs.get("PASSWORD", None)
encoded = base64.b64encode(username+'@gmail.com:'+password)
authstr = "Basic "+encoded
mheaders = {'Authorization':authstr,}
res = urlfetch.fetch(url=url, headers = mheaders, method=urlfetch.POST)
logging.debug(res.status_code)
if res.status_code == 200:
xmldoc = minidom.parseString(res.content)
logging.debug(res.content)
for feed in xmldoc.getElementsByTagName('feed'):
for entry in xmldoc.getElementsByTagName('entry'):
try:
title = entry.getElementsByTagName('title')[0].firstChild.data
logging.debug(title)
root_wavelet = context.GetRootWavelet()
rep_wave = robot_abstract.NewWave(context, root_wavelet.GetParticipants())
rep_wavelet = rep_wave.CreateBlip()
rep_wavelet.GetDocument().SetText(title)
except:
pass
