Skip to content

Events Reference

Complete list of events available in StarStreamer, their data structures, and usage examples.

Twitch Events

All Twitch events use EventSub WebSocket for real-time updates.

Chat Events

twitch.chat.message

Fired when a chat message is received.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "viewer123",
        "display_name": "Viewer123"
    },
    "message": "Hello world!",
    "badges": {
        "subscriber": "12",
        "moderator": "1"
    },
    "emotes": [...],
    "timestamp": "2024-01-01T12:00:00Z"
}

Example:

@on_event("twitch.chat.message")
async def handle_chat(event: Event):
    username = event.data['user']['username']
    message = event.data['message']
    print(f"{username}: {message}")


Follow Events

twitch.follow

Fired when someone follows the channel.

Event Data:

{
    "user": {
        "id": "987654321",
        "username": "newfollower",
        "display_name": "NewFollower"
    },
    "followed_at": "2024-01-01T12:00:00Z"
}

Example:

@on_event("twitch.follow")
async def thank_follower(event: Event, twitch: TwitchClient):
    username = event.data['user']['username']
    await twitch.send_message(f"Thanks for following @{username}!")


Subscription Events

twitch.subscription

Fired for new subscriptions.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "subscriber123",
        "display_name": "Subscriber123"
    },
    "tier": "1000",  # 1000, 2000, or 3000
    "is_gift": false,
    "cumulative_months": 1,
    "streak_months": 1,
    "message": "Love the stream!"
}

twitch.subscription.gift

Fired when someone gifts subscriptions.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "gifter123",
        "display_name": "Gifter123"
    },
    "total": 5,
    "tier": "1000",
    "cumulative_total": 25,
    "is_anonymous": false
}

twitch.subscription.message

Fired for resubscription messages.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "subscriber123",
        "display_name": "Subscriber123"
    },
    "tier": "1000",
    "message": "12 months! Love this community!",
    "cumulative_months": 12,
    "streak_months": 12,
    "duration_months": 1
}


Raid Events

twitch.raid

Fired when another channel raids yours.

Event Data:

{
    "from_broadcaster": {
        "id": "123456789",
        "username": "raider123",
        "display_name": "Raider123"
    },
    "viewers": 42
}

Example:

@on_event("twitch.raid")
async def handle_raid(event: Event, twitch: TwitchClient):
    raider = event.data['from_broadcaster']['username']
    viewers = event.data['viewers']
    await twitch.send_message(
        f"Thank you @{raider} for the raid with {viewers} viewers!"
    )


Bits Events

twitch.cheer

Fired when someone cheers with bits.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "cheerer123",
        "display_name": "Cheerer123"
    },
    "bits": 100,
    "message": "cheer100 Great stream!",
    "is_anonymous": false
}


Channel Points Events

twitch.channel_points_redemption

Fired when channel points are redeemed.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "redeemer123",
        "display_name": "Redeemer123"
    },
    "reward": {
        "id": "reward123",
        "title": "Hydrate!",
        "cost": 500
    },
    "user_input": "Optional user text",
    "redeemed_at": "2024-01-01T12:00:00Z"
}


Moderation Events

twitch.ban

User banned from channel.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "banneduser",
        "display_name": "BannedUser"
    },
    "moderator": {
        "id": "987654321",
        "username": "moderator123",
        "display_name": "Moderator123"
    },
    "reason": "Spam",
    "is_permanent": true,
    "ends_at": null
}

twitch.timeout

User timed out.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "timedoutuser",
        "display_name": "TimedOutUser"
    },
    "moderator": {
        "id": "987654321",
        "username": "moderator123",
        "display_name": "Moderator123"
    },
    "reason": "Caps spam",
    "duration": 600,  # seconds
    "ends_at": "2024-01-01T12:10:00Z"
}

twitch.unban

User unbanned.

Event Data:

{
    "user": {
        "id": "123456789",
        "username": "unbanneduser",
        "display_name": "UnbannedUser"
    },
    "moderator": {
        "id": "987654321",
        "username": "moderator123",
        "display_name": "Moderator123"
    }
}


Stream Events

twitch.stream.online

Stream goes live.

Event Data:

{
    "id": "stream123",
    "broadcaster": {
        "id": "123456789",
        "username": "streamer123",
        "display_name": "Streamer123"
    },
    "type": "live",
    "started_at": "2024-01-01T12:00:00Z"
}

twitch.stream.offline

Stream ends.

Event Data:

{
    "broadcaster": {
        "id": "123456789",
        "username": "streamer123",
        "display_name": "Streamer123"
    }
}

twitch.channel.update

Channel information updated.

Event Data:

{
    "broadcaster": {
        "id": "123456789",
        "username": "streamer123",
        "display_name": "Streamer123"
    },
    "title": "New stream title!",
    "language": "en",
    "category_id": "509658",
    "category_name": "Just Chatting",
    "is_mature": false
}


OBS Events

OBS events come through the OBS WebSocket API.

Scene Events

obs.scene_changed

Active scene changed.

Event Data:

{
    "scene_name": "Gaming",
    "previous_scene": "Starting Soon"
}

obs.scene_list_changed

Scene list modified.

Event Data:

{
    "scenes": ["Starting Soon", "Gaming", "BRB", "Ending"]
}


Stream Control Events

obs.stream_started

Streaming started.

Event Data:

{
    "output_active": true,
    "output_state": "OBS_WEBSOCKET_OUTPUT_STARTED",
    "output_timecode": "00:00:00.000"
}

obs.stream_stopped

Streaming stopped.

Event Data:

{
    "output_active": false,
    "output_state": "OBS_WEBSOCKET_OUTPUT_STOPPED",
    "output_timecode": "02:34:56.789"
}


Recording Events

obs.recording_started

Recording started.

Event Data:

{
    "output_active": true,
    "output_path": "/recordings/2024-01-01.mp4",
    "output_state": "OBS_WEBSOCKET_OUTPUT_STARTED"
}

obs.recording_stopped

Recording stopped.

Event Data:

{
    "output_active": false,
    "output_path": "/recordings/2024-01-01.mp4",
    "output_duration": 9876543  # milliseconds
}


Source Events

obs.source_visibility_changed

Source visibility toggled.

Event Data:

{
    "scene_name": "Gaming",
    "source_name": "Webcam",
    "visible": true
}

obs.source_mute_state_changed

Audio source muted/unmuted.

Event Data:

{
    "source_name": "Microphone",
    "muted": false
}


Custom Events

You can emit custom events for internal communication.

Creating Custom Events

from starstreamer.core.event_bus import get_event_bus

bus = get_event_bus()

# Emit custom event
await bus.emit("custom.alert", {
    "type": "celebration",
    "message": "100 followers reached!",
    "priority": "high"
})

Handling Custom Events

@on_event("custom.alert")
async def handle_alert(event: Event):
    alert_type = event.data['type']
    message = event.data['message']
    print(f"Alert ({alert_type}): {message}")

Common Custom Event Patterns

custom.timer_expired

Timer completion events.

{
    "timer_id": "hydrate_reminder",
    "duration": 1800,  # seconds
    "message": "Time to hydrate!"
}

custom.queue_update

Queue state changes.

{
    "queue_type": "song_requests",
    "action": "added",
    "item": {
        "id": "song123",
        "title": "Never Gonna Give You Up",
        "requested_by": "viewer123"
    },
    "position": 5
}

custom.goal_progress

Goal tracking updates.

{
    "goal_type": "follower",
    "current": 95,
    "target": 100,
    "percentage": 95.0
}

Event Patterns

Wildcard Subscriptions

# All Twitch events
@on_event("twitch.*")

# All chat-related events
@on_event("*.chat.*")

# All subscription events
@on_event("twitch.subscription*")

# Everything
@on_event("**")

Event Filtering

from starstreamer import filter

# Only process mod messages
@on_event("twitch.chat.message")
@filter(lambda e: 'moderator' in e.data.get('badges', {}))
async def mod_only_handler(event: Event):
    pass

# Only raids with 10+ viewers
@on_event("twitch.raid")
@filter(lambda e: e.data['viewers'] >= 10)
async def big_raids_only(event: Event):
    pass

Event Chaining

@on_event("twitch.follow")
async def follow_chain(event: Event):
    bus = get_event_bus()

    # Trigger celebration
    await bus.emit("custom.celebration", {
        "type": "follow",
        "user": event.data['user']['username']
    })

    # Update goal
    await bus.emit("custom.goal_progress", {
        "goal_type": "follower",
        "increment": 1
    })

Testing Events

Emit Test Events

from starstreamer.core.event_bus import get_event_bus

async def test_events():
    bus = get_event_bus()

    # Test chat message
    await bus.emit("twitch.chat.message", {
        "user": {"username": "testuser"},
        "message": "!test command"
    })

    # Test follow
    await bus.emit("twitch.follow", {
        "user": {"username": "newfollower"},
        "followed_at": "2024-01-01T12:00:00Z"
    })

Mock Events in Tests

import pytest
from unittest.mock import MagicMock

def create_mock_event(event_type, data):
    """Create a mock event for testing"""
    event = MagicMock()
    event.type = event_type
    event.data = data
    event.timestamp = 1234567890.0
    event.source = "test"
    return event

@pytest.mark.asyncio
async def test_handler():
    event = create_mock_event("twitch.chat.message", {
        "user": {"username": "testuser"},
        "message": "Hello world"
    })

    await my_handler(event)
    # Assert handler behavior

See Also