How to create a persistent counter for Twitch bot commands in Python

I’m building a Twitch bot feature that tracks how many times a streamer dies in games. When viewers type !deathCount I want it to increment by one each time the command is used.

Right now my code just does basic math instead of actually saving the count between commands. Every time someone uses the command it resets back to zero.

def handle_death_command():
    total_deaths = 0
    increment_value = 1
    result = int(total_deaths) + int(increment_value)
    print('Adding {0} to current count of {1} equals {2}'.format(increment_value, total_deaths, result))
    send_chat_message(CHANNEL, 'Death count updated successfully!')

The problem is obvious - I’m setting total_deaths = 0 every single time. I need the counter to remember the previous value and keep adding to it. What’s the best way to make this persistent?

Just use a pickle file to save your counter data. I’ve done this for several Twitch bots and it works great without needing extra dependencies.

import pickle
import os

def handle_death_command():
    counter_file = 'death_count.pkl'
    
    if os.path.exists(counter_file):
        with open(counter_file, 'rb') as f:
            total_deaths = pickle.load(f)
    else:
        total_deaths = 0
    
    total_deaths += 1
    
    with open(counter_file, 'wb') as f:
        pickle.dump(total_deaths, f)
    
    send_chat_message(CHANNEL, f'Deaths: {total_deaths}')

Pickle does all the work for you and creates the file automatically. Your counter survives bot restarts and keeps working. You’ll want to add error handling for file access in production, but this setup works perfectly for persistent counters without database complexity.

Honestly, just use a global variable if your bot stays running. Way simpler than dealing with files. Declare death_counter = 0 outside the function, then use global death_counter inside when you need to modify it. Only downside is losing the count if the bot crashes, but that’s usually not a big deal for most streams.

The Problem:

You’re trying to build a Twitch bot that tracks a streamer’s death count using a persistent counter. Your current code resets the count to zero every time the !deathCount command is used because the counter variable is declared and initialized inside the function. You need a way to store the death count persistently so it increments correctly across multiple command invocations.

:thinking: Understanding the “Why” (The Root Cause):

The issue lies in the scope of your total_deaths variable. Because you declare total_deaths = 0 inside the handle_death_command function, it’s created and destroyed each time the function is called. This means the counter always starts from zero. To make the counter persistent, you need to store it outside the function’s scope, ideally in a way that survives restarts of your bot. Using a simple file, or a database (like SQLite) is the most straightforward solution for this.

:gear: Step-by-Step Guide:

  1. Use SQLite to store the death count: This approach offers better reliability and scalability than simple text files, especially if multiple users might execute the command simultaneously. SQLite is a lightweight, file-based database that’s readily available in Python.

    First, ensure you have the sqlite3 library installed. It’s usually included with Python, but you can check using: pip show sqlite3.

    Then, modify your code as follows:

    import sqlite3
    
    def handle_death_command():
        conn = sqlite3.connect('bot_data.db')  # Connect to the database (creates it if it doesn't exist)
        cursor = conn.cursor()
    
        # Create the table if it doesn't exist
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS death_counts (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                count INTEGER
            )
        ''')
    
        # Get the current count. If there is no entry, it defaults to 0.
        cursor.execute("SELECT count FROM death_counts ORDER BY id DESC LIMIT 1")
        result = cursor.fetchone()
        if result:
            current_count = result[0]
        else:
            current_count = 0
    
        # Increment the count
        new_count = current_count + 1
        cursor.execute("INSERT INTO death_counts (count) VALUES (?)", (new_count,))
    
        # Commit changes and close the connection
        conn.commit()
        conn.close()
    
        send_chat_message(CHANNEL, f'Death count: {new_count}')
    
  2. Verify Database Setup: After running this code, a file named bot_data.db will be created in the same directory as your script. Check to make sure the file exists and has the correct structure. You can verify this by opening the .db file with a database browser (many free tools are available online).

  3. Error Handling (Optional but Recommended): For a production-ready bot, wrap your database interactions in try...except blocks to handle potential errors, like database connection failures:

    try:
        conn = sqlite3.connect('bot_data.db')
        # ... your database code ...
    except sqlite3.Error as e:
        print(f"An error occurred: {e}")
        send_chat_message(CHANNEL, "Error updating death count. Please try again later.")
    finally:
        if conn:
            conn.close()
    

:mag: Common Pitfalls & What to Check Next:

  • Database Path: Ensure that your bot has the necessary permissions to create and write to the bot_data.db file. If you’re running this from a restricted environment, you may need to adjust the file path accordingly.
  • Concurrent Access: While SQLite handles concurrent access reasonably well, for high-traffic streams, consider using a more robust database solution (like PostgreSQL or MySQL) designed for concurrent operations.
  • Data Backup: Implement a regular backup strategy for your database to prevent data loss.

:speech_balloon: Still running into issues? Share your (sanitized) config files, the exact command you ran, and any other relevant details. The community is here to help!

Skip the files and databases - you can automate the whole thing without writing any storage code.

I do this for stream event counters constantly. Let automation handle data persistence while you focus on bot logic.

Set up a webhook that receives death count commands. Create an automation flow that keeps a running counter in memory or simple storage. Bot needs to increment? Hit the webhook, counter updates automatically, you get the new value back.

Keeps your Python code clean:

def handle_death_command():
    response = requests.post('your-webhook-endpoint')
    new_count = response.json()['count']
    send_chat_message(CHANNEL, f'Death count: {new_count}')

Automation handles incrementing, storing, and returning the count. No file handling, no database setup, no persistence headaches.

You can build this stateful automation workflow in minutes instead of writing storage code from scratch.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.