https://github.com/hslarson/faster-twitch-alerts
Faster Twitch Alerts is a highly customizable, lightning-fast alternative to Twitch's slow mobile notification system
https://github.com/hslarson/faster-twitch-alerts
discord pushover python python3 twitch twitch-api
Last synced: 4 months ago
JSON representation
Faster Twitch Alerts is a highly customizable, lightning-fast alternative to Twitch's slow mobile notification system
- Host: GitHub
- URL: https://github.com/hslarson/faster-twitch-alerts
- Owner: hslarson
- License: gpl-3.0
- Created: 2021-12-27T09:37:31.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-06-06T07:35:45.000Z (about 2 years ago)
- Last Synced: 2025-10-14T02:33:02.885Z (8 months ago)
- Topics: discord, pushover, python, python3, twitch, twitch-api
- Language: Python
- Homepage:
- Size: 131 KB
- Stars: 8
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# __Faster Twitch Alerts__
## __What is "Faster Twitch Alerts"?__
Faster Twitch Alerts is a highly customizable, lightning-fast alternative to Twitch's slow mobile notification system. Faster Twitch Alerts currently supports two notification platforms: Discord and Pushover. You can also [build your own plugins](#making-your-own-plugins).
The program can notify you when:
- A streamer goes live
- A streamer goes offline
- A streamer gets banned
- A streamer is unbanned
- A streamer updates their title and/or game
Disclaimer: This program is not associated in any way with Twitch, Discord, or Pushover
## __Getting Started__
1. Clone the repository
2. Install Python (≥3.7) and the aiohttp Library
3. Set your notification preferences in the [config.json File](#config-fields-explained)
4. Run Main.py
- If the program terminates unexpectedly, check the log file for more information
- You can terminate the program at any time using 'ctrl+c'
## __Config Fields Explained__
### Primary Fields
For more detailed explanations of each field, follow the links
| Field Name | Required? |
|-----------------------------------------|-----------|
| [Twitch Settings](#twitch-settings) | Yes |
| [Logger Settings](#logger-settings) | Yes |
| [Streamers](#streamers) | Yes |
| [Discord Settings](#discord-settings) | No |
| [Pushover Settings](#pushover-settings) | No |
### Twitch Settings
This is where we store overall program settings and settings related to the Twitch API
#### __Example Twitch Settings Object:__
```
"Twitch Settings" : {
"Client ID" : "YOUR CLIENT ID",
"Secret" : "YOUR SECRET",
"Reconnect Attempts" : 10,
"Reconnect Cooldown" : 60,
"Refresh Rate" : 1
}
```
#### __Twitch Settings Fields:__
| Field Name | Description | Required? | Datatypes | [Alert-Specific Settings](#alert-specific-settings) | [Special Formatting](#special-formatting) |
| - | - | - | - | - | - |
| Client ID | Your Twitch developer application client ID 1 | Yes | str | Not Allowed | Not Allowed |
| Secret | Your Twitch developer application client secret 1 | Yes | str | Not Allowed | Not Allowed |
| Reconnect Attempts | The number of times the program will attempt to reconnect to the network during an outage 2 | Yes | int | Not Allowed | Not Allowed |
| Reconnect Cooldown | The amount of time (in seconds) that the program will wait before trying to reconnect to the network after a connection failure |Yes | int, float | Not Allowed | Not Allowed |
| Refresh Rate3 | The number of times per second to pull new data from the Twitch API | Yes | int, float | Not Allowed | Not Allowed |
__Footnotes:__
- 1 [Setting Up a Twitch Developer Application](https://dev.twitch.tv/docs/api/)
- 2 Negative values signal infinite reconnect attempts
- 3 There is a hard cap on the refresh rate imposed by Twitch API rate limits. You can calculate the refresh rate using the following formula: 20 / (3 * ceil( [# of streamers] / 100 ))
### Logger Settings
Settings related to the log file
#### __Example Logger Settings Object:__
```
"Logger Settings" : {
"Log Level" : "INFO",
"Log Filepath" : "logs/twitch_alerts.log",
"Message Text" : "ALERT!"
}
```
#### __Logger Settings Fields:__
| Field Name | Description | Required? | Datatypes | [Alert-Specific Settings](#alert-specific-settings) | [Special Formatting](#special-formatting) |
| - | - | - | - | - | - |
| Log Level | Allows users to define which messages they receive 1 | Yes | str | Not Allowed | Not Allowed |
| Log Filepath | The path (relative to current working directory) of the log file | Yes | str | Not Allowed | Not Allowed |
| Message Text | Text to display when an [alert](#alert-types) is triggered | No 2 | str | Allowed | Allowed |
__Footnotes:__
- 1 More Info on Log Levels:
- DEBUG: Shows minor network errors
- ALERT: Info about streamer activity
- INFO: General program info
- WARNING: Info about non-fatal errors
- ERROR: Info about fatal errors
- 2 A warning will be displayed if field is incomplete and log level is either DEBUG or ALERT
### Streamers
The JSON object containing settings for all of the streamers we wish to monitor
#### __Example Streamers Object__:
```
"Streamers" : {
"streamer-username-1" : {
"Ban Status" : false,
"User ID" : "123456789"
},
"streamer-username-2" : {
"Ban Status" : true,
"User ID" : "987654321"
}
}
```
#### __Streamer Object Fields:__
| Field Name | Description | Required? | Datatypes | [Alert-Specific Settings](#alert-specific-settings) | [Special Formatting](#special-formatting) |
| - | - | - | - | - | - |
| Ban Status | A Boolean flag used to signal if a streamer is banned 1 | Yes | bool | Not Allowed | Not Allowed |
| User ID | A streamer's unique identification number (provided by Twitch) 1 | Yes | str | Not Allowed | Not Allowed |
| Discord Settings | Streamer-Specific Discord Settings. For possible fields see [Discord Settings](#discord-settings) 2 | No | dict | N/A | N/A |
| Pushover Settings | Streamer-Specific Pushover Settings. For possible fields see [Pushover Settings](#pushover-settings) 2 | No | dict | N/A | N/A |
__Footnotes:__
- 1 A streamer's user ID can only be viewed using API calls, it is recommended that you use the set_config.py program in Utils/ to generate the "Streamers" field
- 2 The "Soon Cooldown" field can only exist in global settings
#### __Sidenote: Global vs. Streamer-Specific Settings__
We refer to Discord/Pushover settings within the streamer object as "streamer-specific settings." These settings take precedence over "global settings" in either [Discord Settings](#discord-settings) or [Pushover settings](#pushover-settings). In this way, we can create global settings that will apply to all streamers, and also make fine-grain adjustments to individual streamers' settings.
### Discord Settings
Global settings for Discord alerts
#### __Example Discord Settings Object:__
```
"Discord Settings" : {
"Soon Cooldown" : 300,
"Alerts" : "all",
"Webhook URL" : "SOME WEBHOOK URL",
"Bot Username" : "Faster Twitch Alerts",
"Avatar URL" : "Link to Avatar Image",
"Discord ID" : "Some Discord ID",
"Embeds" : [
{
"title" : "Some Title",
"description" : "Some Description"
}
],
"Message Text" : "DISCORD ALERT!"
}
```
#### __Example Discord Settings Fields:__
| Field Name | Description | Required? | Datatypes | [Alert-Specific Settings](#alert-specific-settings) | [Special Formatting](#special-formatting) |
| - | - | - | - | - | - |
| Soon Cooldown | Controls how often changes to an individual streamer's title or game will generate an alert by setting a cooldown period (units = seconds) | No | int, float | Not Allowed | Not Allowed |
| [Alerts](#alerts-field) | Controls what types of messages will generate an alert | No | str | Allowed | Not Allowed |
| Webhook URL | The Webhook URL for the Discord channel which will receive the alert | No1 | str | Allowed | Allowed |
| Bot Username | The display name of the bot that will be the sender of the alert | No | str | Allowed | Allowed |
| Avatar URL | A direct link to an image that will be the Discord bot's avatar | No | str | Allowed | Allowed |
| Discord ID2 | A Discord role/user ID that can be used to tag members of a Discord server. See below for examples | No | str | Allowed | Allowed |
| Embeds | An list of up to 10 Discord embed objects3 | No | list | Allowed | Allowed |
| Message Text | Text to display when an [alert](#alert-types) is triggered | No1 | str | Allowed | Allowed |
__Footnotes:__
- 1 These fields must be defined for all active alert types in either global settings or streamer-specific settings otherwise the program will terminate
- 2 You can find user/role ID's by activating "Developer Mode" on Discord
- 3 [Discord Embed Documentation](https://discord.com/developers/docs/resources/channel#embed-object)
__Discord Message Tips:__
Mentions:
```
Everyone, Here: @everyone, @here
Users: "<@discord_user_id>"
Roles: "<@&discord_role_id>"
```
Using a Custom Server Emoji:
```
Normal: "<:emoji_alias:emoji_id>"
Animated: ""
```
### Pushover Settings
Global settings for Pushover alerts
#### __Example Pushover Settings Object:__
```
"Pushover Settings" : {
"Soon Cooldown" : 300,
"Alerts" : "all",
"API Token" : "YOUR API TOKEN",
"Group Key" : "YOUR GROUP KEY",
"Devices" : "Some Devices",
"Priority" : 1,
"Embed URL" : "https://www.twitch.tv/{name.lower()}",
"URL Title" : "Go To Stream",
"Sound" : "Some Sound",
"Message Title" : "Faster Twitch Alerts",
"Message Text" : {
"live" : "{name} is Live Right Now! \ud83d\udce1",
"title" : "{name} Might Be Going Live Soon! \u231b",
"game" : "{name} Might Be Going Live Soon! \u231b",
"offline" : "{name} Just Went Offline \ud83d\ude14",
"ban" : "{name} Just Got Banned \u2696\ufe0f",
"unban" : "{name} has Been Unbanned! \ud83c\udf89"
}
}
```
#### __Example Pushover Settings Fields:__
| Field Name | Description | Required? | Datatypes | [Alert-Specific Settings](#alert-specific-settings) | [Special Formatting](#special-formatting) |
| - | - | - | - | - | - |
| Soon Cooldown | Controls how often changes to an individual streamer's title or game will generate an alert by setting a cooldown period (units = seconds) | No | int, float | Not Allowed | Not Allowed |
| [Alerts](#alerts-field) | Controls what types of messages will generate an alert | No | str | Allowed | Not Allowed |
| API Token1 | Pushover API token | No2 | str | Allowed | Allowed |
| Group Key1 | Pushover User or Group Key | No2 | str | Allowed | Allowed |
| Devices1 | Comma-separated list of device names to send the alert to | No | str | Allowed | Allowed |
| Priority1 | Integer from -2 to 2 that specifies how important the alert is | No | int | Allowed | Not Allowed |
| Embed URL1 | Supplementary URL for the alert | No | str | Allowed | Allowed |
| URL Title1 | The text to display for the "Embed URL" | No | str | Allowed | Allowed |
| Sound1 | The name of the sound to play for the alert | No | str | Allowed | Allowed |
| Message Title1 | The title of the alert | No | str | Allowed | Allowed |
| Message Text | Text to display when an [alert](#alert-types) is triggered | No2 | str | Allowed | Allowed |
__Footnotes:__
- 1 [More information about Pushover alert fields](https://pushover.net/api)
- 2 These fields must be defined for all active alert types in either global settings or streamer-specific settings otherwise the program will terminate
## Alert-Specific Settings
For certain fields, we may want to change our preferences based on the [type of alert](#alert-types) being triggered. This is fairly easy to do, we can simply create a JSON object of [alert-type keywords](#alert-types) and specify different parameters for each keyword.
#### __Alert-Specific Settings Example:__
Without Alert-Specific Settings:
```
"Message Text" : "Some Alert Message"
```
With Alert-Specific Settings:
```
"Message Text" : {
"live" : "Some 'Live' Message",
"offline" : "Some 'Offline' Message",
"ban" : "Some 'Ban' Message",
"unban" : "Some 'Unban' Message",
"title" : "Some 'Title Change' Message",
"game" : "Some 'Game Change' Message"
}
```
### __Alert Types__
Faster Twitch Alerts can send alerts for many types of events. Below are the keywords describing each alert type
| Alert Type | Description |
| - | - |
| live | The streamer went live |
| offline | The streamer went offline |
| ban | The streamer was banned |
| unban | The streamer's ban ended |
| title | The streamer updated their stream's title (while offline) |
| game | The streamer switched categories (while offline) |
### __Keyword Mapping__
For the sake of efficiency, we've provided additional keywords that specify multiple alert fields. Below you can see the keywords and which alert types they map to.
| Alert Type | Description |
| - | - |
| all | live, offline, ban, unban, title, game |
| none1 | |
| bans | ban, unban |
| soon | title, game |
__Footnotes:__
- 1 Only valid for the ["Alerts" field](#alerts-field)
### __Alerts Field__
The Alerts field is used to toggle certain alert types on and off.
__Valid "Alerts" Formats:__
Boolean Keyword Dictionary:
```
"Alerts" : {
"live" : true
"offline" : true,
"ban" : true,
"unban" : true,
"title" : true,
"game" : true
}
```
Comma-Separated Keywords in String Format:
```
"Alerts" : "live, offline, ban, unban, title, game"
```
__Negation Operator:__
'!' Can be used in front of a keyword to negate that keyword
Note that keywords are parsed in order, for example
- "all, !live" -> Alerts for everything except "live"
- "!live, all" -> Alerts for everything, even "live"
## Special Formatting
Sometimes we want more customization beyond what a normal string can offer. For this reason, we've created a special formatting system for certain fields.
__Here's how it works:__
Every statement in curly braces will be evaluated by the formatter. The formatter understands Python and expects a string to be returned by whatever is contained in the braces.
There are a few local variables we can use as well:
| Variable | Datatype | Description |
| - | - | - |
| time | struct_time | Evaluates to time.localtime() |
| name | str | The username of the streamer |
| title | str | The streamer's current stream title |
| game | str | The streamer's current game category |
| message | str | The [alert type](#alert-types) of the message |
| discord_id | str | The user-specified Discord ID for the message |
Due to the way Python interprets strings, we may need alternate ways to specify escape characters. Below are the currently available alternatives:
| Variable | Datatype | Description |
| - | - | - |
| nl | str | newline |
| tb | str | tab |
| dq | str | double quote |
| sq | str | single quote |
__Examples:__
Basic Example:
```
"Message Text" : {
"ban" : "{name} Was Just Banned",
"unban" : "{name} Was Just Unbanned",
"live" : "{name} Just Went Live",
"offline" : "{name} Just Went Offline",
"title" : "{name} Changed Their Title to \"{title}\"",
"game" : "{name} Changed Their Game to \"{game}\""
}
```
String Formatting Example:
```
"Bot Username" : "{name.capitalize()} - {message.capitalize()}"
```
If/Else Statement Example:
```
"Message Text" : {
"bans" : "{name} Was Just {'Ban' if message=='ban' else 'Unban'}ned"
}
```
## __Making Your Own Plugins__
### Get your notifications your way! Here's how to make a custom plugin
### Step 1: Getting Started
- Start by creating a python file containing a class with the name of your plugin
- You may want to store your plugin in the 'Plugins' folder for convenience
- There is an example file called 'Template.py' in the 'Plugins' folder
### Step 2: Help the program find your plugin
- In Main.py, import your module
- Add your plugin to the list of enabled plugins (Config.enabled_modules in Main.py)
### Step 3: Interfacing With the Program
- If you add your plugin's settings to config.json, you should to add a member variable called 'SETTINGS_KEY' to your module to mark the field
- There are four special functions that the main program will automatically try to use to interact with your plugin:
1. validate()
- This function is called before module initialization
- Used to check that the settings for your module have been correctly specified
- Optionally, you can return a list of 'warning' strings if you find any non-fatal issues
- Validate.py contains some helpful functions for validation
2. init(streamer_dict: dict)
- This function is used to initialize your module
- The full dictionary of streamer information is always passed to this function
- Read Streamer.py to see what information comes with the streamer dictionary
3. alert(streamer_obj: dict, message: str)
- Called every time an alert is triggered for a streamer
- A streamer's dictionary entry and the [type of alert](#alert-types) are always passed to this function
4. terminate()
- A 'destructor' for your plugin
- Called immediately before the program exits
- All exceptions that occur inside this function will be ignored
- You aren't limited to just these functions, but they're there to make your life easier
- These functions can be defined as either synchronous or asynchronous