2018-02-20 11:22:17 +00:00
|
|
|
from flask import jsonify, redirect, render_template, session, url_for
|
2017-05-24 13:19:31 +01:00
|
|
|
from flask_login import login_required
|
2018-02-20 11:22:17 +00:00
|
|
|
from notifications_python_client.errors import HTTPError
|
2017-05-24 13:19:31 +01:00
|
|
|
from notifications_utils.recipients import format_phone_number_human_readable
|
|
|
|
|
from notifications_utils.template import SMSPreviewTemplate
|
2018-02-20 11:22:17 +00:00
|
|
|
|
2018-10-25 07:59:50 +01:00
|
|
|
from app import current_service, notification_api_client, service_api_client
|
2017-05-24 13:19:31 +01:00
|
|
|
from app.main import main
|
2019-02-06 17:32:13 +00:00
|
|
|
from app.main.forms import SearchByNameForm
|
2017-11-07 17:22:57 +00:00
|
|
|
from app.utils import user_has_permissions
|
2017-05-24 13:19:31 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@main.route("/services/<service_id>/conversation/<notification_id>")
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
@user_has_permissions('view_activity')
|
2017-05-24 13:19:31 +01:00
|
|
|
def conversation(service_id, notification_id):
|
|
|
|
|
|
|
|
|
|
user_number = get_user_number(service_id, notification_id)
|
|
|
|
|
|
|
|
|
|
return render_template(
|
|
|
|
|
'views/conversations/conversation.html',
|
|
|
|
|
user_number=user_number,
|
2017-07-07 15:34:06 +01:00
|
|
|
partials=get_conversation_partials(service_id, user_number),
|
|
|
|
|
updates_url=url_for('.conversation_updates', service_id=service_id, notification_id=notification_id),
|
2017-10-15 12:59:36 +01:00
|
|
|
notification_id=notification_id,
|
2017-05-24 13:19:31 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2017-07-07 15:34:06 +01:00
|
|
|
@main.route("/services/<service_id>/conversation/<notification_id>.json")
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
@user_has_permissions('view_activity')
|
2017-07-07 15:34:06 +01:00
|
|
|
def conversation_updates(service_id, notification_id):
|
|
|
|
|
|
|
|
|
|
return jsonify(get_conversation_partials(
|
|
|
|
|
service_id,
|
|
|
|
|
get_user_number(service_id, notification_id)
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
2017-10-15 12:59:36 +01:00
|
|
|
@main.route("/services/<service_id>/conversation/<notification_id>/reply-with")
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
@user_has_permissions('send_messages')
|
2017-10-15 12:59:36 +01:00
|
|
|
def conversation_reply(
|
|
|
|
|
service_id,
|
|
|
|
|
notification_id,
|
|
|
|
|
):
|
2018-11-05 15:26:59 +00:00
|
|
|
templates = current_service.get_templates('sms')
|
2017-10-15 12:59:36 +01:00
|
|
|
return render_template(
|
|
|
|
|
'views/templates/choose-reply.html',
|
|
|
|
|
templates=templates,
|
|
|
|
|
show_search_box=(len(templates) > 7),
|
|
|
|
|
template_type='sms',
|
2019-02-06 17:32:13 +00:00
|
|
|
search_form=SearchByNameForm(),
|
2017-10-15 13:40:49 +01:00
|
|
|
notification_id=notification_id,
|
2017-10-15 12:59:36 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2017-10-15 13:40:49 +01:00
|
|
|
@main.route("/services/<service_id>/conversation/<notification_id>/reply-with/<template_id>")
|
|
|
|
|
@login_required
|
2018-03-01 10:30:17 +00:00
|
|
|
@user_has_permissions('send_messages')
|
2017-10-15 13:40:49 +01:00
|
|
|
def conversation_reply_with_template(
|
|
|
|
|
service_id,
|
|
|
|
|
notification_id,
|
|
|
|
|
template_id,
|
|
|
|
|
):
|
|
|
|
|
|
|
|
|
|
session['recipient'] = get_user_number(service_id, notification_id)
|
|
|
|
|
session['placeholders'] = {'phone number': session['recipient']}
|
|
|
|
|
|
|
|
|
|
return redirect(url_for(
|
|
|
|
|
'main.send_one_off_step',
|
|
|
|
|
service_id=service_id,
|
|
|
|
|
template_id=template_id,
|
|
|
|
|
step_index=1,
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
2017-07-07 15:34:06 +01:00
|
|
|
def get_conversation_partials(service_id, user_number):
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
'messages': render_template(
|
|
|
|
|
'views/conversations/messages.html',
|
|
|
|
|
conversation=get_sms_thread(service_id, user_number),
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2017-05-24 13:19:31 +01:00
|
|
|
def get_user_number(service_id, notification_id):
|
|
|
|
|
try:
|
|
|
|
|
user_number = service_api_client.get_inbound_sms_by_id(service_id, notification_id)['user_number']
|
2018-05-03 15:40:24 +01:00
|
|
|
except HTTPError as e:
|
|
|
|
|
if e.status_code != 404:
|
|
|
|
|
raise
|
2017-05-24 13:19:31 +01:00
|
|
|
user_number = notification_api_client.get_notification(service_id, notification_id)['to']
|
|
|
|
|
return format_phone_number_human_readable(user_number)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_sms_thread(service_id, user_number):
|
2017-06-07 15:46:34 +01:00
|
|
|
|
|
|
|
|
for notification in sorted((
|
2018-03-12 12:44:32 +00:00
|
|
|
notification_api_client.get_notifications_for_service(service_id,
|
|
|
|
|
to=user_number,
|
|
|
|
|
template_type='sms')['notifications'] +
|
2018-03-21 15:08:03 +00:00
|
|
|
service_api_client.get_inbound_sms(service_id, user_number=user_number)['data']
|
2017-06-07 15:46:34 +01:00
|
|
|
), key=lambda notification: notification['created_at']):
|
|
|
|
|
|
|
|
|
|
is_inbound = ('notify_number' in notification)
|
2017-09-29 10:15:17 +01:00
|
|
|
redact_personalisation = not is_inbound and notification['template']['redact_personalisation']
|
2017-07-07 10:04:49 +01:00
|
|
|
|
|
|
|
|
if redact_personalisation:
|
|
|
|
|
notification['personalisation'] = {}
|
2017-06-07 15:46:34 +01:00
|
|
|
|
|
|
|
|
yield {
|
|
|
|
|
'inbound': is_inbound,
|
2017-05-24 13:19:31 +01:00
|
|
|
'content': SMSPreviewTemplate(
|
2017-11-07 17:22:57 +00:00
|
|
|
{
|
|
|
|
|
'content': (
|
|
|
|
|
notification['content'] if is_inbound else
|
|
|
|
|
notification['template']['content']
|
|
|
|
|
)
|
|
|
|
|
},
|
2017-07-07 10:04:49 +01:00
|
|
|
notification.get('personalisation'),
|
|
|
|
|
downgrade_non_gsm_characters=(not is_inbound),
|
|
|
|
|
redact_missing_personalisation=redact_personalisation,
|
2017-05-24 13:19:31 +01:00
|
|
|
),
|
|
|
|
|
'created_at': notification['created_at'],
|
|
|
|
|
'status': notification.get('status'),
|
|
|
|
|
'id': notification['id'],
|
|
|
|
|
}
|