A Better Quoting System [Live Coding Recap]

πŸ’Ύ bun9000 - Oct 27 '19 - - Dev Community

Streamed: 10/27 on Twitch

Topic(s): We created a persistent data system for the Twitch Bot
Language: Python, JSON
Tech & libs used: VSCode, TwitchIO

πŸ‘‡ You can find the code we wrote on stream down below! :D

⭐ Star β‡’ Project Repository
πŸ’œ Follow β‡’ on Twitch and GitHub
πŸ”΄ Watch β‡’ Twitch VOD (replay)

During the stream we...

βœ” unboxed the a hat from DEV!! Ty!!
βœ” changed voice on tts to Brian
βœ” moved !project command to DeepThonk
βœ” get !quoth partially working
βœ” handled a case of key-errors
βœ” tested out the fixes - it works!
βœ” worked on vscode for the next live coding article for a bit
βœ” ended the night playing video games w/community

Making the quote system

We made a command called !quoth that takes a user name as an argument and saves the last thing that user said as a quote.

BestCoderNA: I'm not totally useless. I can be used as a bad example!
F1SavesLives: !quoth @BestCoderNA
QUOTE SAVED: "I'm not totally useless. I can be used as a bad example!" - @BestCoderNA

Here's the entry point to the quoth feature. It's an async command registered in the bot's event loop. You invoke it by sending !quoth in chat.

# commands.py
@bot.command(name="quoth")
async def quoth(ctx):
    'the raven, nevermore. nevermore.'
    token = ctx.content.split(' ', 1)  # tokenizeβ„’
    author = token[1].lower()  # match case for msg database keys
    if author[0] == '@':  # strip the @ if tagged
        author = author[1:]
    data.quoth(author)
Enter fullscreen mode Exit fullscreen mode

Every message sent in chat is added to a dictionary with a key of the user name.

# called in event_message():
def save_last_message(self, author, msg):
    if msg[0] == '!':  # ignore commands
        return
    if msg[0] == '@': # strip tags if tagged
        author = author[1:]
    self.last_message[author] = msg
    log.debug(f"saved: {author} - {self.last_message[author]}")
Enter fullscreen mode Exit fullscreen mode

In our data object, which is our JSON "database" interface, we use the quoth method to append the python quote to a list of quotes.

# in the `data` object, an instance of DataInterface
def quoth(self, author):
    'take in an author name and add the last thing said from them'

    try:  # check if they've even said anything yet
        incoming_quote = {
            "author" : author,
            "quote" : self.last_message[author]
        }
    except KeyError:
        log.debug(f"{author} hasn't said anything yet...")

    # pull the json data to an object
    with open('quotes.json') as json_file:
        data = json.load(json_file)
        quotes = list()
        for quote in data:
            quotes.append(quote) # add all the quotes from json to a list
        quotes.append(incoming_quote) # add the new quote to the end of the list
        log.debug(f"QUOTE SAVED! {incoming_quote}")

    # rewrite with the new quote
    with open('quotes.json', 'w+') as json_file:
        json.dump(quotes, json_file, indent=4)  # dump it back in to jso
Enter fullscreen mode Exit fullscreen mode

And here's the JSON "database" after we tested it out with a few quotes!

[
    {
        "author": "Jigokuniku",
        "quote": "TBH, some best practices are really only ever learned by getting annoyed at the bad practice"
    },
    {
        "author": "NinjaBunny9000",
        "quote": "JUST πŸ‘ BECAUSE πŸ‘ IT'S πŸ‘ EATABLE πŸ‘ DOESN'T πŸ‘ MEAN πŸ‘ IT'S πŸ‘ EDIBLE πŸ‘"
    },
    {
        "author": "J0nnyclueless",
        "quote": "I sometimes get kernel panic attacks"
    },
    {
        "author": "Sockelo",
        "quote": "Forgive them, for they know not what they compile."
    }
]
Enter fullscreen mode Exit fullscreen mode
. . . . . . . . . . . . . . . . . .
Terabox Video Player