node.jsjsontypeform

Get all answers reply value from Typeform payload - NodeJS


Typeform's Webhook payload looks like below (Described: Typeform docs)

{
  "event_id": "01G8DK433Z6V1TGK2TGKBV3F2E",
  "event_type": "form_response",
  "form_response": {
    "form_id": "e8cPLv2K",
    "token": "01G8DK433Z6V1TGK2TGKBV3F2E",
    "landed_at": "2022-07-20T10:40:41Z",
    "submitted_at": "2022-07-20T10:40:41Z",
    "hidden": {
      "center": "hidden_value",
      "epost": "hidden_value",
      "navn": "hidden_value",
      "telefon": "hidden_value"
    },
    "definition": {
      "id": "e8cPLv2K",
      "title": "TST - AppForm",
      "fields": [
        {
          "id": "FSFY4Z4cYeiM",
          "ref": "beb79bf4-d2f8-483e-8ac9-89c4f4d1f537",
          "type": "short_text",
          "title": "Navn ",
          "properties": {}
        },
        {
          "id": "twEi9zVDtCe9",
          "ref": "02cc325b-16f8-4e1f-bfed-8c33652ccd8f",
          "type": "email",
          "title": "E-post",
          "properties": {}
        },
        {
          "id": "6AY0xPhLKFTI",
          "ref": "305f0b4b-7e94-45cc-bbf6-0cdbdd612831",
          "type": "short_text",
          "title": "Telefonnummer",
          "properties": {}
        },
        {
          "id": "PRDxsquMmsUT",
          "ref": "0bebcb0b-677f-4230-b349-5f1c81e8392b",
          "type": "short_text",
          "title": "Skriv hva du vil :)",
          "properties": {}
        },
        {
          "id": "IfhKml9JtP2I",
          "ref": "e912d118-ca93-4fb4-9c39-fbece3ec1215",
          "type": "email",
          "title": "E-post",
          "properties": {}
        },
        {
          "id": "XzqmZI9S1LpF",
          "ref": "01FPYWPBJZ9R58WXDTBG73GYJH",
          "type": "multiple_choice",
          "title": "hva liker du best? A eller be",
          "properties": {},
          "choices": [
            {
              "id": "Ei4oc8JCG8Ht",
              "label": "Dette er A"
            },
            {
              "id": "pQDp1qFKzL8d",
              "label": "Dette er B"
            }
          ]
        }
      ],
      "hidden": [
        "center",
        "navn",
        "epost",
        "telefon"
      ]
    },
    "answers": [
      {
        "type": "text",
        "text": "Lorem ipsum dolor1",
        "field": {
          "id": "FSFY4Z4cYeiM",
          "type": "short_text",
          "ref": "beb79bf4-d2f8-483e-8ac9-89c4f4d1f537"
        }
      },
      {
        "type": "email",
        "email": "an_account1@example.com",
        "field": {
          "id": "twEi9zVDtCe9",
          "type": "email",
          "ref": "02cc325b-16f8-4e1f-bfed-8c33652ccd8f"
        }
      },
      {
        "type": "text",
        "text": "Lorem ipsum dolor2",
        "field": {
          "id": "6AY0xPhLKFTI",
          "type": "short_text",
          "ref": "305f0b4b-7e94-45cc-bbf6-0cdbdd612831"
        }
      },
      {
        "type": "text",
        "text": "Lorem ipsum dolor3",
        "field": {
          "id": "PRDxsquMmsUT",
          "type": "short_text",
          "ref": "0bebcb0b-677f-4230-b349-5f1c81e8392b"
        }
      },
      {
        "type": "email",
        "email": "an_account2@example.com",
        "field": {
          "id": "IfhKml9JtP2I",
          "type": "email",
          "ref": "e912d118-ca93-4fb4-9c39-fbece3ec1215"
        }
      },
      {
        "type": "choice",
        "choice": {
          "label": "Barcelona"
        },
        "field": {
          "id": "XzqmZI9S1LpF",
          "type": "multiple_choice",
          "ref": "01FPYWPBJZ9R58WXDTBG73GYJH"
        }
      }
    ]
  }
}

I narrowed it down when I tested:

body = JSON.parse(req.body);
answers = body.form_response.answers;

But how do I loop through, and get the end user response, for all "answers"? The idea is to have a function to work with no matter what order, or type of questions, or how many question a form might have.

Expected result from example over (or something similar - the idea is to just to get the answers out):

text: Lorem ipsum dolor1
email: an_account1@example.com
text: Lorem ipsum dolor2
text: Lorem ipsum dolor3
email: an_account2@example.com
choice: Barcelona

(I also have used the Typeform API (with oAuth) and works fine, but in this case I want to learn to read any Typeform answers from webhook payload)

Any ideas?


Solution

  • Based on Typeform docs for answers you can loop through the array like this and extract the answer value:

    // mocked request object
    const req = {
      body: '{"event_id":"01G8DK433Z6V1TGK2TGKBV3F2E","event_type":"form_response","form_response":{"form_id":"e8cPLv2K","token":"01G8DK433Z6V1TGK2TGKBV3F2E","landed_at":"2022-07-20T10:40:41Z","submitted_at":"2022-07-20T10:40:41Z","hidden":{"center":"hidden_value","epost":"hidden_value","navn":"hidden_value","telefon":"hidden_value"},"definition":{"id":"e8cPLv2K","title":"TST - AppForm","fields":[{"id":"FSFY4Z4cYeiM","ref":"beb79bf4-d2f8-483e-8ac9-89c4f4d1f537","type":"short_text","title":"Navn ","properties":{}},{"id":"twEi9zVDtCe9","ref":"02cc325b-16f8-4e1f-bfed-8c33652ccd8f","type":"email","title":"E-post","properties":{}},{"id":"6AY0xPhLKFTI","ref":"305f0b4b-7e94-45cc-bbf6-0cdbdd612831","type":"short_text","title":"Telefonnummer","properties":{}},{"id":"PRDxsquMmsUT","ref":"0bebcb0b-677f-4230-b349-5f1c81e8392b","type":"short_text","title":"Skriv hva du vil :)","properties":{}},{"id":"IfhKml9JtP2I","ref":"e912d118-ca93-4fb4-9c39-fbece3ec1215","type":"email","title":"E-post","properties":{}},{"id":"XzqmZI9S1LpF","ref":"01FPYWPBJZ9R58WXDTBG73GYJH","type":"multiple_choice","title":"hva liker du best? A eller be","properties":{},"choices":[{"id":"Ei4oc8JCG8Ht","label":"Dette er A"},{"id":"pQDp1qFKzL8d","label":"Dette er B"}]}],"hidden":["center","navn","epost","telefon"]},"answers":[{"type":"text","text":"Lorem ipsum dolor1","field":{"id":"FSFY4Z4cYeiM","type":"short_text","ref":"beb79bf4-d2f8-483e-8ac9-89c4f4d1f537"}},{"type":"email","email":"an_account1@example.com","field":{"id":"twEi9zVDtCe9","type":"email","ref":"02cc325b-16f8-4e1f-bfed-8c33652ccd8f"}},{"type":"text","text":"Lorem ipsum dolor2","field":{"id":"6AY0xPhLKFTI","type":"short_text","ref":"305f0b4b-7e94-45cc-bbf6-0cdbdd612831"}},{"type":"text","text":"Lorem ipsum dolor3","field":{"id":"PRDxsquMmsUT","type":"short_text","ref":"0bebcb0b-677f-4230-b349-5f1c81e8392b"}},{"type":"email","email":"an_account2@example.com","field":{"id":"IfhKml9JtP2I","type":"email","ref":"e912d118-ca93-4fb4-9c39-fbece3ec1215"}},{"type":"choice","choice":{"label":"Barcelona"},"field":{"id":"XzqmZI9S1LpF","type":"multiple_choice","ref":"01FPYWPBJZ9R58WXDTBG73GYJH"}}]}}'
    }
    
    const body = JSON.parse(req.body);
    const answers = body.form_response.answers;
    
    answers.forEach((answer) => {
      const { type, text, number, email, date, boolean, url, file_url, choice, payment } = answer
      const value = text 
        || number 
        || email 
        || date 
        || boolean 
        || url 
        || file_url 
        || choice?.label 
        || choice?.labels?.join(', ') 
        || payment && `${payment.name} - ${payment.amount} (${payment.success ? 'PAID' : 'FAILED'})`
      console.log(`${type}: ${value}`)
    })