Created
March 8, 2019 03:59
-
-
Save ellisgeek/2a2044c086a50a03728d17f04662b6d7 to your computer and use it in GitHub Desktop.
basic bot for people to guess koopa freerunning times.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import logging | |
import irc.bot | |
import requests | |
import toml | |
import re | |
from copy import deepcopy | |
from time import time, strftime, localtime | |
class TwitchBot(irc.bot.SingleServerIRCBot): | |
"""Base Class for Twitch IRC Bot""" | |
def __init__(self, username, oauth_token, client_id, channel): | |
self.token = oauth_token | |
self.channel = '#' + channel.lower() | |
self.minigames = { | |
"race": { | |
"type": "time", | |
'friendly_name': "Race", | |
"about": "guess the exact time it takes to win the race", | |
'guess_regex': re.compile("^(([01]):)?([0-5]?\d)\.([0-5]?\d)$"), | |
'guess_help': "Make guesses in the format [<minutes>:]<seconds>.<milliseconds> (minutes are optional)", | |
'guesses': {} | |
} | |
} | |
self.active_minigame = None | |
self.minigame_active = False | |
# Get the channel id, we will need this for v5 API calls | |
url = 'https://api.twitch.tv/kraken/users?login=' + channel | |
headers = {'Client-ID': client_id, 'Accept': 'application/vnd.twitchtv.v5+json'} | |
r = requests.get(url, headers=headers).json() | |
self.channel_id = r['users'][0]['_id'] | |
logging.info(f"Channel ID is {self.channel_id}") | |
# Create IRC bot connection | |
server = 'irc.chat.twitch.tv' | |
port = 6667 | |
logging.info(f"Connecting to {server}:{port} as {username}") | |
irc.bot.SingleServerIRCBot.__init__( | |
self, | |
[(server, port, 'oauth:' + oauth_token)], | |
username, | |
username | |
) | |
def on_welcome(self, c, e): | |
"""Join Channel when we connect to the server""" | |
c.cap('REQ', ':twitch.tv/membership') | |
c.cap('REQ', ':twitch.tv/tags') | |
logging.info(f"Joining Channel {self.channel}") | |
c.join(self.channel) | |
def on_pubmsg(self, c, e): | |
"""Parse chat messages for bot commands starting with !""" | |
tags = {} | |
for i in e.tags: | |
tags[i['key']] = i['value'] | |
e.tags = tags | |
if e.arguments[0][:1] == '!': | |
cmd = e.arguments[0].split(' ')[0][1:] | |
logging.debug(f"Received Command: !{cmd}") | |
self.do_command(e, cmd) | |
return | |
def do_command(self, e, cmd): | |
"""Execute bot commands""" | |
c = self.connection | |
cmd_user = e.source.split('!')[0] | |
is_broadcaster = True if e.tags['badges'] and 'broadcaster' in e.tags['badges'] else False | |
is_mod = True if e.tags['mod'] == '1' else False | |
is_vip = True if e.tags['badges'] and 'vip' in e.tags['badges'] else False | |
if cmd == "minigame": | |
if is_mod or is_broadcaster: | |
logging.debug("Start a minigame") | |
args = (e.arguments[0].split(' ')[1:]) or None | |
if self.minigame_active: | |
c.privmsg(self.channel, "Minigame is already active!") | |
return | |
minigames_help = "" | |
leng = len(self.minigames) | |
iter = 1 | |
for key, value in self.minigames.items(): | |
if iter == leng: | |
sep = '' | |
else: | |
sep = ', ' | |
minigames_help += f"{key} ({value['about']}){sep}" | |
iter += 1 | |
if not args: | |
c.privmsg(self.channel, f"Available minigames are: {minigames_help}") | |
return | |
minigame = args[0] | |
if minigame not in self.minigames: | |
c.privmsg( | |
self.channel, | |
f"That is not a valid minigame, available minigames are: {minigames_help}" | |
) | |
return | |
self.minigame_active = True | |
self.active_minigame = deepcopy(self.minigames[minigame]) | |
c.privmsg( | |
self.channel, | |
f"Starting minigame {self.active_minigame['friendly_name']}, the goal is {self.active_minigame['about']}" | |
) | |
if cmd == "guess": | |
args = (e.arguments[0].split(' ')[1:]) or None | |
if not self.minigame_active: | |
c.privmsg(self.channel, f"Sorry @{cmd_user}, no minigame is running.") | |
return | |
if not args or not self.active_minigame['guess_regex'].match(args[0]): | |
c.privmsg( | |
self.channel, | |
f"{self.active_minigame['guess_help']} @{cmd_user}" | |
) | |
return | |
if cmd_user in self.active_minigame['guesses']: | |
c.privmsg(self.channel, f"You have already guessed for this minigame @{cmd_user}") | |
return | |
self.active_minigame['guesses'][cmd_user] = args[0] | |
if cmd == 'guesses': | |
if is_mod or is_broadcaster: | |
if not self.minigame_active: | |
c.privmsg(self.channel, "No minigame active!") | |
return | |
guesses = "Current Guesses: " | |
leng = len(self.minigames) | |
iter = 1 | |
for user, guess in self.active_minigame['guesses'].items(): | |
if iter == leng: | |
sep = '' | |
else: | |
sep = ', ' | |
guesses += f"{user} = {guess}{sep}" | |
iter += 1 | |
c.privmsg(self.channel, guesses) | |
if cmd == "endgame": | |
if is_mod or is_broadcaster: | |
args = (e.arguments[0].split(' ')[1:]) or None | |
if not self.minigame_active: | |
c.privmsg(self.channel, "No minigame active!") | |
return | |
if not args or not self.active_minigame['guess_regex'].match(args[0]): | |
c.privmsg( | |
self.channel, | |
f"winning time needs to be in same format as guess @{cmd_user}" | |
) | |
return | |
winning_time = args[0] | |
c.privmsg(self.channel, f"{self.active_minigame['friendly_name']} is ending, {self.channel.strip('#')}'s time was {winning_time}") | |
for user, guess in self.active_minigame['guesses'].items(): | |
if guess == winning_time: | |
c.privmsg(self.channel, f"Congratulations @{user}, you guessed @{self.channel.strip('#')}'s time down to the millisecond PogChamp") | |
break | |
c.privmsg(self.channel, f"No one guessed {self.channel.strip('#')}'s time, better luck next time!") | |
self.active_minigame = None | |
self.minigame_active = False | |
if cmd == "ping": | |
if is_mod or is_broadcaster: | |
logging.debug("Pong") | |
c.privmsg(self.channel, "!pong") | |
else: | |
return | |
def main(): | |
"""Main Entry point""" | |
logging.basicConfig(level=logging.DEBUG) | |
username = "SyneArdwin" | |
oauth_token = "40x03hdf0e7fuzexb1rj7rpwmt5jqk" | |
client_id = "905i1wl26azhpevr9bxfwxh45qalxt" | |
channel = "syneardwin" | |
bot = TwitchBot(username, oauth_token, client_id, channel) | |
bot.start() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment