Skip to content

Commit 4286dd0

Browse files
committed
Create an email autoresponder
1 parent 286b05c commit 4286dd0

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

Procfile

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
web: gunicorn app:app --log-file=-
22
worker: python worker.py
3+
clock: python clock.py

clock.py

+90
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
"""Check emails to [email protected], lint them, and reply."""
2+
3+
from apscheduler.schedulers.blocking import BlockingScheduler
4+
import gmail
5+
import smtplib
6+
from email.MIMEMultipart import MIMEMultipart
7+
from email.MIMEText import MIMEText
8+
from worker import conn
9+
import requests
10+
import hashlib
11+
import json
12+
import os
13+
14+
scheduler = BlockingScheduler()
15+
16+
# Settings
17+
18+
user_to = "[email protected]"
19+
name = "proselint"
20+
password = os.environ['gmail_password']
21+
22+
tagline = "Linted by proselint"
23+
url = "http://prose.lifelinter.com"
24+
api_url = "http://api.prose.lifelinter.com/v0/"
25+
26+
27+
@scheduler.scheduled_job('interval', minutes=0.25)
28+
def check_email():
29+
"""Check the mail account and lint new mail."""
30+
server = smtplib.SMTP("smtp.gmail.com", 587)
31+
server.ehlo()
32+
server.starttls()
33+
server.ehlo()
34+
server.login(user, password)
35+
36+
g = gmail.login(user, password)
37+
38+
# Check for unread messages.
39+
unread = g.inbox().mail(unread=True)
40+
41+
# Submit a job to lint each email sent to [email protected]. Record the
42+
# resulting job_ids somewhere (in Redis, I suppose), keyed by a hash of the
43+
# email.
44+
for u in unread:
45+
46+
u.fetch()
47+
48+
signature = (u.fr.decode('utf-8') +
49+
u.subject.decode('utf-8') +
50+
u.body.decode('utf-8'))
51+
52+
hash = hashlib.sha256(signature.encode('utf-8')).hexdigest()
53+
54+
if user_to in u.to or user_to in u.headers['Cc']:
55+
56+
job_id = conn.get(hash)
57+
58+
if not job_id:
59+
# If the email hasn't been sent for processing, send it.
60+
r = requests.post(api_url, data={"text": u.body})
61+
conn.set(hash, r.json()["job_id"])
62+
63+
else:
64+
# Otherwise, check whether the results are ready, and if so,
65+
# reply with them.
66+
r = requests.get(api_url, params={"job_id": job_id})
67+
68+
if r.json()["status"] == "success":
69+
70+
errors = json.dumps(r.json()['data'])
71+
72+
msg = MIMEMultipart()
73+
msg["From"] = "{} <{}>".format(name, user)
74+
msg["To"] = u.fr
75+
msg["Subject"] = "Re: " + u.subject
76+
77+
msg.add_header("In-Reply-To", u.headers['Message-ID'])
78+
msg.add_header("References", u.headers['Message-ID'])
79+
80+
body = errors + "\n\n--\n" + tagline + "\n" + url
81+
msg.attach(MIMEText(body, "plain"))
82+
83+
text = msg.as_string()
84+
server.sendmail(user, u.fr, text)
85+
86+
# Mark the email as read.
87+
u.read()
88+
u.archive()
89+
90+
scheduler.start()

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
APScheduler==3.0.0
22
-e git+https://4753ad3ace64ac52c8e052ff8e782eb8a6960b04:[email protected]/suchow/proselint.git#egg=proselint
3+
-e git+https://github.com/charlierguo/gmail.git#egg=gmail
34
click==3.3
45
Flask==0.10.1
56
Flask-API==0.6.2

0 commit comments

Comments
 (0)