I am trying to make an irc bot. It connects but doesn't send the complete message. If I want to send "hello world" it only sends "hello". It just sends everything until the first space.
In this program if you type hello in irc, the bot is supposed to send hello world. But it only sends hello.
import socket
channel = "#bots"
server = "chat.freenode.org"
nickname = "my_bot"
class IRC:
irc = socket.socket()
def __init__(self):
self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def send(self, chan, msg):
self.irc.send("PRIVMSG " + chan + " " + msg + "\n")
def connect(self, server, channel, botnick):
# defines the socket
print("connecting to: " + server)
self.irc.connect((server, 6667)) # connects to the server
self.irc.send("NICK %s\n" % botnick)
self.irc.send("USER %s %s Ibot :%s\n" % (botnick, botnick, botnick))
self.irc.send("JOIN %s\n" % channel)
self.irc.send("PRIVMSG %s :Hello Master\n" % channel)
def get_text(self):
text = self.irc.recv(2040) # receive the text
if text.find('PING') != -1:
self.irc.send('PONG ' + text.split()[1] + 'rn')
return text
irc = IRC()
irc.connect(server, channel, nickname)
while True:
text = irc.get_text().strip()
if "hello" in text.lower():
irc.send(channel, "hello world")
print text
You forgot a : before the message. This should work:
def send(self, chan, msg):
self.irc.send("PRIVMSG " + chan + " :" + msg + "\n")
Related
i have a client will send some string to my server. However, i need to send twice so that the server get the package. So for every package client wants to send the server, it needs to send twice. I do not understand why it went in this way.
my server's code that does listening:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
myIp = "0x2A"
myPort = 2222
targetPort = 0
myAddress = ("localhost",myPort)
bufferSize = 1024
def listen():
print('starting up on {} port {}'.format(*myAddress))
sock.bind(myAddress)
# sock.listen(1)
print("waiting for message")
# connection, client_address = sock.accept()
while True:
received = sock.recvfrom(bufferSize)[0]
address = sock.recvfrom(bufferSize)[1]
received = json.loads(received.decode())
source = received.get("source")
destination = received.get("destination")
length = received.get("length")
message = received.get("message")
protocol = received.get("protocol")
print("the source is: " + source)
if destination == myIp:
print("the message is: " + message)
print('sending back to sender...')
sock.sendto(message.encode(),address)
if protocol == 0:
print("protocol is: " + str(protocol))
elif protocol == 1:
print("protocol is: " + str(protocol))
print("write data to log file....")
f = open("log.txt","w")
f.write(message)
print('done!')
elif protocol == 2:
print("protocol is: " + str(protocol))
# sock.close()
print("exit")
sock.close()
sys.exit()
else:
print("this is not my package: \n" + "destination Ip is: " + destination + "\n my Ip is: " + myIp)
if not received:
break
my client's code that does the sending:
def send():
try:
sock.sendto(message.encode(),serverAddress)
print("message: " + message + " is sent")
finally:
print('closing socket')
sock.close()
received = sock.recvfrom(bufferSize)[0]
address = sock.recvfrom(bufferSize)[1]
The first recvfrom will do the first read. The second recvfrom will do another read. Voila: you need two reads. Instead you should do a single read:
received, address = socket.recvfrom(bufferSize)
I'm writing a Twitch bot and it will only send one message to server. When executing code below "Connected" shows up in Twitch chat, "Testing" does not.
import socket
HOST = "irc.chat.twitch.tv"
PORT = 6667
NICK = "mybot"
PASS = 'oauth:mytoken'
CHANNEL = "mychannel"
def send_message(msg):
s.send(bytes("PRIVMSG #" + CHANNEL + " :" + msg + "\r\n", "UTF-8"))
s = socket.socket()
s.connect((HOST, PORT))
s.send(bytes("PASS " + PASS + "\r\n", "UTF-8"))
s.send(bytes("NICK " + NICK + "\r\n", "UTF-8"))
s.send(bytes("JOIN #" + CHANNEL + " \r\n", "UTF-8"))
send_message("Connected")
send_message("Testing")
Where am I going wrong here. as far as i can tell this should work.
import socket, string
#some user data, change as per your taste
SERVER = 'irc.freenode.net'
PORT = 6667
NICKNAME = 'echoquote'
CHANNEL = '#python'
PASSWORD = 'nope'
import time
#open a socket to handle the connection
IRC = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#open a connection with the server
def irc_conn():
IRC.connect((SERVER, PORT))
#simple function to send data through the socket
def send_data(command):
IRC.send(command + '\n')
#join the channel
def join(channel):
send_data("JOIN %s" % channel)
#send login data (customizable)
def login(nickname, username='user', password = None, realname='Pythonist', hostname='Helena', servername='Server'):
send_data("USER %s %s %s %s" % (username, hostname, servername, realname))
send_data("NICK " + nickname)
send_data("nickserv identify %s %s\r\n" % (NICKNAME, PASSWORD))
time.sleep(3)
irc_conn()
login(NICKNAME)
join(CHANNEL)
while (1):
buffer = IRC.recv(1024)
msg = string.split(buffer)
message = ' '.join(msg[3:])
message = ''.join([x for x in message if x in string.printable])
if message:
print message + '\n'
if msg[0] == "PING": #check if server have sent ping command
send_data("PONG %s" % msg[1]) #answer with pong as per RFC 1459
if msg [1] == 'PRIVMSG' and msg[2] == NICKNAME:
filetxt = open('/tmp/msg.txt', 'a+') #open an arbitrary file to store the messages
nick_name = msg[0][:string.find(msg[0],"!")] #if a private message is sent to you catch it
message = ' '.join(msg[3:])
filetxt.write(string.lstrip(nick_name, ':') + ' -> ' + string.lstrip(message, ':') + '\n') #write to the file
filetxt.flush() #don't wait for next message, write it now!
send_data("nickserv identify %s %s\r\n" % (NICKNAME, PASSWORD))
There is no nickserv command in IRC. This is an alias in some IRC clients, and all it does is send a private message to NickServ. Read the IRC specification, and stop reinventing wheels — use an existing IRC library, eg. twisted.words, or an existing IRC bot solution.
I am trying to make my IRC bot handle multiple messages at a time, but it's not sending back messages.
Behavior: Process(target=func) is called, func() calls a function that has socket.socket().send(message) in it, but the message doesn't send. Suspect is that the socket isn't passed to the sending function.
Code:
import socket
import re
import requests
import urllib
import config # just my file of variables
import math
import time
import sys
import winsound
import string
import random
import multiprocessing
# import traceback
# CONNECTION COMMANDS
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = config.server # Server
password = config.password # Password
botnick = config.botnick # Your bots nick
adminname = config.adminname # Your IRC nickname
exitcode = config.exitcode
ircsock.settimeout(300)
def connection(host, port, password, nick, realname):
ircsock.connect((host, port))
ircsock.send(bytes("PASS " + password + "\n", "UTF-8"))
ircsock.send(bytes("USER " + botnick + " " + botnick + " " + botnick + " " + botnick + "\n", "UTF-8"))
ircsock.send(bytes("NICK " + botnick + "\n", "UTF-8"))
def ping(): # respond to server Pings.
ircsock.send(bytes("PONG :pingis\n", "UTF-8"))
print("Ponged after " + str(time.time() - last_ping) + " seconds from last ping!")
def sendmsg(msg, target): # sends messages to the target.
# it enters here, no problem
ircsock.send(bytes("PRIVMSG " + target + " :" + msg + "\n", "UTF-8")) ### At this point, when using multiprocessing, the bot fails ###
print("Sending: [" + str(msg) + "] to: " + str(target))
# MAIN
if __name__ == '__main__':
connection(server, 6667, password, botnick, botnick)
# joinchan(channel)
while 1:
# print("Connected!")
ircmsg = ircsock.recv(1024).decode("UTF-8")
ircmsg = ircmsg.strip('\n\r')
if ircmsg.find("PRIVMSG") != -1:
try:
# “:[Nick]!~[hostname]#[IP Address] PRIVMSG [channel] :[message]”
name = ircmsg.split('PRIVMSG', 1)[0].split(':')[-1].split("!")[0] # ircmsg.split('!', 1)[0][1:]
message = ircmsg.split('PRIVMSG', 1)[1].split(':', 1)[1].splitlines()[0] # .strip()[0]
me = ircmsg.split('PRIVMSG', 1)[1].split(':', 1)[0].split()[0]
# print(me)
print("name: " + name + ", message: " + message)
if len(name) < 17:
if me == botnick:
if message.find("Hi!") != -1:
process1 = multiprocessing.Process(target=sendmsg, args=("Hello!", name))
process1.daemon = True
process1.start()
if name.lower() == adminname.lower() and message.rstrip() == exitcode:
sendmsg("Bot is quitting.", name)
ircsock.send(bytes("QUIT \n", "UTF-8"))
sys.exit()
time.sleep(1)
except:
pass
elif ircmsg.find("PING") != -1:
ping()
Please word your answers as simply as possible, since I am not that experienced in Python. The code above can be run with a correct config.py file.
Format:
password = "" # password to open the server
exitcode = "" # What is typed to stop the bot
server = "" # Server
botnick = "" # Your bots nick
adminname = "" # Your IRC nickname
I wrote a simple Python twitch bot following a video tutorial, but the tutorial didn't include whisper functionality. It can currently connect to the chat of the channel I specify, but when I try to have it send a whisper nothing happens. Here's the relevant code bits:
import socket
def openSocket():
s = socket.socket()
s.connect((HOST, PORT))
message = "PASS " + PASS + "\r\n"
s.send(message.encode('utf-8'))
message = "NICK " + USER + "\r\n"
s.send(message.encode('utf-8'))
message = "JOIN #" + CHAN + "\r\n"
s.send(message.encode('utf-8'))
return s
def sendMessage(s, message):
messageTemp = "PRIVMSG #" + CHAN + " :" + message + "\r\n"
s.send(messageTemp.encode('utf-8'))
print("Sent:" + messageTemp)
def sendWhisper(s, user, message):
messageTemp = "PRIVMSG #jtv :/w " + user + " " + message
s.send(messageTemp.encode('utf-8'))
import string
from Socket import sendMessage
def joinRoom(s):
readbuffer = ""
Loading = True
while Loading:
readbuffer = readbuffer + s.recv(1024).decode()
temp = readbuffer.split('\n')
readbuffer = temp.pop()
for line in temp:
print(line)
Loading = loadingComplete(line)
def loadingComplete(line):
if("End of /NAMES list" in line):
return False;
else: return True
I've been reading a little bit about connecting to some sort of group chat in order to make this work, but I'm confused and haven't found what I'm looking for. It seems like it should be an easy fix. Any help is appreciated.
You were very close. Where you messed up is there should not be a # in front of jtv:
def sendWhisper(s, user, message):
messageTemp = "PRIVMSG jtv :/w " + user + " " + message
s.send(messageTemp.encode('utf-8'))