Getting the newest line added to a json and sending in discord.py

Question:

I am making a discord bot using discord.py and have a nice little setup so when I add something to my json file it checks every 20 seconds and if something has changed then it will send a discord embed with the new content. Only problem is, instead of sending the newest line it sends every single line (line as in all the content)

Here is the code:

@tasks.loop(seconds=10)
async def update():
    print("Games Update Loop Started")
    last_modified = os.path.getmtime('Game Bot/games.json')
    last_length = 0  # initialize the last length of the JSON file
    while True:
        current_modified = os.path.getmtime('Game Bot/games.json')
        if current_modified != last_modified:
            last_modified = current_modified
            with open('Game Bot/games.json', 'r') as f:
                config_data = json.load(f)
            if len(config_data) > last_length:  # check if new line(s) have been added
                for key, value in config_data.items():
                    embed = discord.Embed(title="New Game Added!", color=0xFFFFFF)
                    embed.add_field(name=key, value=f"[Download]({value})")
                    channel = bot.get_channel(1090051943633780758)
                    await channel.send(embed=embed)
                print("Games updated.")
                last_length = len(config_data)  # update the last length of the JSON file
        await asyncio.sleep(10)

and here is my .json file

{
    "Sons Of The Forest [MULTIPLAYER]" : "https://youtube.com/watch?v=dQw4w9WgXcQ",
    "Geometry Dash [FULL VERSION]" : "https://youtube.com/watch?v=dQw4w9WgX",
    "Rust [MULTIPLAYER]" : "https://youtube.com/watch?v=dQw4w"
}

I tried just about everything I could think of (basically nothing cause im dumb) and expected it to only send the newest line of contents. It sent very lines content.

Asked By: Caden

||

Answers:

Your JSON file seems to be incorrectly formatted, put your data into a list and add keys to make it more easily sortable. Reformat your JSON file to something similar to this.

{
  "videos": [
    {
      "title": "Sons Of The Forest [MULTIPLAYER]", "link": "https://youtube.com/watch?v=dQw4w9WgXcQ"
    },
    { "title": "Geometry Dash [FULL VERSION]", "link":  "https://youtube.com/watch?v=dQw4w9WgX" },
    { "title": "Rust [MULTIPLAYER]", "link":  "https://youtube.com/watch?v=dQw4w" }
  ]

All of the objects are put into a list, this means you can index them and they can be sorted. Before, you needed the key to access an object. This meant that you needed the title of the object if you wanted to return it specifically. For example, you would need the key "Sons Of The Forest [MULTIPLAYER]" to return "https://youtube.com/watch?v=dQw4w9WgXcQ". Otherwise, you would just need to go through every single object to get the one you are looking for, hence your error.

With a list, to get the newest addition, all you need to do is index the last item. With the updated JSON, you can do config_data['videos'] to get the list. Then, you can use your len function on it. To access the newest "line", do config_data['videos][-1]. The -1, accesses the last item in the list.

Once each object is in the list, you can add keys to access values such as the title or the link. This means if you wanted a certain value, you index it from the list, and access the value you want through brackets. So to return the newest lines’s title, you would do config_data['videos'][-1]['title].

All the brackets are a bit confusing so you should put some of them in variables first. Here is some updated code with the logic changed to go along with the JSON.


@tasks.loop(seconds=10)
async def update():
    print("Games Update Loop Started")
    last_modified = os.path.getmtime('Game Bot/games.json')
    last_length = 0
    while True:
        current_modified = os.path.getmtime('Game Bot/games.json')
        if current_modified != last_modified:
            last_modified = current_modified
            with open('Game Bot/games.json', 'r') as f:
                config_data = json.load(f)
                videos = config_data['videos'] # Getting list

            if len(videos) > last_length: 
                    newest_video = videos[-1] # Getting last item in list
                    
                    title = newest_video['title']
                    link = newest_video['link'] # Accessing link of object

                    embed = discord.Embed(
                        title="New Game Added!", color=0xFFFFFF)
                    embed.add_field(name=title, value=f"[Download]({link})")
                    channel = bot.get_channel(1090051943633780758)
                    await channel.send(embed=embed)
                print("Games updated.")
                last_length = len(videos)
        await asyncio.sleep(10)
Answered By: rabbibillclinton

This worked perfectly.

@tasks.loop(seconds=10)
async def update():
    print("Games Update Loop Started")
    last_modified = os.path.getmtime('Game Bot/games.json')
    last_length = 0
    while True:
        current_modified = os.path.getmtime('Game Bot/games.json')
        if current_modified != last_modified:
            last_modified = current_modified
            with open('Game Bot/games.json', 'r') as f:
                config_data = json.load(f)
                videos = config_data['videos'] # Getting list

            if len(videos) > last_length: 
                    newest_video = videos[-1] # Getting last item in list
                    
                    title = newest_video['title']
                    link = newest_video['link'] # Accessing link of object

                    embed = discord.Embed(
                        title="New Game Added!", color=0xFFFFFF)
                    embed.add_field(name=title, value=f"[Download]({link})")
                    channel = bot.get_channel(1090051943633780758)
                    await channel.send(embed=embed)
                print("Games updated.")
                last_length = len(videos)
        await asyncio.sleep(10)
Answered By: Caden
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.