├── db └── example │ ├── chatlog.txt │ └── botactions.txt ├── requirements.txt ├── .DS_Store ├── README.md ├── src ├── config.py ├── rolecheck.py └── main.py └── LICENSE /db/example/chatlog.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /db/example/botactions.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.26.0 -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qwertyuiop0011/Pytwitch/HEAD/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pytwitch 2 | Twitch chat IRC communication written in python 3 | -------------------------------------------------------------------------------- /src/config.py: -------------------------------------------------------------------------------- 1 | server = { 2 | 'host': 'irc.chat.twitch.tv', 3 | 'port': 80 4 | } 5 | 6 | bot = { 7 | 'botnick': '', 8 | 'channel': '', 9 | 'oauth': '', 10 | 'prefix': '.' 11 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Jeesung Lee 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/rolecheck.py: -------------------------------------------------------------------------------- 1 | import urllib.request 2 | import json 3 | import config 4 | 5 | CHANNEL = config.bot['channel'] 6 | 7 | with urllib.request.urlopen(f'http://tmi.twitch.tv/group/user/{CHANNEL}/chatters') as response: 8 | res = json.loads(response.read()) 9 | 10 | class UserRole: 11 | def __init__(self, user): 12 | self.user = user 13 | 14 | def ismod(self): 15 | try: 16 | if self.user in res['chatters']['moderators']: 17 | return True 18 | else: 19 | return False 20 | except: 21 | return False 22 | 23 | def isglobalmod(self): 24 | try: 25 | if self.user in res['chatters']['global_mods']: 26 | return True 27 | else: 28 | return False 29 | except: 30 | return False 31 | 32 | def isstaff(self): 33 | try: 34 | if self.user in res['chatters']['staff']: 35 | return True 36 | else: 37 | return False 38 | except: 39 | return False 40 | 41 | def isadmin(self): 42 | try: 43 | if self.user in res['chatters']['admins']: 44 | return True 45 | else: 46 | return False 47 | except: 48 | return False 49 | 50 | def ishost(self): 51 | if self.user == CHANNEL: 52 | return True 53 | else: 54 | return False -------------------------------------------------------------------------------- /src/main.py: -------------------------------------------------------------------------------- 1 | #-*- coding:utf-8 -*- 2 | import socket 3 | import requests 4 | import json 5 | import redis 6 | 7 | import config 8 | import rolecheck 9 | 10 | from datetime import datetime 11 | 12 | HOST = config.server['host'] 13 | PORT = config.server['port'] 14 | PREFIX = config.bot['prefix'] 15 | 16 | NICK = config.bot['botnick'] 17 | CHANNEL = config.bot['channel'] 18 | PASS = config.bot['oauth'] 19 | 20 | irc = socket.socket() 21 | irc.connect((HOST, PORT)) 22 | irc.send(bytes(f'PASS oauth:{PASS}\r\n', 'utf-8')) 23 | irc.send(bytes(f'NICK siro_32\r\n', 'utf-8')) 24 | irc.send(bytes(f'JOIN #{CHANNEL}\r\n', 'utf-8')) 25 | 26 | def sendmsg(message): 27 | irc.send(bytes(f'PRIVMSG #{CHANNEL} :{message}\r\n', 'utf-8')) 28 | with open(f'db/{CHANNEL}/botactions.txt', 'a', encoding = 'utf-8') as f: 29 | f.write(f'{datetime.utcnow()} | BOT MESSAGE: {message}\n') 30 | 31 | while True: 32 | try: 33 | buffer = irc.recv(2048).decode('utf-8') 34 | 35 | if buffer == 'PING :tmi.twitch.tv\r\n': 36 | irc.send(bytes('PONG :tmi.twitch.tv\r\n', 'utf-8')) 37 | 38 | sw = buffer.find('PRIVMSG') 39 | 40 | if sw != -1: 41 | arr = buffer.split('\r\n') 42 | arr1 = arr[0].split('#') 43 | arr2 = arr1[1].split(':') 44 | arr3 = arr2[0].split(' ') 45 | 46 | susr = arr3[0] 47 | rmsg = arr2[1] 48 | 49 | print(f'{susr} said {rmsg}') 50 | 51 | rc = rolecheck.UserRole(susr) 52 | 53 | # Commands 54 | if rmsg == 'zzz': 55 | sendmsg('zzz') 56 | 57 | with open(f'db/{CHANNEL}/chatlog.txt', 'a', encoding = 'utf-8') as f: 58 | if rc.ishost(): 59 | f.write(f'{datetime.utcnow()} | STREAMER ({susr}): {rmsg}\n') 60 | elif rc.isstaff(): 61 | f.write(f'{datetime.utcnow()} | STAFF ({susr}): {rmsg}\n') 62 | elif rc.isglobalmod(): 63 | f.write(f'{datetime.utcnow()} | GLOBAL_MOD ({susr}): {rmsg}\n') 64 | elif rc.ismod(): 65 | f.write(f'{datetime.utcnow()} | MOD ({susr}): {rmsg}\n') 66 | elif rc.isadmin(): 67 | f.write(f'{datetime.utcnow()} | ADMIN ({susr}): {rmsg}\n') 68 | else: 69 | f.write(f'{datetime.utcnow()} | {susr}: {rmsg}\n') 70 | 71 | else: 72 | print(buffer) 73 | 74 | except socket.error: 75 | print('Socket ERROR. Closing socket...') 76 | except socket.timeout: 77 | print('Socket TIMEOUT. Closing socket...') --------------------------------------------------------------------------------