Is there a way to simplify the processing of webhook data? | Community
Skip to main content
Answered

Is there a way to simplify the processing of webhook data?

  • September 7, 2021
  • 9 replies
  • 1247 views

Hi :wave:,

I need to save the results from the TypeForm web hook to a SQL database for my project.

Is there a simple and efficient way to process the data received on the web hook?

I am on PHP8/Symfony5,

  • I want to know if there is a way to customize the results, for example by putting a string key instead of a translated string for the choice type results.
  • If is exist another way than id to identify what answer correspond
  • I don't want to store in the database all possible answer identifiers to link with the right data

Thank you for helping me :)

Best answer by picsoung

Hey @bandofboats 

We send you a JSON payload to your app.

If you are not familiar on how to receive JSON webhook on your PHP app you can refer to this StackOverflow question.

$data = json_decode(file_get_contents('php://input'));
$answers = $data->form_response->answers;

Each question is identified by both an id and a ref. Similarly for a choice in a mulitple choice, picture choice or dropdown. While you can’t edit the id, you still can edit the ref to make it easier to work with.
Do do so you will go to ⚙️ → For Developers → Block References.
And there you can edit references.
Unfortunately we don’t support yet editing choice reference, you will have to use this tool to do so.

Hope this helps

View original

9 replies

Liz
Community Team
Forum|alt.badge.img+5
  • Tech Community Advocate
  • 14857 replies
  • September 7, 2021

Hi @bandofboats Happy Tuesday! We don’t have customization options for the webhook data at this time, but tagging @picsoung in case they happen to know of any fancy workarounds for this. :grinning:


picsoung
Typeform
Forum|alt.badge.img+5
  • Developer Advocate @ Typeform
  • 384 replies
  • Answer
  • September 7, 2021

Hey @bandofboats 

We send you a JSON payload to your app.

If you are not familiar on how to receive JSON webhook on your PHP app you can refer to this StackOverflow question.

$data = json_decode(file_get_contents('php://input'));
$answers = $data->form_response->answers;

Each question is identified by both an id and a ref. Similarly for a choice in a mulitple choice, picture choice or dropdown. While you can’t edit the id, you still can edit the ref to make it easier to work with.
Do do so you will go to ⚙️ → For Developers → Block References.
And there you can edit references.
Unfortunately we don’t support yet editing choice reference, you will have to use this tool to do so.

Hope this helps


  • Author
  • Explorer
  • 2 replies
  • September 8, 2021

Thank’s @Liz and @picsoung this gonna help me to identify data :ok_hand:

Happy Wednesday


Liz
Community Team
Forum|alt.badge.img+5
  • Tech Community Advocate
  • 14857 replies
  • September 8, 2021

Glad to hear, @bandofboats ! Keep us posted on how this works for you. :grinning:


  • Explorer
  • 3 replies
  • September 16, 2021

@picsoung 

Hello Nicolas,
Actually we’re also struggling a lot with webhooks data here.

The question is not in parsing json process itself but in data structure sent to webhooks.

What we’re receiving here inside answers is object like this:

{
  "type": "text",
  "text": "Lorem ipsum dolor",
  "field": {
    "id": "p9XOht3JwNXf",
    "type": "short_text",
    "ref": "a3651332e7fa6c9e"
  }
}

Let’s try assume what is the fastest and efficient way to find text `Lorem ipsum dolor` by id or ref to put this value into specific db field.
And the answer will look like “Iterate via all objects and compare id or ref from nested `field` object with target id or ref value”. Then we should iterate through all objects again to find the value for 2nd target field and so on. Iterate through all objects as many times as many fields required to find.

I do not know yet what should I do to fetch selected values for predefined selections but from what we can see here already is developer-not-so-friendly data schema.

Please do something with this or explain how to handle this data schema fast and efficient.


  • Explorer
  • 3 replies
  • September 16, 2021
Dcentralab wrote:

@picsoung

Hello Nicolas,
Actually we’re also struggling a lot with webhooks data here.

The question is not in parsing json process itself but in data structure sent to webhooks.

What we’re receiving here inside answers is object like this:

{
  "type": "text",
  "text": "Lorem ipsum dolor",
  "field": {
    "id": "p9XOht3JwNXf",
    "type": "short_text",
    "ref": "a3651332e7fa6c9e"
  }
}

Let’s try assume what is the fastest and efficient way to find text `Lorem ipsum dolor` by id or ref to put this value into specific db field.
And the answer will look like “Iterate via all objects and compare id or ref from nested `field` object with target id or ref value”. Then we should iterate through all objects again to find the value for 2nd target field and so on. Iterate through all objects as many times as many fields required to find.

I do not know yet what should I do to fetch selected values for predefined selections but from what we can see here already is developer-not-so-friendly data schema.

Please do something with this or explain how to handle this data schema fast and efficient.

 

Hello, Questioner from the past

The answer for your question about how to not iterate through all fields every time to find and get required field value sounds like “Iterate through all objects once, compare answer['field']['id'] with required value and try to fit this answer’s value into database field”. This looks like something upside down but at least we haven’t to iterate each time. Still no any way invented to implement direct getters.


  • Author
  • Explorer
  • 2 replies
  • September 17, 2021

@Dcentralab@Liz Im gonna show you how i’ve found a way to be efficient to work with this payload ;) (only api calls to typeform are not efficient but it just need to be fixed on webhook payload)

 

  1. I use the tf-edit tool to custom my ref
  2. The refs values i use is all the properties name in my PHP class (Entity on Symfony)
  3. I use this function to return my entity with all data set inside, after this i just have to flush in my db

    (if you want to copy paste)

    private function processReview(array $answers, ReviewOffice|ReviewVersion $entity): ReviewOffice|ReviewVersion
        {
            // after json decode and get $payload->form_response->answers i use this function
            foreach ($answers as $answer) {
                // that return me a string like $setter => 'setTimeLimitScore'
                $setter = 'set'.ucfirst($answer->field->ref);
                switch ($answer->type) {
                    // for each answer's question type case
                    case self::CHOICE:
                        $entity->{$setter}($answer->choice);
                        /* todo: when webhook is fixed (we don't receive ref for this type yet)
                        $entity->{$setter}($answer->field->ref); */
                        break;
                    case self::CHOICES:
    
                        // Use TypeForm api directly to get ref on choices type
                        $response = $this->client->request(
                            'GET',
                            'https://api.typeform.com/forms/'.$this->formId
                        );
                        $response = json_decode($response->getContent());
                        $field = array_values(array_filter($response->fields, fn ($field) => $field->id === $answer->field->id))[0];
                        $choices = array_filter($field->properties->choices, fn ($choice) => in_array($choice->label, $answer->choices->labels));
                        $choicesRef = array_map(fn ($choice) => $choice->ref, $choices);
                        $entity->{$setter}($choicesRef);
    
                        /* todo: when webhook is fixed (we don't receive ref for this type yet)
                        $choicesRef = [];
                        foreach ($answer->choices as $choice) {
                            $choicesRef[] = $choice->ref;
                        }
                        $entity->{$setter}($choicesRef); */
    
                        break;
                    case self::NUMBER:
                        $entity->{$setter}($answer->number);
                        break;
                    case self::TEXT:
                        if (self::REVIEW_TEXT == $answer->field->ref) {
                            break;
                        }
                        $entity->{$setter}($answer->text);
                        break;
                    default:
                        throw new BadRequestException('case not supported');
                }
            }
    
            return $entity;
        }

     


Liz
Community Team
Forum|alt.badge.img+5
  • Tech Community Advocate
  • 14857 replies
  • September 21, 2021

Liz
Community Team
Forum|alt.badge.img+5
  • Tech Community Advocate
  • 14857 replies
  • July 25, 2023

Reply