@@ -921,43 +921,35 @@ To handle delta reports in our mail handling microservice we will need 2 things:
921921- Get access to the POST body of a request
922922- Process and manipulate JSON data
923923
924- To get access to this add the following imports to your `web.py` file :
925-
926- ` ` ` python
927- import json
928- from flask import request
929- ` ` `
930-
931- Then we define a new method that will :
924+ To get access to this we edit `web.py` to define a new method that will :
932925- Handle the incoming delta reports
933926- Load the delta report into a variable
934927- Define some variables.
935928
936- Lastly we define an array that will hold the URI’s of all emails that need to be sent.
929+ Lastly we define an array that will hold the URIs of all emails that need to be sent.
937930
938931
939932` ` ` python
940933# mail-service/web.py
941- @app.route("/process_delta", methods=['POST'])
942- def processDelta():
943- delta_report = json.loads(request.data)
944- mails_to_send = set()
945- predicate_mail_is_ready = "http://example.com/ready"
946- value_mail_is_ready = "yes"
947- # continued later...
948- ` ` `
934+ import json
935+ from flask import request
949936
950- We will loop over all inserted triples to check for mails that are ready to be sent :
951- ` ` ` python
952- # mail-service/web.py
937+ # ...
938+
939+ @app.route("/process_delta", methods=['POST'])
953940def processDelta():
954- # ...
955- # ...continuation
956- for delta in delta_report['delta']:
957- for triple in delta['inserts']:
958- if(triple['p']['value'] == predicate_mail_is_ready):
959- if(triple['o']['value'] == value_mail_is_ready):
960- mails_to_send.add(triple['s']['value'])
941+ delta_report = json.loads(request.data)
942+ mails_to_send = set()
943+ predicate_mail_is_ready = "http://example.com/ready"
944+ value_mail_is_ready = "yes"
945+
946+ # Loop over all inserted triples to check for mails that are ready to be sent:
947+
948+ for delta in delta_report['delta']:
949+ for triple in delta['inserts']:
950+ if(triple['p']['value'] == predicate_mail_is_ready):
951+ if(triple['o']['value'] == value_mail_is_ready):
952+ mails_to_send.add(triple['s']['value'])
961953 # continued later...
962954` ` `
963955
@@ -968,15 +960,18 @@ Add the following code to `mail_helpers.py`:
968960# mail-service/mail_helpers.py
969961def load_mail(uri):
970962 # this query will find the mail (if it exists)
971- select_query = "SELECT DISTINCT ?uuid ?from ?ready ?subject ?content\n "
972- select_query += "WHERE \n {\n "
973- select_query += "<" + str(uri) + "> <http://mail.com/from> ?from;\n "
974- select_query += "a <http://mail.com/Mail>;\n "
975- select_query += "<http://mail.com/content> ?content;\n "
976- select_query += "<http://mail.com/subject> ?subject;\n "
977- select_query += "<http://mail.com/ready> ?ready;\n "
978- select_query += "<http://mu.semte.ch/vocabularies/core/uuid> ?uuid.\n "
979- select_query += "}"
963+ select_query = (
964+ f'SELECT DISTINCT ?uuid ?from ?to ?ready ?subject ?content\n '
965+ f'WHERE {{\n '
966+ f' <{str(uri)}> a <http://example.com/Mail>;\n '
967+ f' <http://example.com/from> ?from;\n '
968+ f' <http://example.com/to> ?to;\n '
969+ f' <http://example.com/content> ?content;\n '
970+ f' <http://example.com/subject> ?subject;\n '
971+ f' <http://example.com/ready> ?ready;\n '
972+ f' <http://mu.semte.ch/vocabularies/core/uuid> ?uuid.\n '
973+ f'}}'
974+ )
980975
981976 # execute the query...
982977 result = helpers.query(select_query)
@@ -993,7 +988,8 @@ def load_mail(uri):
993988 # we extract an object
994989 mail = dict()
995990 mail['uuid'] = bindings['uuid']['value']
996- mail['sender'] = bindings['from']['value']
991+ mail['from'] = bindings['from']['value']
992+ mail['to'] = bindings['to']['value']
997993 mail['ready'] = bindings['ready']['value']
998994 mail['subject'] = bindings['subject']['value']
999995 mail['content'] = bindings['content']['value']
@@ -1009,12 +1005,9 @@ To send the mail I have copied the entire `send_mail` function from http://naels
10091005
10101006` ` ` python
10111007# mail-service/mail_helpers.py
1012- def send_mail(mail):
1013-
1014- fromaddr = "YOUR EMAIL"
1015- toaddr = "EMAIL ADDRESS YOU SEND TO"
1016-
1008+ def send_mail(mail, from_addr, password):
10171009 msg = MIMEMultipart()
1010+ helpers.log(f"sending... {mail}")
10181011
10191012 msg['From'] = mail['from']
10201013 msg['To'] = mail['to']
@@ -1023,15 +1016,15 @@ def send_mail(mail):
10231016 body = mail['content']
10241017 msg.attach(MIMEText(body, 'plain'))
10251018
1026- server = smtplib. SMTP('smtp.gmail.com' , 587)
1019+ server = SMTP(environ['SMTP_SERVER'] , 587)
10271020 server.starttls()
1028- server.login(fromaddr, "YOUR PASSWORD" )
1021+ server.login(from_addr, password )
10291022 text = msg.as_string()
1030- server.sendmail(fromaddr, toaddr , text)
1023+ server.sendmail(from_addr, mail['to'] , text)
10311024 server.quit()
10321025` ` `
10331026
1034- The last thing that we need to do is to connect the list of URI’s to the send_mail function :
1027+ The last thing that we need to do is to connect the list of URIs to the send_mail function :
10351028` ` ` python
10361029# mail-service/web.py
10371030def processDelta():
@@ -1040,6 +1033,10 @@ def processDelta():
10401033 mail = mail_helpers.load_mail(uri)
10411034 if 'uuid' in mail.keys():
10421035 mail_helpers.send_mail(mail, EMAIL_ADDRESS, EMAIL_PWD)
1036+ else:
1037+ helpers.log(f"Either no mail found or not ready: {mail}")
1038+
1039+ return "ok"
10431040` ` `
10441041
10451042To test this you can send a POST request similar to this one to your local mu.semte.ch application on http://localhost/mails :
@@ -1058,7 +1055,7 @@ To test this you can send a POST request similar to this one to your local mu.se
10581055}
10591056` ` `
10601057
1061- If all went well then the person whose email address you filled in in the to field will have gotten a mail from you. Good job! You've just created a mailing microservice.
1058+ If all went well then the person whose email address you filled in in the to field will have gotten a mail from you (or there's a 'sent' mail in the [Ethereal Mail](https://ethereal.email/messages/) mailbox) . Good job! You've just created a mailing microservice.
10621059
10631060*This tutorial has been adapted from Jonathan Langens' mu.semte.ch articles. You can view them [here](https://mu.semte.ch/2017/02/16/reactive-microservice-hands-on-tutorial-part-1/) and [here](https://mu.semte.ch/2017/03/16/reactive-microservice-hands-on-tutorial-part-2/).*
10641061
0 commit comments