96 lines
3.0 KiB
Python
96 lines
3.0 KiB
Python
import enum
|
|
import logging
|
|
import socket
|
|
import time
|
|
|
|
from twitchAPI import Twitch, AuthScope
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
TW_CHAT_SERVER = 'irc.chat.twitch.tv'
|
|
TW_CHAT_PORT = 6667
|
|
|
|
|
|
class TwitchStreamStatus(enum.Enum):
|
|
ONLINE = 0
|
|
OFFLINE = 1
|
|
NOT_FOUND = 2
|
|
UNAUTHORIZED = 3
|
|
ERROR = 4
|
|
|
|
|
|
class TwitchApi:
|
|
_cached_token = None
|
|
|
|
def __init__(self, client_id, client_secret):
|
|
self.client_id = client_id
|
|
self.client_secret = client_secret
|
|
self.twitch = Twitch(self.client_id, self.client_secret, target_app_auth_scope=[AuthScope.CHAT_READ])
|
|
self.twitch.authenticate_app([AuthScope.CHAT_READ])
|
|
|
|
def get_user_status(self, streamer):
|
|
try:
|
|
streams = self.twitch.get_streams(user_login=streamer)
|
|
if streams is None or len(streams["data"]) < 1:
|
|
return TwitchStreamStatus.OFFLINE
|
|
else:
|
|
return TwitchStreamStatus.ONLINE
|
|
except:
|
|
return TwitchStreamStatus.ERROR
|
|
|
|
def start_chat(self, streamer_name, on_message):
|
|
logger.info("Connecting to %s:%s", TW_CHAT_SERVER, TW_CHAT_PORT)
|
|
connection = ChatConnection(streamer_name, self, on_message)
|
|
|
|
self.twitch.get_app_token()
|
|
connection.run()
|
|
|
|
def get_user_chat_channel(self, streamer_name):
|
|
streams = self.twitch.get_streams(user_login=streamer_name)
|
|
if streams is None or len(streams["data"]) < 1:
|
|
return None
|
|
return streams["data"][0]["user_login"]
|
|
|
|
|
|
class ChatConnection:
|
|
logger = logging.getLogger(__name__)
|
|
|
|
connection = None
|
|
|
|
def __init__(self, streamer_name, api, on_message):
|
|
self.on_message = on_message
|
|
self.api = api
|
|
self.streamer_name = streamer_name
|
|
|
|
def run(self):
|
|
# Need to verify channel name.. case sensitive
|
|
channel = self.api.get_user_chat_channel(self.streamer_name)
|
|
if not channel:
|
|
logger.error("Cannot find streamer channel, Offline?")
|
|
return
|
|
|
|
self.connect_to_chat(f"#{channel}")
|
|
|
|
def connect_to_chat(self, channel):
|
|
self.connection = socket.socket()
|
|
self.connection.connect((TW_CHAT_SERVER, TW_CHAT_PORT))
|
|
# public data to join hat
|
|
self.connection.send(f"PASS couldBeRandomString\r\n".encode("utf-8"))
|
|
self.connection.send(f"NICK justinfan113\r\n".encode("utf-8"))
|
|
self.connection.send(f"JOIN {channel}\r\n".encode("utf-8"))
|
|
|
|
logger.info("Connected to %s", channel)
|
|
|
|
try:
|
|
while True:
|
|
msg = self.connection.recv(2048).decode('utf-8')
|
|
if "PING :tmi.twitch.tv" in msg:
|
|
self.connection.send(bytes("PONG :tmi.twitch.tv\r\n", "UTF-8"))
|
|
logger.info("RECEIVED Ping from server. Answered")
|
|
continue
|
|
if self.on_message:
|
|
self.on_message(msg)
|
|
except BaseException as e:
|
|
logger.error(e)
|
|
logger.error("Error happened during reading chat")
|