Git Product home page Git Product logo

pajbot's Introduction

pajbot Python 4HEad

pajbot is a twitch chat bot created by pajlada.
Website

Note: pajbot is in maintenance mode. This means we focus on keeping the project alive by not allowing major overhauls of any pajbot system or any major features. Fixing bugs, updating dependencies and ensuring that code interacting with external APIs still function will be our main goal. Feature requests will not be accepted unless someone is willing to own the feature, and even then some features that change too much of the architecture won't be allowed. Current minimal supported Python version is 3.9.

Python versioning

We use pyenv to manage Python versions. Get familiar with this tool.
Quick install of pyenv on Linux systems: curl https://pyenv.run | bash

If you don't want to use pyenv's version of Python in any of our scripts, set the SKIP_PYENV environment variable to 1.

Quick install

  1. Install library requirements by typing ./scripts/venvinstall.sh in the root folder
  2. Copy ./configs/example.ini to ./config.ini and change the relevant lines in the file.
  3. Run the bot! ./main.py

Detailed install

You can find a detailed installation guide for pajbot in the install-docs directory of this repository.

Run-time options

Some values can be set to apply to your bot without modifying the config file, these are mostly for out-of-bot things.
They are configured using environment variables. The following options are available:

  • PB1_LOG_HIDE_TIMESTAMPS
    If this option is set to 1, all log entries will be printed without a timestamp prefix.

pajbot's People

Contributors

0rmi avatar alazymeme avatar badoge avatar datguy1 avatar dependabot[bot] avatar dextermb avatar felanbird avatar foretack avatar gempir avatar hotbear1110 avatar hptk avatar imgbot[bot] avatar iprodigy avatar joaopms avatar leppunen avatar magichack avatar manik1337 avatar mmattbtw avatar mrmurb avatar nacht123 avatar nerixyz avatar nuuls avatar pajlada avatar polle-vanhoof avatar randers00 avatar t-brawl avatar talvivian avatar troykomodo avatar yagueto avatar zneix avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pajbot's Issues

Pagination for /highlights/

Does it even need to be paginated?
Should it instead be categorized? By the date for example.
There could be a calendar you can browse, which shows you how many highlights was created on a day before you click it.

New sort of Action: ReplyAction

Derived from MessageAction. It simply replies in the same channel as the command was triggered from.
Or whispers if it was from a whisper.

Request soundcloud songs

  • Set up a soundcloud dev api thing
  • Figure out how to parse soundcloud links from donations
  • Create a global volume controller
  • Explore if we need to change anything in the database.

New time-related filter for web app

make a filter method in app.py that gives out a relative time if it happened less than 2 days ago, otherwise a full date in some fancy localized format

$(usersource) variable for commands

If you use $(usersource;1:username_raw) in a command, and the user does not pass through a valid username, it should fall back to source instead.

Store data about raffles?

tb_raffle
id, primary_key=True, autoincrement=True
winner_user_id, int, foreign key to tb_user.id, nullable=False, index=True
points, int, nullable=False

tb_raffle_participant
raffle_id, primary_key=True, autoincrement=False, foreign key to tb_raffle.id
user_id, int, primary_key=True, autoincrement=False, foreign key to tb_user.id

duels [enhancement]

pajbot should automatically accept duels or something. so many points wasted if not.

Revise the !add/!remove link blacklist/whitelist system.

Make it so we can remove blacklisted and whitelisted links with only the ID.
Syntax: !remove link blacklist --id 34
Change the !add link blacklist syntax, so it's instead like this:
!add link blacklist --shallow google.com
or
!add link blacklist --deep google.com
where --shallow is the default value for now.
Shallow = level 0, deep = level 1

Mark highlights of the stream, to be viewable on the website.

Command

!add highlight
Optional arguments
--id ID of existing highlight to edit
--offset Amount of "back in time" to offset the highlight with

Positional argument:
Tag/Description

Table layout

tb_stream

id, auto increment, primary key, int
title, varchar, 256. max length for twitch titles right now seem to be 140 but yolo
stream_start, datetime, time for when the stream started. When the stream is started, this should be adjusted based on the initial "created_at" attribute of the API call which we use to check if the stream is live or not.
stream_end, datetime, time for when the stream is ended. This should be the timestamp when the stream hs first seen as "offline", not after the X amount of retries have gotten the "offline" mark in a row.

tb_stream_chunk

_When a new chunk is detected (due to the change in id), try to check if there's a video ID available here: https://api.twitch.tv/kraken/channels/strifecro/videos?limit=10&broadcasts=true
If there is no video with the same broadcast id there yet, set it to null.
Upon checking stream status, if the current chunk url is null, this API should be checked again.

id, auto increment, primary key, int
stream_id, foreign key linking back to a tb_stream
broadcast_id, unique ID, as seen in https://api.twitch.tv/kraken/streams/strifecro. use _id there
video_url, varchar, 128, nullable
chunk_start, datetime
chunk_end, datetime

tb_stream_chunk_highlight

id, auto increment, primary key, int
chunk_id, foreign key linking back to a tb_stream
created_at, datetime, timestamp of when the highlight was created
highlight_offset, datetime
description, text, nullable

Code structure

another model
should be StreamManager
which starts an execute_every for the stream_check interval (by default, this is currently 20).
Maybe StreamManager should not keep a permanent session, as the DB requests should very seldomly be made.

Web part

There should be an entire section for highlights.
How should we list them?
Right now we fetch all chunks, in descending order, and just list all highlights.
In the future, we should probably fetch, along with the video url, we fetch the preview image as well.

TODO for later

  • Fetch preview image for each chunk as well
  • Improve the listing on /highlights so it looks decent
  • Add some sort of paging on the /highlights page
  • Run bot before stream goes live, go live until video url is fetched, then go offline for a second, and go live again so a new chunk is started, make sure it can fetch the video url for that as well.
  • ask ilisha how she wants the offset to work. Should the default be 40 seconds back in the vod?
  • look into delaying the video_url fetching, by 10 minutes or something. should it be run in a separate thread? This will be apparent during the test mentioned above

challenge raffles?

challenge to count from X to Y

import re
import logging

log = logging.getLogger('tyggbot')


class RaffleCountDownParser:
    init_val = -1
    current_num = -1
    participants = []
    target_reached = False
    regex = re.compile('[0-9]+')

    def __init__(self, bot):
        self.bot = bot

    def parse_line(self, msg, source):
        try:
            # If current number is > 0 we are on a raffle 
            if self.current_num > 0:
                # The message has to be a number
                if self.regex.match(msg) is None:
                    reset(self)
                    return False

                chat_num = int(msg.strip())
                # If the number chat spams is equal or 1 point smaller than the previous
                # it is valid else fail                
                if chat_num == self.current_num or chat_num == self.current_num - 1:
                    self.current_num = chat_num
                    if not source.username_raw in self.participants:
                        # Add new participatns
                        self.participants.append(source.username_raw)

                else:
                    reset(self)
                    return False 
            # If we reached the target
            elif self.current_num == 0:
                self.target_reached = True

            if self.target_reached:
                # Reward participants
                log.debug(participants)
                reset(self)

        except:
            log.exception('Exception')

    def init_raffle_countdown(self, init_val):
        self.init_val = init_val
        self.participants = []
        self.current_num = init_val
        self.target_reached = False

    def reset(self):
        self.target_reached = False
        self.current_num = -1
        self.init_val = -1
        self.participants = []

duel winstreaks?

,for the winstreak: have the time of the last duel already on your page - just need to capture the result. if it's win winstreak += 1 else winstreak = 0 -> sort user's descending by winstreak count and you should get the list

do we want this?

Let moderators remove/skip songs

Another ajax query which looks for songs that have been deleted.
This allows us to skip songs for forsen, in case there's a hidden earrape in a song or something.
Make sure this is something he wants before developing.

Web based login

Should be admin only to begin with.
Use twitch authentication.
Can be used to modify highlights, see all available filters/banphrases etc.
"admin only" means people with level 500+

Modifying commands in admin panel

Bot

We need to make sure commands are always synced when they are modified.

To help in this task, we will need to make some changes to the database.
While we're at it, rename tb_commands to tb_command.
Remove some data from tb_command and move it to tb_command_data

tb_command_data structure
command_id, int, primary_key=True, autoincrement=False, foreign_key='tb_command.id'
num_uses, int, nullable=False

from tb_command remove:
created
last_updated

This would allow us to always keep tb_command up to date in the database when we make some modifications, but let tb_command_data fall behind since it's not as important.

Website

There would need to be an /admin/commands/ page, from which you can click commands and edit them. Also a link to a page where you can create commands.

Connection between Bot and Website

When a command is created or edited, we need to send a ping to the Bot somehow, to let it know that the command with id X has been updated somehow.

How do we solve this?

Timezones

Each bot should have a timezone set in the config file. This should be the timezone that the streamer streams in. All time-related things should be customized to this timezone.

Beautify URL's in tweets

When a tweet is posted there is no way to see what the link is, as only the t.co link link is shown.
It should be possible to beautify the text before it is sent to chat.

In tyggbot.py#L118 after def on_status(self, tweet) it should be possible to use tweet.entities['urls'] to fetch expanded_url as shown in Twitter's API documentation:

Entities in Objects - The urls entity

{
  ...
  "text": "Today, Twitter is updating embedded Tweets to enable a richer photo experience: https:\/\/t.co\/XdXRudPXH5",
  "entities": {
    "hashtags": [],
    "symbols": [],
    "urls": [{
      "url": "https:\/\/t.co\/XdXRudPXH5",
      "expanded_url": "https:\/\/blog.twitter.com\/2013\/rich-photo-experience-now-in-embedded-tweets-3",
      "display_url": "blog.twitter.com\/2013\/rich-phot\u2026",
      "indices": [80, 103]
    }],
    "user_mentions": []
  }
}

How to do the actual replace, I don't know. I guess the code has to be able to handle more than one link per tweet, which means using the url key, and replace it with expanded_url. Because if there's more than one link, the indices key will not be accurate after the first link has been replaced.

Also, while beautifying the link, I personally would like to remove the http:// prefix to save some space in chat, just like Twitter does with their display_url. But since that key is cut off if the link is long, that one can probably not be used for chat.

Combo Emote

Count when X amount of emotes are posted in a row.
If a big enough combo is created, create a notification on the overlay.
Relies in #35

Pleblist

Database

Single table for now

id, int, primary_key
stream_id, int, foreign key to tb_stream.id
youtube_id, varchar, 64, nonnullable
date_added, datetime, nonnullable
date_played, datetime, nullable

Implemented in 795da1d

API

/pleblist/list

Get a list of pleblist songs for the current stream. Return 404 if no stream is active.
Implemented in 2b260be

/pleblist/list/<stream_id>

Get a list of pleblist songs for the given stream id.
Implemented in 2b260be

/pleblist/add

Add a song to the pleblist.
Uses the youtube_id value from a POST request.
This should require some sort of authentication before going through.
Implemented in 2b260be

/pleblist/next

Skip to the next song in the pleblist.
This should require some sort of authentication before going through
Structure added in 2b260be. Still lacking implementation.

/pleblist/blacklist

Adds the current song to the blacklist and skip to the next song in the pleblist.
This should require some sort of authentication before going through.
Structure added in 2b260be. Still lacking implementation.

Youtube frontend

Simple youtube player covers 70% of the area.
Under or above the youtube player, place two buttons:
Skip - Skip the current song (uses the /pleblist/next api call)
Blacklist - Skip and blacklist the current song (uses the /pleblist/blacklist api call)
A list of songs in the playlist on the right side.

Design

design
Base design added in c890b2b

Donation list frontend

Simply connect to the streamtip API, fetch new donations and parse any youtube links.

Should we parse the youtube link and make sure it's available in sweden?
Then we need $$$ for a proper youtube API Key Kappa

Design

design

Suggestions from Transcendence9

  • Make it so mods have 80% cd reduction
  • Add a warning system to timeouts

For the web interface:

  • Add a "Back to command" link next to Save Changes on Edit Command
  • Create/Modify MOTDs (timed messages) #75
  • Create/Modify Banphrases
  • Improve the alias on "create command" page.
  • Check what enter does in all fields on the Create Command page.
  • If no alias has been added, and Create is pressed, press Add Alias as well first.
  • Move over eloise's dashboard

More detailed command viewing

Should be able to click on commands to go to their separate command page (/commands/id+firstalias)
This would show their cooldown, description, maybe some extended usage examples etc.

Duel System

Duel someone for points.
How should this work?
Describe below!

Multiple filters for variables

With the new regular expression engine we use, we can simple allow for an infinite amount of filters to be applied to a variable.
See how we did it with if-arguments.

Design changes to /pleblist/history/

  • Make already-played songs gray
  • Strengthen the color of the currently playing song
  • Add an anchor link at the top which takes you to the currently playing song
  • Show the current song at the top of the page, since that's usually the most relevant thing.

Stream overlay system

This should be embedded as a CLR in the web part.
There should be some sort of password or authentication to get the CLR url, other than that it's fine.

The Stream overlay system can be used to show notifications or play sounds anywhere on the screen.

Rework phrase system

Could we access phrases by variables in actions?

This way, we could, for example, call points "Pizza Points" without any issues. Instead of typing "points" in commands we would place $(phrase:points) instead.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.