0

Hello Guys i am trying to learn how to make a twitch bot for my friends' channel they streams regulary and sometimes i join them. Now i was able to make the bot join to the chat room but i couldn't figure out administration part so the bot suppoused to timeout any body uses the word "swear" instead i get this error:

tmi: :tmi.twitch.tv 001 wasddabulyuasede_bot :Welcome, GLHF!
:tmi.twitch.tv 002 wasddabulyuasede_bot :Your host is tmi.twitch.tv

:tmi.twitch.tv 003 wasddabulyuasede_bot :This server is rather new
:tmi.twitch.tv 004 wasddabulyuasede_bot :-
:tmi.twitch.tv 375 wasddabulyuasede_bot :-
:tmi.twitch.tv 372 wasddabulyuasede_bot :You are in a maze of twisty passages, all alike.
:tmi.twitch.tv 376 wasddabulyuasede_bot :>

wasddabulyuasede_bot: :wasddabulyuasede_bot!wasddabulyuasede_bot@wasddabulyuasede_bot.tmi.twitch.tv JOIN #wlrs
_
:wasddabulyuasede_bot.tmi.twitch.tv 353 wasddabulyuasede_bot = #wlrs_ :wasddabulyuasede_bot
:wasddabulyuasede_bot.tmi.twitch.tv 366 wasddabulyuasede_bot #wlrs_ :End of /NAMES list

wlrs_: swear

Traceback (most recent call last):
  File "Bot.py", line 57, in <module>
    timeout(s,username,10)
  File "Bot.py", line 33, in timeout
    chat(sock, ".timeout {}".format(user, secs))
  File "Bot.py", line 14, in chat
    sock.send("PRIVMSG #{} :{}".format(cfg.CHAN, msg_encoded))
TypeError: a bytes-like object is required, not 'str'

CODE

#cfg.py
#oauth key has been removed

HOST = "irc.chat.twitch.tv"
PORT = 6667
PASS = "oauth:xxxxxxxxxxxxxxxxxxxx"
NICK = "wasddabulyuasede_bot"
CHAN = "#wlrs_"
RATE = (20/30)
PATT = [
    r"swear"
]

Bot.py

from cfg import HOST, PORT, PASS, NICK, CHAN, RATE, PATT
import cfg
import socket
import re
import time

def chat(sock, msg):
    """
    Send a chat message to the server.
    Keyword arguments:
    sock -- the socket over which to send the message
    msg  -- the message to be sent
    """
    msg_encoded = msg.encode("utf-8")
    sock.send("PRIVMSG #{} :{}".format(cfg.CHAN, msg_encoded))

# def ban(sock, user):
#     """
#     Ban a user from the current channel.
#     Keyword arguments:
#     sock -- the socket over which to send the ban command
#     user -- the user to be banned
#     """
#     chat(sock, ".ban {}".format(user))
#
def timeout(sock, user, secs=600):
    """
    Time out a user for a set period of time.
    Keyword arguments:
    sock -- the socket over which to send the timeout command
    user -- the user to be timed out
    secs -- the length of the timeout in seconds (default 600)
    """
    chat(sock, ".timeout {}".format(user, secs))


# ----- network functions -----
s = socket.socket()
s.connect((HOST, PORT))
s.send("PASS {} \r\n".format(PASS).encode("utf-8"))
s.send("NICK {} \r\n".format(NICK).encode("utf-8"))
s.send("JOIN {} \r\n".format(CHAN).encode("utf-8"))


# pattern we are looking for
CHAT_MSG=re.compile(r"^:\w+!\w+@\w+\.tmi\.twitch\.tv PRIVMSG #\w+ :")

while True:
    response = s.recv(1024).decode("utf-8")
    if response == "PING :tmi.twitch.tv\r\n":
        s.send("PONG :tmi.twitch.tv\r\n".encode("utf-8"))
    else:
        username = re.search(r"\w+", response).group(0) # return the entire match
        message = CHAT_MSG.sub("", response)
        print(username + ": " + message)
        for pattern in cfg.PATT:
            if re.match(pattern,message):
                timeout(s,username,10)
                break
    time.sleep(1/cfg.RATE)
walrus
  • 65
  • 1
  • 5
  • Possible duplicate of [Sending string via socket (python)](https://stackoverflow.com/questions/21233340/sending-string-via-socket-python) – Paco H. Sep 18 '17 at 14:56

1 Answers1

1

A string is an abstraction, representing a sequence of unicode codepoints. To turn a string into a sequence of bytes, you need to encode your string, aka decide on how you want to represent your text on the wire. For Twitch, use UTF-8:

full_msg = "PRIVMSG #{} :{}".format(cfg.CHAN, msg)
msg_encoded = full_msg.encode("utf-8")
sock.send(msg_encoded)
Felk
  • 7,720
  • 2
  • 35
  • 65
  • Doesn't `socket.send` require bytes? Are you not giving a `str` here? – Paco H. Sep 18 '17 at 14:59
  • `socket.send` expects bytes: https://docs.python.org/3/library/socket.html#socket.socket.send – Felk Sep 18 '17 at 15:01
  • Yes, on the first line you go from str to bytes. But isn't the result of the format of the second line a str? – Paco H. Sep 18 '17 at 15:06
  • `File "Bot.py", line 15, in chat sock.send("PRIVMSG #{} :{}".format(cfg.CHAN, msg_encoded)) TypeError: a bytes-like object is required, not 'str'` i still get the same error – walrus Sep 18 '17 at 15:10
  • Please update your answer to include the new code and also show what line is the one mentioned in the error message – Felk Sep 18 '17 at 15:19
  • i don't get any errors but not sure if it works properly.thanks for help – walrus Sep 18 '17 at 16:17