Need help parsing JSON

Hi, I’m trying to call an API that generates stories, and it returns a big chunk of text in a JSON file. So far I’ve managed to get that contents of the JSON logged through the script attached in the screenshot below. This is what I get when I call the script:

{“story_request”:{“language”:“English”,“characters”:“frank,carla,and tim”,“antagonist”:“sean”,“contagonist”:“sofia”,“model”:“gpt-3.5-turbo-16k-0613”,“preamble_key”:“193a31cfac98094dee8412b5d948d377c7c87a03”,“prompt_template_key”:0.2,“temperature”:“28640f0a62bc8af8ed66d33211346ab970f04f89”},“content_id”:“cc6e8c3144cd0d6f1625f56dd528a36895f5b8e9”,“story”:“Once upon a time, in the beautiful country of Ecuador, Frank, Carla, and Tim were on a family adventure in their trusty van. They were driving through the lush rainforests of the Amazon when suddenly, the videophone rang. It was Grandpa, calling to announce that they were going on an exciting adventure!\n\n"Hey there, my little adventurers! I have a game for you," Grandpa said with a mischievous smile. "I’ll give you clues, and you have to guess our destination."\n\n"I love games! Let’s do it!" Tim exclaimed, bouncing up and down in his seat.\n\n"Alright, here’s the first clue," Grandpa said. "Our destination is known for its stunning mountains and colorful markets."\n\nCarla thought for a moment and then shouted, "I know! We’re going to Quito!"\n\n"Correct, Carla! We’re teleporting to Quito right now!" Grandpa exclaimed, and in an instant, the van was surrounded by the bustling streets of the capital city.\n\nAs they explored the vibrant city, the family stumbled upon a problem. A factory nearby was releasing thick smoke into the air, polluting the environment.\n\n"Oh no, this pollution is terrible!" Frank exclaimed, covering his nose.\n\nSacha, always eager to take charge, said, "We can’t just ignore this. We have to do something!"\n\n"But what can we do?" Oscar asked, scratching his head.\n\nSacha thought for a moment and then said, "I have an idea! Let’s gather all the people in the market and have a peaceful protest against the factory."\n\nExcitedly, the family set off to gather people and spread the word about the protest. But just as they were about to start, a sudden rainstorm poured down, scattering everyone.\n\n"Oh no, our plan is ruined!" Carla exclaimed, her face falling.\n\nBut Sacha, never one to give up, said, "Don’t worry, we can adapt our plan. Let’s find a sheltered area and continue our protest there."\n\nAs they regrouped and found a covered area, they were suddenly surprised by the appearance of Sofia, a local environmental activist.\n\n"I heard about your protest and I want to help," Sofia said, determination shining in her eyes.\n\nWith Sofia’s help, the family revised their plan. They decided to create a giant mural depicting the beauty of nature and the importance of protecting it.\n\nTogether, they worked tirelessly, painting and spreading their message. And finally, the mural was complete, capturing the attention of everyone who passed by.\n\nAs the crowd gathered around, Sofia stepped forward and said, "We must work together to protect our environment. Let’s make a promise to take care of our planet."\n\nThe crowd cheered, and the family felt a sense of triumph. They had made a difference in their own small way.\n\nJust then, Grandpa appeared on the videophone, cheering them on. "Well done, my little adventurers! You’ve shown the world the power of unity and determination."\n\nBut as the family celebrated, Grandpa revealed a surprising twist. "You know, I was the one causing the pollution in the factory. It was all part of my plan to teach you about the importance of standing up for the environment."\n\nThe family gasped in disbelief, but then burst into laughter. They realized that even though Grandpa had played the role of the antagonist, his intentions were for their own growth and understanding.\n\nAnd so, with their hearts full of love and a newfound appreciation for the environment, the family continued their adventures, ready to face any challenge that came their way.”,“title”:“Untitled”,“timestamp”:“2023-07-22T18:13:48.406349+00:00”}

How would I go about getting just the story text and making it readable? I’ve followed a bunch of tutorials on YouTube and they all end up with this chunk at the end even after I try parsing it the way they did.
Thank you!

You wouldn’t. Instead you would reverse engineer the json file into a c# class (can do this with online tools), and then you would deserialize the file and it spits out an instance of that class. Then you can fetch the text from that class instance.

Convert JSON to C# Classes Online - Json2CSharp Toolkit

    public class Root
    {
        public StoryRequest story_request { get; set; }
        public string content_id { get; set; }
        public string story { get; set; }
        public string title { get; set; }
        public DateTime timestamp { get; set; }
    }

    public class StoryRequest
    {
        public string language { get; set; }
        public string characters { get; set; }
        public string antagonist { get; set; }
        public string contagonist { get; set; }
        public string model { get; set; }
        public string preamble_key { get; set; }
        public double prompt_template_key { get; set; }
        public string temperature { get; set; }
    }

How would I go about doing that if the JSON file isn’t saved on my computer, but a new one is made by the API every time? Is there a good YouTube tutorial for this?

Not sure at what advanced stage you are now. But if you have a JSON string you only need to deserialize it for example with that Unity - Manual: JSON Serialization and from the serialized class you get the text you want to print.

You can use ofc another library to serialize JSON. The above has some limitations like multi-dimension arrays but it’s quite fast.

I tried what you said, but I keep getting Null or errors instead of the chunk of text I want. I’ve got a class called APIResponseJSONVariables that contains everything returned by the API in JSON format, but whenever I log myObject.story (myObject being equal to JsonUtility.FromJson(json), and story being the part of the json file containing the story). Is there something I’m missing?



using System;

[Serializable]
public class StoryData
{
    public string content_id;
    public string story;
    public StoryRequestData story_request;
    public DateTime timestamp;
    public string title;
}

[Serializable]
public class StoryRequestData
{
    public string antagonist;
    public string characters;
    public string contagonist;
    public string language;
    public string model;
    public string preamble_key;
    public float prompt_template_key;
    public string temperature;
}

Above structures should handle your JSON. The problem can be also using Coroutine because this function runs independently so when you StartCoroutine program go on to the next tasks and when you hit deserialization the JSON could be not ready yet (not loaded from URL). Use deserialization when you already get full JSON text.

Where would I put this code? Should that replace what’s inside the APIResponseJSONVariables script?

Yes. You have a struct inside you’re JSON so you need a separate serializable class to handle it. Usage will be like that below.

Alright, now that I’ve changed that do I set the APIResponseJSONVariables stuff from before to StoryRequestData or StoryData?

9164750--1275323--Screenshot 2023-07-22 at 2.44.49 PM.png

StoryData storyData = JsonUtility.FromJson<StoryData>(json);

I updated it again, I turned the part you didn’t mention into a comment, I assume I’m supposed to delete it, right? When I ran the code in unity it gave me an error saying that the log call was asking for something that didn’t exist, did I do something wrong or is it the fact it’s still in the coroutine?

Try to move the deserialization.

json = request.downloadHandler.text;
StoryData storyData = JsonUtility.FromJson<StoryData>(json);
Debug.Log(storyData.story);

When you set you’re deserialization in Start it fires before URL end reading for sure.

storyData.story is still undefined

9164816--1275341--Screenshot 2023-07-22 at 3.02.58 PM.png

Not into Start, it must be inside GetDatas in the else part. In Start leave only StartCoroutine you had earlier.

It worked! Thank you so much for helping!

Great! This can be helpful if you want to understand why you had to do it that way.

Is there a quick way I can call on the string characters from my readInput script in my APIRetry script? Or do I need to make a class and have the readInput script save the characters there and the APIRetry script pull the character data from there?

9164891--1275356--Screenshot 2023-07-22 at 3.29.50 PM.png
9164891--1275359--Screenshot 2023-07-22 at 3.29.42 PM.png

You must start with something simple. I see you don’t see the difference between class and object. Class is only a blueprint and object is copy filled with data for example. You can have many copies with different data. So you ask about data objects, not class (like you have done it).

Ok, yeah classes and objects haven’t come up for me until now. So how would I access that variable from a different script?

Depending on the engineering approach you set. You can create a class Connection that handles connections (don’t has to be MonoBehaviour). Now when you need to download something for example in a class Storyteller (this can be MonoBehaviour) you create inside an object Connection connection and you can access its public methods and values by return, or its member values.