Merge pull request #1611 from alphagov/inbound-callback

Inbound callback page
This commit is contained in:
Pete Herlihy
2017-11-03 16:22:48 +00:00
committed by GitHub
7 changed files with 82 additions and 14 deletions

View File

@@ -693,10 +693,10 @@ class ServiceInboundNumberForm(Form):
class ServiceInboundApiForm(Form): class ServiceInboundApiForm(Form):
url = StringField("Inbound sms url", url = StringField("Callback URL",
validators=[DataRequired(message='Cant be empty'), validators=[DataRequired(message='Cant be empty'),
Regexp(regex="^https.*", Regexp(regex="^https.*",
message='Must be a valid https url')] message='Must be a valid https URL')]
) )
bearer_token = PasswordFieldShowHasContent("Bearer token", bearer_token = PasswordFieldShowHasContent("Bearer token",
validators=[DataRequired(message='Cant be empty'), validators=[DataRequired(message='Cant be empty'),

View File

@@ -135,3 +135,8 @@ def using_notify():
@main.route('/information-risk-management') @main.route('/information-risk-management')
def information_risk_management(): def information_risk_management():
return render_template('views/information-risk-management.html') return render_template('views/information-risk-management.html')
@main.route('/callbacks')
def callbacks():
return render_template('views/callbacks.html')

View File

@@ -0,0 +1,63 @@
{% from "components/table.html" import mapping_table, row, text_field, edit_field, field, row_heading%}
{% extends "withoutnav_template.html" %}
{% block per_page_title %}
Callbacks
{% endblock %}
{% block maincolumn_content %}
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-large">Callbacks for received text messages</h1>
<p>
Text messages you receive can be forwarded to a URL that you specify, using our callback feature.
</p>
<p>
Messages are forwarded as they are received.
</p>
<p>
To protect your service, we require you to provide a bearer token. We put this token in the authorisation header of the callback requests.
</p>
<p>
Once you have receive text messages enabled, you can set up your callback on the settings page of your service.
</p>
<p>
If you dont have receive text messages enabled for your service, <a href="{{ url_for('.support') }}">get in touch</a> and we can turn it on for you.
</p>
<h2 class="heading-medium">Format of the callback</h2>
<p>
The format of the callback message you receive is JSON.
</p>
<div class="bottom-gutter-3-2">
{% call mapping_table(
caption='Callback message format',
field_headings=['Key', 'Description', 'Format'],
field_headings_visible=True,
caption_visible=False
) %}
{% for key, description, format in [
('id', 'Notifys id for the received message', 'UUID'),
('source_number', 'The phone number the message was sent from', '447700912345'),
('destination_number', 'The number the message was sent to (your number)', '07700987654'),
('message', 'The received message', 'Hello Notify!'),
('date_received', 'The UTC datetime that the message was received by Notify', '2017-05-14T12:15:30.000000Z')
] %}
{% call row() %}
{% call row_heading() %} {{ key }} {% endcall %}
{{ text_field(description) }}
{{ text_field(format) }}
{% endcall %}
{% endfor %}
{% endcall %}
</div>
{% endblock %}

View File

@@ -106,7 +106,7 @@
{% if can_receive_inbound %} {% if can_receive_inbound %}
{% call row() %} {% call row() %}
{{ text_field('API endpoint for received text messages') }} {{ text_field('Callback URL for received text messages') }}
{{ optional_text_field(inbound_api_url) }} {{ optional_text_field(inbound_api_url) }}
{{ edit_field('Change', url_for('.service_set_inbound_api', service_id=current_service.id)) }} {{ edit_field('Change', url_for('.service_set_inbound_api', service_id=current_service.id)) }}
{% endcall %} {% endcall %}

View File

@@ -3,27 +3,27 @@
{% from "components/page-footer.html" import page_footer %} {% from "components/page-footer.html" import page_footer %}
{% block service_page_title %} {% block service_page_title %}
Inbound api Callback URL
{% endblock %} {% endblock %}
{% block maincolumn_content %} {% block maincolumn_content %}
<div class="grid-row"> <div class="grid-row">
<div class="column-five-sixths"> <div class="column-five-sixths">
<h1 class="heading-large">API endpoint for received text messages</h1> <h1 class="heading-large">Callback URL for received text messages</h1>
<p> <p>
This is the https url that the inbound SMS messages will be posted to Text messages you receive can be forwarded to your systems with our callback feature.
and the bearer token used in the authorisation header of the request. See our <a href="{{ url_for('.callbacks') }}">documentation on the format of the callback</a>.
</p> </p>
<form method="post"> <form method="post">
{{ textbox( {{ textbox(
form.url, form.url,
width='2-3', width='2-3',
hint='Valid https url' hint='Valid https URL'
) }} ) }}
{{ textbox( {{ textbox(
form.bearer_token, form.bearer_token,
width='1-4', width='2-3',
hint='At least 10 characters' hint='At least 10 characters'
) }} ) }}
{{ page_footer( {{ page_footer(
@@ -35,4 +35,4 @@
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@@ -18,7 +18,7 @@ def test_logged_in_user_redirects_to_choose_service(
@pytest.mark.parametrize('view', [ @pytest.mark.parametrize('view', [
'cookies', 'using_notify', 'pricing', 'terms', 'integration_testing', 'roadmap', 'cookies', 'using_notify', 'pricing', 'terms', 'integration_testing', 'roadmap',
'features', 'information_risk_management' 'features', 'information_risk_management', 'callbacks'
]) ])
def test_static_pages( def test_static_pages(
client, client,

View File

@@ -121,7 +121,7 @@ def test_should_show_overview(
'Text message sender GOVUK Manage', 'Text message sender GOVUK Manage',
'International text messages On Change', 'International text messages On Change',
'Receive text messages On Change', 'Receive text messages On Change',
'API endpoint for received text messages Not set Change', 'Callback URL for received text messages Not set Change',
'Label Value Action', 'Label Value Action',
'Send letters Off Change', 'Send letters Off Change',
@@ -207,7 +207,7 @@ def test_service_settings_show_elided_api_url_if_needed(
non_empty_trs = [tr.find_all('td') for tr in page.find_all('tr') if tr.find_all('td')] non_empty_trs = [tr.find_all('td') for tr in page.find_all('tr') if tr.find_all('td')]
api_url = [api_setting[1].text.strip() for api_setting in non_empty_trs api_url = [api_setting[1].text.strip() for api_setting in non_empty_trs
if api_setting[0].text.strip() == 'API endpoint for received text messages'][0] if api_setting[0].text.strip() == 'Callback URL for received text messages'][0]
assert api_url == elided_url assert api_url == elided_url
assert mocked_get_fn.called is True assert mocked_get_fn.called is True
@@ -1272,7 +1272,7 @@ def test_does_not_show_research_mode_indicator(
@pytest.mark.parametrize('url, bearer_token, expected_errors', [ @pytest.mark.parametrize('url, bearer_token, expected_errors', [
("", "", "Cant be empty Cant be empty"), ("", "", "Cant be empty Cant be empty"),
("http://not_https.com", "1234567890", "Must be a valid https url"), ("http://not_https.com", "1234567890", "Must be a valid https URL"),
("https://test.com", "123456789", "Must be at least 10 characters"), ("https://test.com", "123456789", "Must be at least 10 characters"),
]) ])
def test_set_inbound_api_validation( def test_set_inbound_api_validation(