Parsing JSON text into a Bubble Data Structure

I am using an API call to get results of surveys from Lime Survey. The data is returned as a base64 encoded string inside a JSON structure:

{“id”:1, “result”:“eyJyZXNwb25zZXMiOiBbeyJpZCI6IjEiLCJzdWJtaXRkYXRlIjoiMTk4MC0wMS0wMSAwMDowMDowMCIsImxhc3RwYWdlIjoiMSIsInN0YXJ0bGFuZ3VhZ2UiOiJlbiIsInNlZWQiOiIxNzA0ODQ2MzI2IiwidG9rZW4iOiJHZW42THpPVU9SMHUzRDciLCJHMDFRMDJbU1EwMDFdIjoiMyIsIlEwMCI6IjMifV19”, “error”:null}

Easy enough, I decode the result from the above JSON, which gives me more JSON:
{“responses”: [{“id”:“1”,“submitdate”:“1980-01-01 00:00:00”,“lastpage”:“1”,“startlanguage”:“en”,“seed”:“1704846326”,“token”:“Gen6LzOUOR0u3D7”,“G01Q02[SQ001]”:“3”,“Q00”:“3”}]}

This JSON however is now just a string inside Bubble. I want to parse it and put it into the database. Table will have 3 columns, token, question, answer. From the JSON above, I would have 2 rows:
Gen6LzOUOR0u3D7, G01Q02[SQ001], 3
Gen6LzOUOR0u3D7, Q00,3

My question is, how can I parse the JSON string I get back from the base64 encoded string and get it into the database? It doesn’t get mapped in the API because it is still encoded at that point. I haven’t found a plugin that will do it, but perhaps there is one? Is there some native way to map JSON to a Bubble thing?

3 Likes

Maybe you need some custom code written for you? :wink:

1 Like

You can use a plugin or alternatively you can create an endpoint (backend workflow), make the call from there, and return the json as plain text. Then you can call your endpoint using the API connector and it should be parsed automatically.

4 Likes

if you just consistently want those values then you could regex + Bubble text modify them out.
It’s totally non-elegant but the alternative gets very involved and I would definitely recommend a Jedi like @jared.gibb to guide you through it.

To get those out you would:

  1. apply a regex to the decoded string (?<=“token”:“).*?(?=}]})
  2. use find & replace on the first item in the result of (1), three times:
    2.1 swap out : for ,
    2.2 swap out for nothing
    2.3 swap out for nothing
  3. then use split by (,) as the last part of the expression

p.s. watch out for the speech mark values… there are diff types of speech marks out there - for a first attempt, try copying and pasting mine over as they match the ones in the return string.

Result will look like this, though your value won’t be coming from an input field.
Screenshot 2022-02-06 at 19.47.16

You’ll then have access to a list of 4 values that you can do something with.


For context, my entire app is built off of the mapped, coded approach - it’s awesome and very flexible. Just don’t go in lightly.

4 Likes

I think I will start with the back end workflow approach. I would prefer to keep things in native Bubble. Barring that, couldn’t I pass the string to Javascript via the toolbox, manipulate it and then pass back a list? Rather than the Regex attack. The only problem with Javascript being the questions will be different from survey to survey.

I haven’t actually tested it, but I’m not sure that will work, because the Content-Type response header (MIME type) will be incorrect. JSON should be served as application/json, but the endpoint will return text/plain for the content type. If it does work, that will be an interesting quirk, but it technically shouldn’t work.

I have done it many times :slight_smile:

1 Like

Nice trick then. I guess the API Connector ignores that header. :slightly_smiling_face:

A simple demo:

image

4 Likes

That’s really handy to know. I seem to recall having tried that with an external service and no go. I guess as long as Bubble is the API consumer, it seems to work. Thanks for the tip. Hopefully, it doesn’t get “fixed” by Bubble. :wink:

I use this technique for data manipulation all the time :slight_smile: the only “bad thing” is that you have to expose the endpoint, but you can keep it protected requiring authentication and if you want to put an extra layer of security, add a parameter as password and keep it safe. Also deactivate swagger

Can I get some clarification @pipeleteli? I am getting the following payload from a webhook:

{"type":"message_action","token":"****","action_ts":"1644940855.830058", ...(etc)}

The data is essentially JSON format but Bubble just sees it as text. Are you saying that the workaround is as follows:

  1. Schedule API workflow for Current Time (here called ‘parse_json’)
    image

  2. Setup a backend workflow with 1 step: Return data from API. Let it return the payload unedited.

  3. Use this returned data using ‘Result of step 1’
    image

The issue I now have is that Bubble doesn’t know what the structure of the Result is like so I can’t use the data. Clearly I’m missing something (or perhaps everything?!) - could you enlighten me?

Thanks! :slight_smile:

Have you tried to use the feature “Detect request data” to autogenerate the parameters (link to the documentation).

If the webhook sends the parameter “payload” and its value is a “JSON object” formatted as a string, like this:
{
“payload” : “{JSON object}”
}
You could create an auxiliar endpoint to pass that json in the body and parse the data to store it in your DB

3 Likes

Thanks, I understand now. I think the data I’m getting is formatted as Form Data like this:

payload: {“type”:“message_action”,“token”:“****”, …etc}

As raw data it looks like this:

payload=%7B%22type%22%3A%22message_action%22%2C%22token%22

I can pass the payload on like this but I can’t work out how to extract it still. I’ve tried two things:

  1. Detect data types at endpoint 2, sending the JSON from payload (from postman). This picks up all the data types it expects perfectly, but now I can’t schedule Endpoint 2 to run from Endpoint 1 (presumably because bubble doesn’t have the ability to send an initialization to endpoint_2/initialize)
  2. Manually enter the data types (eg type, token etc). However, when I try to save them to the database nothing comes through. I assume this means the JSON from payload isn’t quite in the right format?

Any ideas? I’m at a loss

This is URL encoded, so you will have decode it first, I believe there are couple of plugins that could help you with this: Decode URL/URI SSA (Server Side) Plugin | Bubble

Alternatively, you can use find and replace to decode it yourself, usually in this type of calls you have a few different type of characters you would have to replace like " { } . , : (). For instance, %7B is the encoded form of the character { , %22 is " , %3A is : and %2C is ,

I encourage you to give it a try, sadly I can’t think of a cleaner way to deal with this stuff right now and Bubble do not always have a straight forward solution, but at a first glance it looks like its totally doable :wink:

Also, I would generate an API connector call to your second endpoint where I would pass the decoded JSON in the body instead of passing it as a parameter

Great, thanks for all the help. I’ll give this a go and see what happens!

Hi @exception-rambler what does that mean?

Thanks,
George

At a v high level, it’s a blended app - ½ Bubble, ½ codebase…
Lots of my app data is stored in JSON packets inside the database and the core computation of the platform happens by taking that data, moving it and parsing it inside custom plugins, running it through the codebase.

This hack of api mappings brings the whole thing together because once you have everything setup, you can work with the JSON packets & codebase output as if it was native Bubble Things. You end up with a best of both approach, although of course you have to structure things in a hack-y Bubble way.

My platform Habitude (a process management / workflow system where anything can be joined to anything in long complex sequences) would be - I think at least - not possible with straight-up Bubble.

5 Likes

Very interesting! Thank you!