Skip to main content

Submitter

[Needs Reviewing]

Submitting user data

Once a user’s data has been collected and the user has confirmed that the data is correct, urls representing the required output of the data and any uploaded files are sent to the submitter api

Submitting overview

[to add] Submission overview diagram

Default output

Send copy to user

In order to send a copy to the user, there must be an email address to send to:

  • If a value has been defined in the service configuration for emailInputNameUser, the value entered for the control with that name is used as the user’s email address
  • Otherwise, if a control named email exists, the value for that is used
Outputs
  • Email message
    • /api/submitter/email/user
  • PDF output
    • /api/submitter/pdf/default/:submissionId.pdf

Send application to service team via email

In order to send the data to the service team, there must be an email address to send to. This address is set through the Publisher as a config param SERVICE_OUTPUT_EMAIL

Outputs
  • Email message
    • /api/submitter/email/team
  • PDF output
    • /api/submitter/pdf/default/:submissionId.pdf
  • CSV (TODO)

JSON output

It is possible to get raw JSON for a submission from the Runner application. Currently this is forwarded onto adapters to make external API calls. In order to use this, two config params are required. SERVICE_OUTPUT_JSON_ENDPOINT and SERVICE_OUTPUT_JSON_KEY.

SERVICE_OUTPUT_JSON_ENDPOINT

The endpoint to which this JSON will be forwarded.

SERVICE_OUTPUT_JSON_KEY

A JWE key used for encrypting the data. This key has to be exactly 16 bytes.

  • API endpoint
    • /api/submitter/json/default/:submissionId.json

Output specification

In future, it will be possible to define alternative outputs

TODO: output specification

Repo: fb-submitter

The Submitter is an app that provides an API and workers for dealing with a form’s submissions.

Submitter API

Introduction

When a user has completed their journey on a FormBuilder service, they will be presented with a ‘Check your answers’ page with the option to submit their data.

Once they click to submit, they should immediately get a confirmation message, with a reference number that they can use for future reference if needed. The component that generates this reference number and takes responsibility for sending the data to where it needs to go, is the “Submitter”.

This document summarises requirements for the Submitter, its API calls, parameters & responses.

System Context

TODO: Insert image

API

Constraints: No Ingress, JWT authentication, JSON-only, HTTPS-only (NB. dependent on Cloud Platforms providing a solution for cluster-internal SSL)

Following the same pattern as the User Data Store, each request will be timestamped and signed using a per-service serviceToken (generated by Publisher and injected into the service’s Runner as an environment variable).

Methods

Every request must be signed using JWT with the service’s serviceToken (this will be injected into the Runner’s container as an environment variable called SERVICE_TOKEN, by Publisher) Signing options should include iat: (current timestamp)to allow a time-limit and mitigate against replay attacks

The resulting token must be passed as a header called x-access-token

POST /submission

When the user clicks the final button to submit their data, the service should should perform a POST request to /submission, passing a JSON packet in the body of the following form:

{
    "service_slug": "...",
    "encrypted_user_id_and_token": "(userId and userToken encrypted via AES-256 with the serviceToken as the key - sent back to runner as ‘x-encrypted-user-id-and-token’ header)",
    "submission_details": [
        {
            "type": "email",
            "to": "email address of recipient",
      "from": "email address replies go to",
            "subject": "(mail subject line)",
            "body_parts": {
                "text/html": "(relative url)",
                "text/plain": "(relative url)"
            },
            "attachments": [
                "(relative url 1)",
                "(relative url 2)",
                "(...)"
      ]
    },
    ["..."]
    ]
}
  • If the request was successful:
    • A submission record will be created to store the given details
    • A job will be placed on the queue for asynchronous execution
    • The response status will be 201 Created
    • The body of the response will contain a JSON packet of the form: json { "id": "(uuid of the submission for future reference)", "created_at": "(timestamp in ISO-8601 format)", "updated_at": "(timestamp in ISO-8601 format)", "status": "(queued|processing|retrying|completed|failed)" }
  • If the token is not present, the response will be 401 Unauthorised
  • If the token is not valid, the response will be 403 Forbidden
  • Other failure types will result in the corresponding standard HTTP response codes (400, 500, etc)
GET /submission/:submission_id

Allows retrieval of the submission status. Returns a response of the form:

{
    "id": "(uuid of the submission for future reference)",
    "created_at": "(timestamp in ISO-8601 format)",
    "updated_at": "(timestamp in ISO-8601 format)",
    "status": "(queued|processing|completed|failed)"
}

Submitter Workers

In the same manner as Publisher, there will be separate containers/pods for the back-end worker processes, which will be responsible for retrieving the PDFs and actually sending the emails via Amazon SES. The queue will be Resque using Elasticache Redis, and the job framework will be ActiveJob with a Resque backend.

When processing a submission, the job will:

  • Update the submission record status to processing
  • Read the email submission details
  • Retrieve PDFs from all of the given URLs (in the event of the same PDF being required by multiple emails, it will only retrieve the PDF once)
  • Construct an email to each recipient address, attaching the relevant PDFs
  • Send the email via Amazon SES
  • Update the submission record status to completed
  • If there is a retryable error (e.g. timeout retrieving URLs) the job will automatically retry, and the submission record status will be updated to failed_retryable
  • If there is a non-retryable error at any point, the submission record status will be updated to failed_non_retryable
This page was last reviewed on 1 June 2021. It needs to be reviewed again on 1 September 2021 .
This page was set to be reviewed before 1 September 2021. This might mean the content is out of date.