diff --git a/README.md b/README.md index ec6bd58..3b86fc5 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ whitelist: * `server`: Twitch IRC server to be used (default should be fine) * `clearmsg_timeout`: Time to wait for an moderator to delete a message, before it's added to the TTS queue +You can generate your `oauth_token` by leaving the value empty when starting `tts.exe/tts.py`. The integrated webserver will then provide an OAuth-Generator. (Due to limitations to the `redirect_url` parameter used by twitch, this is only possible if you use Port `8080` or `80` as `http:bind`.) + Please note that the `oauth_token` is valid for approximately 60 days. If it become invalid the bot will not connect anymore and you will have to renew the token. ##### http diff --git a/tts.py b/tts.py index dea5e3a..cfe2620 100644 --- a/tts.py +++ b/tts.py @@ -27,6 +27,8 @@ import sys import time import datetime import socketserver +import urllib.request +import urllib.parse from threading import Thread from http.server import BaseHTTPRequestHandler @@ -398,6 +400,39 @@ class HTTPserv(BaseHTTPRequestHandler): self.end_headers() self.wfile.write(bytes("Internal Server error\n", "utf-8")) + elif self.path.startswith('/token') and conf['IRC_OAUTH_TOKEN'] == "Invalid": + data = {} + data['client_id'] = "ebo548vs6tq54c9zlrgin2yfzzlrrs" + data['response_type'] = "token" + data['scope'] = "chat:edit chat:read" + if conf['HTTP_PORT'] == 80: + data['redirect_uri'] = "http://localhost/token" + elif conf['HTTP_PORT'] == 8080: + data['redirect_uri'] = "http://localhost:8080/token" + else: + self.send_response(500) + self.send_header('Content-type', 'text/plain') + self.end_headers() + self.wfile.write(bytes("You can only use this function if HTTP_PORT is 80 or 8080. Please change your port or use https://www.21x9.org/twitch instead.\n", "utf-8")) + return False + + try: + url_values = urllib.parse.urlencode(data) + url = "https://id.twitch.tv/oauth2/authorize" + full_url = url + "?" + url_values + data = urllib.request.urlopen(full_url) + if data: + self.send_response(200) + self.send_header('Content-type', 'text/html') + self.end_headers() + self.wfile.write(bytes("OAuth Token Generator
Click to start the OAuth process.
\n", "utf-8")) + else: + self.send_response(500) + self.send_header('Content-type', 'text/plain') + self.end_headers() + self.wfile.write(bytes("Could not get OAuth-URL from Twitch\n", "utf-8")) + except: + logging.error('Could not fetch OAuth-URL from Twitch.') else: self.send_response(404) self.send_header('Server', 'TTS') @@ -477,7 +512,8 @@ def load_config(): if not conf['IRC_USERNAME']: raise ValueError('Please add the bots username to config.yml.') if not conf['IRC_OAUTH_TOKEN']: - raise ValueError('Please add the bots oauth-token to config.yml.') + conf['IRC_OAUTH_TOKEN'] = "Invalid" + return conf if not conf['IRC_OAUTH_TOKEN'].startswith('oauth:'): raise ValueError('Your oauth-token is invalid, it has to start with: "oauth:"') @@ -506,54 +542,60 @@ def main(): http_thread = Thread(target=http_serve_forever, daemon=True, args=(httpd, )) http_thread.start() - logging.info("Starting IRC bot") - irc = IRC() - irc.connect(conf['IRC_SERVER'], 6667, conf['IRC_CHANNEL'], conf['IRC_USERNAME'], conf['IRC_OAUTH_TOKEN']) - irc.sendpriv(conf['IRC_CHANNEL'], 'MrDestructoid', conf['MESSAGE']['READY']) + if conf['IRC_OAUTH_TOKEN'] == "Invalid": + logging.error('No OAuth Token, skipping start of IRC bot.') + while True: + logging.error('Please open http://'+str(conf['HTTP_BIND'])+':'+str(conf['HTTP_PORT'])+'/token to generate your OAuth-Token.') + time.sleep(10) + else: + logging.info("Starting IRC bot") + irc = IRC() + irc.connect(conf['IRC_SERVER'], 6667, conf['IRC_CHANNEL'], conf['IRC_USERNAME'], conf['IRC_OAUTH_TOKEN']) + irc.sendpriv(conf['IRC_CHANNEL'], 'MrDestructoid', conf['MESSAGE']['READY']) - logging.info("Please open your browser and visit: http://"+str(conf['HTTP_BIND']+":"+str(conf['HTTP_PORT'])+"/")) + logging.info("Please open your browser and visit: http://"+str(conf['HTTP_BIND']+":"+str(conf['HTTP_PORT'])+"/")) - while True: - if conf['LOG_LEVEL'] == "DEBUG": - time.sleep(1) + while True: + if conf['LOG_LEVEL'] == "DEBUG": + time.sleep(1) - try: - irc.get_response() + try: + irc.get_response() - if not irc.tts_status: - logging.debug("TTS is disabled") - if conf['LOG_LEVEL'] == "DEBUG": - time.sleep(1) - continue + if not irc.tts_status: + logging.debug("TTS is disabled") + if conf['LOG_LEVEL'] == "DEBUG": + time.sleep(1) + continue - confreload = datetime.datetime.now() - if confreload - lastreload > datetime.timedelta(seconds=60): - conf = load_config() - lastreload = datetime.datetime.now() - - if irc.quickvote and irc.votemsg: - logging.info('Quickvote is active') - irc.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") + confreload = datetime.datetime.now() + if confreload - lastreload > datetime.timedelta(seconds=60): + conf = load_config() + lastreload = datetime.datetime.now() + + if irc.quickvote and irc.votemsg: + logging.info('Quickvote is active') + irc.sendpriv(conf['IRC_CHANNEL'], "@chat", conf['MESSAGE']['VOTESTART'] + " (" + str(irc.votemsg) + ")") - logging.debug('Raw message queue:') - logging.debug(msg_queue_raw) - - for raw_msg in msg_queue_raw: - logging.debug('Raw msg:') + logging.debug('Raw message queue:') logging.debug(msg_queue_raw) - now = datetime.datetime.now() - if now - raw_msg['queuetime'] > datetime.timedelta(seconds=conf['IRC_CLEARMSG_TIMEOUT']): - logging.debug('clearmsg_timeout reached') - if raw_msg['timestamp'] not in msg_queue: - logging.info('Sending TTS message') - msg_queue[raw_msg['timestamp']] = [raw_msg['user'], raw_msg['msg']] - logging.debug(msg_queue) - else: - logging.debug('Msg is already in queue') - except KeyboardInterrupt: - logging.info('Exiting...') - sys.exit() + for raw_msg in msg_queue_raw: + logging.debug('Raw msg:') + logging.debug(msg_queue_raw) + + now = datetime.datetime.now() + if now - raw_msg['queuetime'] > datetime.timedelta(seconds=conf['IRC_CLEARMSG_TIMEOUT']): + logging.debug('clearmsg_timeout reached') + if raw_msg['timestamp'] not in msg_queue: + logging.info('Sending TTS message') + msg_queue[raw_msg['timestamp']] = [raw_msg['user'], raw_msg['msg']] + logging.debug(msg_queue) + else: + logging.debug('Msg is already in queue') + except KeyboardInterrupt: + logging.info('Exiting...') + sys.exit() if __name__ == "__main__": main()