Send E-mails When You Get @replies On Twitter
I just had a buddy of mine ask me to write a script that would send an e-mail to you whenever you get an "@reply" on Twitter. I've recently been doing some work on a Twitter application, so I feel relatively comfortable with the python-twitter project to access Twitter. It didn't take very long to come up with this script, and it appears to work fine for us (using a cronjob to run the script periodically).
I thought others on the Internets might enjoy the script as well, so here it is!
#!/usr/bin/env python # -*- coding: utf-8 -*- """ A simple script to check your Twitter account for @replies and send you an email if it finds any new ones since the last time it checked. It was developed using python-twitter 0.5 and Python 2.5. It has been tested on Linux only, but it should work fine on other platforms as well. This script is intended to be executed by a cron manager or scheduled task manager. Copyright (c) 2009, Josh VanderLinden All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ import twitter import ConfigParser import os import sys from datetime import datetime import smtplib from email.MIMEMultipart import MIMEMultipart from email.MIMEText import MIMEText from email.Utils import formatdate # get the user's "home" directory DIRNAME = os.path.expanduser('~') CONFIG = os.path.join(DIRNAME, '.twitter_email_replies.conf') FORMAT = '%a %b %d %H:%M:%S +0000 %Y' REPLY_TEMPLATE = """%(author)s said: %(text)s Posted on %(created_at)s Go to http://twitter.com/home?status=@%(screen_name)s%%20&in_reply_to_status_id=%(id)s&in_reply_to=%(screen_name)s to post a reply """ # sections AUTH = 'credentials' EXEC = 'exec_info' EMAIL = 'email_info' # make the code a bit "cleaner" O = lambda s: sys.stdout.write(s + '\n') E = lambda s: sys.stderr.write(s + '\n') str2dt = lambda s: datetime.strptime(s, FORMAT) def get_dict(status): my_dict = status.AsDict() my_dict['screen_name'] = my_dict['user']['screen_name'] my_dict['author'] = my_dict['user']['name'] return my_dict def main(): O('Reading configuration from %s' % CONFIG) parser = ConfigParser.SafeConfigParser() config = parser.read(CONFIG) # make sure we have the proper sections if not parser.has_section(AUTH): parser.add_section(AUTH) if not parser.has_section(EMAIL): parser.add_section(EMAIL) if not parser.has_section(EXEC): parser.add_section(EXEC) try: # get some useful settings from the configuration file username = parser.get(AUTH, 'username') password = parser.get(AUTH, 'password') to_address = parser.get(EMAIL, 'to_address') from_address = parser.get(EMAIL, 'from_address') smtp_server = parser.get(EMAIL, 'smtp_server') smtp_user = parser.get(EMAIL, 'smtp_user') smtp_pass = parser.get(EMAIL, 'smtp_pass') if '' in [username, password, to_address, from_address, smtp_server]: raise Exception('Not configured') except Exception: E('Please configure your credentials and e-mail information in %s!' % CONFIG) # create some placeholders in the configuration file to make it easier sections = { AUTH: ('username', 'password'), EMAIL: ('to_address', 'from_address', 'smtp_server', 'smtp_user', 'smtp_pass') } for section in sections.keys(): for opt in sections[section]: if not parser.has_option(section, opt): parser.set(section, opt, '') else: # determine the last time we checked for replies try: last_check = str2dt(parser.get(EXEC, 'last_run')) except ConfigParser.NoOptionError: last_check = datetime.utcnow() last_check_str = last_check.strftime(FORMAT) info = 'Fetching updates for %s since %s' % (username, last_check_str) O(info) # attempt to connect to Twitter api = twitter.Api(username=username, password=password) # not using the `since` parameter for more backward-compatibility timeline = api.GetReplies() new_replies = [] for reply in timeline: post_time = str2dt(reply.GetCreatedAt()) if post_time > last_check: new_replies.append(reply) count = len(new_replies) if count: # send out an email for this user O('Found %i new replies... sending e-mail to %s' % (count, to_address)) reply_list = '\n\n'.join([REPLY_TEMPLATE % get_dict(r) for r in new_replies]) is_are = 'is' plural = 'y' if count != 1: is_are = 'are' plural = 'ies' params = { 'is_are': is_are, 'count': count, 'replies': plural, 'username': username, 'reply_list': reply_list, 'last_check': last_check_str } text = """There %(is_are)s %(count)i new @repl%(replies)s for %(username)s on Twitter since %(last_check)s: %(reply_list)s""" % params # compose the e-mail msg = MIMEMultipart() msg['From'] = from_address msg['To'] = to_address msg['Date'] = formatdate(localtime=True) msg['Subject'] = 'New @Replies for %s' % username msg.attach(MIMEText(text)) # try to send the e-mail message out email = smtplib.SMTP(smtp_server) if smtp_user and smtp_pass: email.login(smtp_user, smtp_pass) email.sendmail(from_address, to_address, msg.as_string()) email.close() # save the current time so we know where to pick up next time parser.set(EXEC, 'last_run', datetime.utcnow().strftime(FORMAT)) # write the config O('Saving settings...') out = open(CONFIG, 'wb') parser.write(out) out.close() if __name__ == '__main__': main()
Feel free to copy this script and modify it to your desires. Also, please comment if you have issues using it.
Comments
Comments powered by Disqus