From abc95b06e02b369e790806c324d18d81befebdfb Mon Sep 17 00:00:00 2001 From: Jonas Braathen Date: Tue, 17 Feb 2015 09:13:48 +0100 Subject: [PATCH] Switch to using the Sendega API. Now with delivery reports! --- tekstmelding.py | 622 ++++++++++++++++++++++++++---------------------- 1 file changed, 335 insertions(+), 287 deletions(-) diff --git a/tekstmelding.py b/tekstmelding.py index 4abc472..d3dd837 100644 --- a/tekstmelding.py +++ b/tekstmelding.py @@ -2,12 +2,14 @@ # -*- coding: utf-8 -*- from flask import Flask, request, g, abort -from utils import generate_activation_code import MySQLdb import MySQLdb.cursors import datetime -import requests -import sys +import logging + +from utils import generate_activation_code +import sendega +import inside import config @@ -15,29 +17,40 @@ app = Flask(__name__) app.config.from_object('config') if not app.debug: - import logging - handler = logging.StreamHandler() - formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") - handler.setFormatter(formatter) - handler.setLevel(logging.INFO) - app.logger.addHandler(handler) + # Log INFO and higher levels to stderr + stream_handler = logging.StreamHandler() + formatter = logging.Formatter( + "%(asctime)s - %(name)s - %(levelname)s - %(message)s") + stream_handler.setFormatter(formatter) + stream_handler.setLevel(logging.INFO) + app.logger.addHandler(stream_handler) + + # Email admins about ERRORs and higher levels + from logging.handlers import SMTPHandler + mail_handler = SMTPHandler( + mailhost='127.0.0.1', + fromaddr='noreply+tekstmelding@neuf.no', + toaddrs=app.config['ADMINS'], + subject='Tekstmelding FAIL') + mail_handler.setLevel(logging.ERROR) + app.logger.addHandler(mail_handler) def connect_db(): """Connects to our database.""" db = MySQLdb.connect( - host=app.config['DATABASE_HOST'], - user=app.config['DATABASE_USER'], - passwd=app.config['DATABASE_PASS'], - db=app.config['DATABASE_NAME'], + host=app.config['DB_HOST'], + user=app.config['DB_USER'], + passwd=app.config['DB_PASS'], + db=app.config['DB_NAME'], cursorclass=MySQLdb.cursors.DictCursor, charset='utf8') return db def get_db(): - """Opens a new database connection if there is none yet for the - current application context.""" + """Returns a database connection. + Creates one if there is none for the current application context.""" if not hasattr(g, 'db'): g.db = connect_db() return g.db @@ -58,11 +71,13 @@ def query_db(query, args=(), one=False, lastrowid=False): """ assert not (one and lastrowid) - app.logger.debug("Query: %s\nArgs: %s", query, args) + # app.logger.debug('Got query with args: %s', query, args) cur = get_db().cursor() cur.execute(query, args) + # app.logger.debug('Executed query: %s', cur._last_executed) + if lastrowid: ret = cur.lastrowid else: @@ -74,300 +89,290 @@ def query_db(query, args=(), one=False, lastrowid=False): return ret -def get_user_by_phone(number): - user = query_db(""" - SELECT user.*, - (CASE WHEN (user.expires IS NULL) THEN 1 ELSE 0 END) AS expires_lifelong - FROM din_user user, din_userphonenumber phone - WHERE phone.number = %s AND - user.id = phone.user_id - """, [number], one=True) - return user +def get_sendega(): + """Returns a Sendega object. + Creates one if there is none for the current application context.""" + if not hasattr(g, 'sendega'): + g.sendega = sendega.Sendega( + wsdl=config.SENDEGA_WSDL, + username=config.SENDEGA_USERNAME, + password=config.SENDEGA_PASSWORD, + sender_bulk=config.SENDEGA_SENDER_BULK, + sender_billing=config.SENDEGA_SENDER_BILLING, + dlr_url=config.SENDEGA_DLR) + return g.sendega + + +def get_inside(): + if not hasattr(g, 'inside'): + g.inside = inside.Inside( + host=app.config['INSIDE_DB_HOST'], + username=app.config['INSIDE_DB_USER'], + password=app.config['INSIDE_DB_PASS'], + db=app.config['INSIDE_DB_NAME']) + return g.inside def log_incoming(**kwargs): return query_db(""" - INSERT INTO din_sms_received - (userid, gsm, codeword, message, operator, shortno, action, IP, simulation) + INSERT INTO incoming + (msgid, msisdn, msg, mms, mmsdata, shortcode, + mcc, mnc, pricegroup, keyword, keywordid, + errorcode, errormessage, registered, ip) VALUES - (%(userid)s, %(gsm)s, %(codeword)s, %(message)s, %(operator)s, %(shortno)s, %(action)s, %(ip)s, %(simulation)s) + (%(msgid)s, %(msisdn)s, %(msg)s, %(mms)s, %(mmsdata)s, %(shortcode)s, + %(mcc)s, %(mnc)s, %(pricegroup)s, %(keyword)s, %(keywordid)s, + %(errorcode)s, %(errormessage)s, %(registered)s, %(ip)s) """, kwargs, lastrowid=True) -def set_incoming_action(**kwargs): - query_db(""" - UPDATE din_sms_received - SET action = %(action)s - WHERE smsid = %(smsid)s - """, kwargs) - - -def log_sent(**kwargs): - query_db(""" - INSERT INTO din_sms_sent - (response_to, msgid, sender, receiver, countrycode, message, operator, codeword, billing_price, use_dlr, simulation, activation_code) +def log_outgoing(**kwargs): + return query_db(""" + INSERT INTO outgoing + (sender, destination, pricegroup, content, + contentTypeID, contentHeader, dlrUrl, + ageLimit, extID, sendDate, refID, priority, + gwID, pid, dcs) VALUES - (%(response_to)s, %(msgid)s, %(sender)s, %(receiver)s, %(countrycode)s, %(message)s, - %(operator)s, %(codeword)s, %(billing_price)s, %(use_dlr)s, %(simulation)s, %(activation_code)s) - """, kwargs) + (%(sender)s, %(destination)s, %(pricegroup)s, %(content)s, + %(contentTypeID)s, %(contentHeader)s, %(dlrUrl)s, + %(ageLimit)s, %(extID)s, %(sendDate)s, %(refID)s, %(priority)s, + %(gwID)s, %(pid)s, %(dcs)s) + """, kwargs, lastrowid=True) -def is_user_expired(user): - # A friendly reminder about how the 'expires' column works: - # NULL means the membership should never expire - # 0000-00-00 is the default and means the user has never had a membership - # YYYY-MM-DD is the day the membership will or has expired - # - # datetime.date does not accept the date 0000-00-00, instead we end - # up with None. As a workaround we do the NULL comparison with SQL - # and store the result in 'expires_lifelong'. - expires = user.get('expires', None) - expires_lifelong = user.get('expires_lifelong', None) - - # Lifelong membership? - if expires_lifelong: - return False - - # Non-expired membership? - elif type(expires) is datetime.date and expires >= datetime.date.today(): - return False - - # Expired? - elif not expires or (type(expires) is datetime.date and expires < datetime.date.today()): - return True - - else: - assert False, "What a trainwreck, we shouldn't be here" +def log_outgoing_response(**kwargs): + return query_db(""" + INSERT INTO outgoing_response + (id, MessageID, Success, ErrorNumber, ErrorMessage) + VALUES + (%(id)s, %(MessageID)s, %(Success)s, %(ErrorNumber)s, %(ErrorMessage)s) + """, kwargs, lastrowid=True) -def get_full_name(user): - full_name = "%s %s" % ( - user.get('firstname', '').strip(), - user.get('lastname', '').strip() - ) - return full_name[:50].strip() +def log_event(**kwargs): + for key in ('incoming_id', 'outgoing_id', 'dlr_id', + 'action', 'activation_code', 'user_id'): + kwargs.setdefault(key, None) + + return query_db(""" + INSERT INTO event + (incoming_id, outgoing_id, dlr_id, + action, user_id, activation_code) + VALUES + (%(incoming_id)s, %(outgoing_id)s, %(dlr_id)s, + %(action)s, %(user_id)s, %(activation_code)s) + """, kwargs, lastrowid=True) -def fix_encoding(message): - try: - assert type(message) == unicode - new_message = message.encode('latin-1', 'ignore') - except: - new_message = message - app.logger.warning( - "Unicode woes: message_type=%s message=%s exc_info=%s", - type(message), message, sys.exc_info()) - # Oh, never mind, let's try to send it anyway. - pass - - return new_message +def log_dlr(**kwargs): + return query_db(""" + INSERT INTO dlr + (msgid, extID, msisdn, status, statustext, + registered, sent, delivered, errorcode, + errormessage, operatorerrorcode) + VALUES ( + %(msgid)s, %(extID)s, %(msisdn)s, %(status)s, %(statustext)s, + %(registered)s, %(sent)s, %(delivered)s, %(errorcode)s, + %(errormessage)s, %(operatorerrorcode)s) + """, kwargs, lastrowid=True) -def send_sms(log_only=False, gsm=None, message=None, response_to=None, billing=False, billing_price=None, operator=None, activation_code=None): - assert gsm - assert message +def send_sms(destination, content, incoming_id=None, + billing=False, price=0, activation_code=None): + args = get_sendega().create_sms( + destination=destination, + content=content, + reference=incoming_id, + billing=billing, + price=price) - if billing: - assert billing_price - if not operator: - operator = 'ukjent' + app.logger.debug('Outgoing, args: %s', args) - # The strings in this file are in utf-8, encode to latin-1 before sending - message_latin = fix_encoding(message) + outgoing_id = log_outgoing(**args) - # Truncate message if too long - if len(message_latin) > 160: - app.logger.warning( - "Truncated the following message to 160 chars: %s", message_latin) - message_latin = message_latin[:160] + if app.debug: + return outgoing_id - params = { - 'bruker': app.config['EB_USER'], - 'passord': app.config['EB_PASSWORD'], - 'avsender': app.config['EB_SENDER_BULK'], - 'land': 47, - 'til': gsm, - 'melding': message_latin, - } + response = get_sendega().send(**args) + response['id'] = outgoing_id + log_outgoing_response(**response) - if billing: - params.update({ - 'avsender': app.config['EB_SENDER_BILLING'], - #'dlrurl': app.config['EB_DLR'], - 'ore': billing_price, - 'operator': operator, - 'kodeord': 'DNSMEDLEM', - }) + if response.get('Success', None): + return outgoing_id - if app.config['EB_SIMULATE']: - params['simulate'] = 1 - - app.logger.debug("send_sms params: %s" % params.items()) - - msgid = 0 - - if not log_only: - endpoint = app.config['EB_PAYURL'] if billing else app.config['EB_URL'] - - try: - result = requests.get(endpoint, params=params) - except: - app.logger.error( - "Caught exception while attempting to contact Eurobate: %s", - sys.exc_info()) - return False - - if result.status_code != requests.codes.ok: # 200 - app.logger.error( - "Got status code %s from Eurobate", result.status_code) - return False - - app.logger.debug( - "Hit URL: %s\nGot result: %s", result.url, result.text) - - response = result.text.split(' ') - if response[:3] == ['Meldingen', 'er', 'sendt']: - if billing and len(response) == 4 and response[3].isdigit(): - msgid = int(response[3]) - if billing and msgid == 0: - app.logger.warning("Did not get a msgid from Eurobate when billing as response to smsid:%s", response_to) - else: - app.logger.error("Message (response_to:%s) was not sent. Eurobate told us: %s", response_to, result.text) - return False - - log_sent( - response_to=response_to if response_to else 0, - msgid=msgid if billing else 0, - sender=params['avsender'], - receiver=gsm, - countrycode=params['land'], - message=message, - operator=params['operator'] if billing else 'NULL', - codeword=params['kodeord'] if billing else 'NULL', - billing_price=params['ore'] if billing else 0, - #use_dlr=1 if billing else 0, - use_dlr=0, - simulation=1 if app.config['EB_SIMULATE'] else 0, - activation_code=activation_code if activation_code else 'NULL') - - return True if not billing else msgid + return None -def notify_valid_membership(response_to=None, gsm=None, user=None): - assert gsm and user +def notify_valid_membership(incoming_id=None, number=None, user=None): + assert user - message = u"Hei %(name)s! Ditt medlemskap er gyldig til %(expires)s. Last ned app: %(app_link)s" % ({ - 'name': get_full_name(user), - 'expires': 'verdens undergang' if user.get('expires_lifelong') else str(user.get('expires')), - 'app_link': 'http://snappo.com/app', + name = get_inside().get_full_name(user) + expires = 'verdens undergang' if user.get('expires_lifelong') else str(user.get('expires')) + + content = u"Hei %(name)s! Ditt medlemskap er gyldig til %(expires)s. Last ned app: %(app)s" % ({ + 'name': name, + 'expires': expires, + 'app': 'http://snappo.com/app', }) - send_sms(log_only=True, response_to=response_to, gsm=gsm, message=message) - app.logger.info("Sent SMS to gsm:%s with proof of membership and link to app", gsm) - set_incoming_action(smsid=response_to, action='notify_valid_membership') - return fix_encoding(message) + outgoing_id = send_sms( + destination=number, + content=content, + incoming_id=incoming_id) + + app.logger.info("Sent SMS to number:%s with proof of membership", number) + + log_event( + action='notify_valid_membership', + incoming_id=incoming_id, + outgoing_id=outgoing_id, + user_id=user['id']) + + return 'OK' -def notify_payment_options_new(response_to=None, gsm=None): - assert gsm +def notify_payment_options_new(incoming_id=None, number=None): + content = u"Du kan kjøpe medlemskap via SnappOrder: http://snappo.com/app (200,-) eller ved å sende DNSMEDLEM til 2454 (230,-)" - message = u"Du kan kjøpe medlemskap via SnappOrder: http://snappo.com/app (200,-) eller ved å sende DNSMEDLEM til 2090 (230,-)" - send_sms(log_only=True, response_to=response_to, gsm=gsm, message=message) - app.logger.info("Sent SMS to gsm:%s with payment options (new)", gsm) - set_incoming_action(smsid=response_to, action='notify_payment_options_new') - return fix_encoding(message) + outgoing_id = send_sms( + destination=number, + content=content, + incoming_id=incoming_id) + + app.logger.info("Sent SMS to number:%s with payment options (new)", number) + + log_event( + action='notify_payment_options_new', + incoming_id=incoming_id, + outgoing_id=outgoing_id) + + return 'OK' -def notify_payment_options_renewal(response_to=None, gsm=None): - assert gsm +def notify_payment_options_renewal(incoming_id=None, number=None, user=None): + content = u"Ditt medlemskap er utløpt. Det kan fornyes via SnappOrder: http://snappo.com/app (200,-) eller ved å sende DNSMEDLEM til 2454 (230,-)" + + outgoing_id = send_sms( + destination=number, + content=content, + incoming_id=incoming_id) - message = u"Ditt medlemskap er utløpt. Det kan fornyes via SnappOrder: http://snappo.com/app (200,-) eller ved å sende DNSMEDLEM til 2090 (230,-)" - send_sms(log_only=True, response_to=response_to, gsm=gsm, message=message) - app.logger.info("Sent SMS to gsm:%s with payment options (renewal)", gsm) - set_incoming_action(smsid=response_to, action='notify_payment_options_renewal') - return fix_encoding(message) + app.logger.info( + "Sent SMS to number:%s with payment options (renewal)", number) + + log_event( + action='notify_payment_options_renewal', + incoming_id=incoming_id, + outgoing_id=outgoing_id, + user_id=user['id']) + + return 'OK' -def notify_could_not_charge(response_to=None, gsm=None): - assert gsm +def notify_could_not_charge(incoming_id=None, dlr_id=None, number=None): + app.logger.warning( + "Attempt to charge number:%s as a response to incoming_id:%s failed", + number, incoming_id) - app.logger.warning("Attempt to charge gsm:%s as a response to smsid:%s failed", gsm, response_to) - message = u"Beklager, bestillingen kunne ikke gjennomføres. Spørsmål? medlem@studentersamfundet.no" - send_sms(log_only=True, response_to=response_to, gsm=gsm, message=message) - set_incoming_action(smsid=response_to, action='notify_could_not_charge') - return fix_encoding(message) + content = u"Beklager, bestillingen kunne ikke gjennomføres. Spørsmål? medlem@studentersamfundet.no" + + outgoing_id = send_sms( + destination=number, + content=content, + incoming_id=incoming_id) + + log_event( + action='notify_could_not_charge', + incoming_id=incoming_id, + outgoing_id=outgoing_id, + dlr_id=dlr_id) + + return 'OK' -def renew_membership(response_to=None, gsm=None, user=None, operator=None): - assert gsm and user - +def renew_membership(incoming_id=None, number=None, user=None): new_expire = datetime.date.today() + datetime.timedelta(days=365) - query_db( - "UPDATE din_user SET expires = %(expires)s WHERE id = %(id)s", - { - 'expires': str(new_expire), - 'id': user['id'] - }) - - query_db(""" - INSERT INTO din_userupdate (date, user_id_updated, comment, user_id_updated_by) - VALUES (%(date)s, %(user_id_updated)s, %(comment)s, %(user_id_updated_by)s) - """, { - 'date': str(datetime.datetime.now()), - 'user_id_updated': user['id'], - 'comment': "Medlemskap fornyet med SMS.", - 'user_id_updated_by': user['id'], - }) - - message = u"Hei %(name)s! Ditt medlemskap er nå gyldig ut %(new_expire)s. Spørsmål? medlem@studentersamfundet.no" % ({ - 'name': get_full_name(user), + content = u"Hei %(name)s! Ditt medlemskap er nå gyldig ut %(new_expire)s. Spørsmål? medlem@studentersamfundet.no" % ({ + 'name': get_inside().get_full_name(user), 'new_expire': str(new_expire), }) - msgid = send_sms( - response_to=response_to, - gsm=gsm, - message=message, - operator=operator, + outgoing_id = send_sms( + destination=number, + content=content, + incoming_id=incoming_id, billing=True, - billing_price=app.config['MEMBERSHIP_PRICE_KR'] * 100, + price=app.config['MEMBERSHIP_PRICE_KR'] * 100, ) - if not msgid: - return notify_could_not_charge(response_to=response_to, gsm=gsm) + app.logger.info( + "Membership renewal requested by userid:%s number:%s new_expire:%s", + user['id'], number, new_expire) - app.logger.info("Membership of user_id:%s gsm:%s was renewed to %s", user['id'], gsm, new_expire) - set_incoming_action(smsid=response_to, action='renew_membership') - return fix_encoding(u"Vi vil nå forsøke å fornye medlemskapet ditt...") + log_event( + action='renew_membership', + incoming_id=incoming_id, + outgoing_id=outgoing_id, + user_id=user['id']) + + return 'OK' -def new_membership(response_to=None, gsm=None, operator=None): - assert gsm +def renew_membership_delivered(incoming_id=None, dlr_id=None, user_id=None): + new_expire = datetime.date.today() + datetime.timedelta(days=365) + get_inside().renew_user(user_id=user_id, new_expire=new_expire) + app.logger.info( + "Response to incoming_id:%s was delivered, user_id:%s renewed to %s", + incoming_id, user_id, new_expire) + + log_event( + action='renew_membership_delivered', + incoming_id=incoming_id, + dlr_id=dlr_id) + + return 'OK' + + +def new_membership(incoming_id=None, number=None): activation_code = generate_activation_code() - message = u"Velkommen! Dette er et midlertidig medlemsbevis. Aktiver medlemskapet ditt her: http://s.neuf.no/sms/%(gsm)s/%(activation_code)s" % ({ - 'gsm': gsm, + content = u"Velkommen! Dette er et midlertidig medlemsbevis. Aktiver medlemskapet ditt her: http://s.neuf.no/sms/%(number)s/%(activation_code)s" % ({ + 'number': number, 'activation_code': activation_code, }) - msgid = send_sms( - response_to=response_to, - gsm=gsm, - message=message, - operator=operator, - activation_code=activation_code, + outgoing_id = send_sms( + destination=number, + content=content, + incoming_id=incoming_id, billing=True, - billing_price=app.config['MEMBERSHIP_PRICE_KR'] * 100, - ) + price=app.config['MEMBERSHIP_PRICE_KR'] * 100) - if not msgid: - return notify_could_not_charge(response_to=response_to, gsm=gsm) + app.logger.info( + "New membership requested by number:%s, activation code sent", number) - app.logger.info("New membership for gsm:%s, activation code sent", gsm) - set_incoming_action(smsid=response_to, action='new_membership') - return fix_encoding(u"Vi vil nå forsøke å belaste deg for et medlemskap...") + log_event( + action='new_membership', + incoming_id=incoming_id, + outgoing_id=outgoing_id, + activation_code=activation_code) + + return 'OK' + + +def new_membership_delivered(incoming_id=None, dlr_id=None): + app.logger.info( + "Response to incoming_id:%s was delivered, new membership", incoming_id) + + log_event( + action='new_membership_delivered', + incoming_id=incoming_id, + dlr_id=dlr_id) + + return 'OK' @app.route('/') @@ -375,63 +380,106 @@ def main(): return 'Tekstmelding!' -@app.route('/callback') -def callback(): - gsm = request.args.get('gsm', None) - operator = request.args.get('operator', 'ukjent') - codeword = request.args.get('kodeord', None) - message = request.args.get('tekst', '') - shortno = request.args.get('kortnr', None) - ip = request.remote_addr +@app.route('/sendega-incoming') +def incoming(): + args = {'ip': request.remote_addr} - if None in (gsm, codeword, shortno): + for key in ('msgid', 'msisdn', 'msg', 'mms', 'mmsdata', 'shortcode', + 'mcc', 'mnc', 'pricegroup', 'keyword', 'keywordid', + 'errorcode', 'errormessage', 'registered'): + args[key] = request.args.get(key, None) + + app.logger.debug("Incoming, args: %s", args) + + if None in (args['msisdn'], args['keyword'], args['shortcode']): abort(400) # Bad Request - if not gsm.isdigit(): + msisdn = args['msisdn'] + keyword = args['keyword'].strip().upper() + shortcode = args['shortcode'] + + if not msisdn.isdigit(): # What the fuck, man, that's not a phone number, man. abort(400) # Bad Request - if not codeword.strip().upper() in ('DNS', 'DNSMEDLEM'): + if not keyword in ('DNS', 'DNSMEDLEM'): abort(400) # Bad Request - user = get_user_by_phone("+47%s" % gsm) + if not shortcode in ('2454'): + abort(400) # Bad Request - smsid = log_incoming( - userid=int(user['id']) if user else None, - gsm=gsm, - codeword=codeword, - message=message, - operator=operator, - shortno=shortno, - action='no_action', - ip=ip, - simulation=0) + incoming_id = log_incoming(**args) - app.logger.info("Incoming SMS from gsm:%s saved with smsid:%s", gsm, smsid) + app.logger.info( + "Incoming SMS from number:%s saved with id:%s", + args['msisdn'], incoming_id) + + user = get_inside().get_user_by_phone(msisdn) if user: - expired = is_user_expired(user) + expired = get_inside().user_is_expired(user) - if codeword.strip().upper() == 'DNS': + if keyword == 'DNS': if not expired: - return notify_valid_membership(response_to=smsid, gsm=gsm, user=user) + return notify_valid_membership( + incoming_id=incoming_id, number=msisdn, user=user) elif expired: - return notify_payment_options_renewal(response_to=smsid, gsm=gsm) - elif codeword.strip().upper() == 'DNSMEDLEM': + return notify_payment_options_renewal( + incoming_id=incoming_id, number=msisdn, user=user) + elif keyword == 'DNSMEDLEM': if not expired: - return notify_valid_membership(response_to=smsid, gsm=gsm, user=user) + return notify_valid_membership( + incoming_id=incoming_id, number=msisdn, user=user) elif expired: - return renew_membership(response_to=smsid, gsm=gsm, user=user, operator=operator) + return renew_membership( + incoming_id=incoming_id, number=msisdn, user=user) else: - if codeword.strip().upper() == 'DNS': - return notify_payment_options_new(response_to=smsid, gsm=gsm) - elif codeword.strip().upper() == 'DNSMEDLEM': - return new_membership(response_to=smsid, gsm=gsm, operator=operator) + if keyword == 'DNS': + return notify_payment_options_new( + incoming_id=incoming_id, number=msisdn) + elif keyword == 'DNSMEDLEM': + return new_membership( + incoming_id=incoming_id, number=msisdn) + + app.logger.error('Unhandled SMS, incoming_id=%s', incoming_id) -@app.route('/dlr') +@app.route('/sendega-dlr') def dlr(): - return '' + args = {'ip': request.remote_addr} + + for key in ('msgid', 'extID', 'msisdn', 'status', 'statustext', + 'registered', 'sent', 'delivered', + 'errorcode', 'errormessage', 'operatorerrorcode'): + args[key] = request.args.get(key, None) + + dlr_id = log_dlr(**args) + + # We need to check what the original message was all about + incoming_id = args['extID'] + + event = query_db('SELECT * FROM event WHERE incoming_id=%s', + incoming_id, one=True) + + if not event: + app.logger.error('Got an unknown delivery report, dlr_id=%s', dlr_id) + return 'what' + + success = (args['status'] == 4) + action = event['action'] + + if not success: + return notify_could_not_charge( + incoming_id=incoming_id, dlr_id=dlr_id, number=args['msisdn']) + + if action == 'renew_membership': + return renew_membership_delivered( + incoming_id=incoming_id, dlr_id=dlr_id, user_id=event['user_id']) + elif action == 'new_membership': + return new_membership_delivered( + incoming_id=incoming_id, dlr_id=dlr_id) + + app.logger.error('Unhandled DLR, dlr_id=%s', dlr_id) if __name__ == '__main__': app.run()