Archived
Switch to using the Sendega API. Now with delivery reports!
This commit is contained in:
1 parent
6e31ee9645
commit
abc95b06e0
1 file changed
+335
-287
+335
-287
@@ -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()
|
||||
|
||||
Reference in new issue
Block a user