So I made a Twitch.tv bot for my own channel, after having fun with it a little bit, I wanted to have some command restricted to some users, and some commands that can say the users name, for example:
Username reply example:
Person1: !tea
PythonBot: Would you like some tea, Person1?
Admin restriction example:
Person1: !ban Person2
PythonBot: I'm sorry, Person1, This command is restricted to admins only.
Ok, So here is the code I'm using (I will be modifying it soon to make it my own)
import socket
import threading
bot_owner = '~Not Today~'
nick = '~Not Today~'
channel = '~Not Today~'
server = 'irc.twitch.tv'
password = '~Not Today~'
queue = 13
irc = socket.socket()
irc.connect((server, 6667))
irc.send('PASS ' + password + '\r\n')
irc.send('USER ' + nick + ' 0 * :' + bot_owner + '\r\n')
irc.send('NICK ' + nick + '\r\n')
irc.send('JOIN ' + channel + '\r\n')
def message(msg):
global queue
queue = 5
if queue < 20:
irc.send('PRIVMSG' + channel + ' :' + msg + '\r\n')
else:
print 'Message Deleted'
def queuetimer():
global queue
queue = 0
threading.Timer(30,queuetimer).start()
queuetimer()
while True:
botdata = irc.recv(1204)
botuser = botdata.split(':')[1]
botuser = botuser.split('!')[0]
print botdata
if botdata.find('PING') != -1:
irc.send(botdata.replace('PING', 'PONG'))
if botdata.find('!res') != -1:
irc.send(botdata.replace('!res', '1600x900'))
The twitch IRC raw message is like
:jkm!jkm#jkm.tmi.twitch.tv PRIVMSG #trumpsc :needs Kappa
for above msg, it actually means userjkm at channel trumpsc saying needs Kappa
for your code, the method to get botuser is right, but you don't have the message the user sent, add following code should get the message
botmsg = botdata.split(':')[2]
so you get the message and username, the next step would be handling them.
Here would be some example for your need. For me, I will prepared a adminuserList and commmandList for other command, but I will simplify it here.
def commmanHandler(botuser, botmsg): # botmsg = '!ban user1'
command = botmsg.split(' ')[0] # command = '!ban'
command = command[1:] # command = 'ban'
argu = message.split(' ')[1] # argu = 'user1'
if command not in commmandList:
raise Exception("command not support")
if command == 'ban': # ban command, or using switch
# check if admin
if botuser not in adminList:
raise Exception("I'm sorry, " + botuser + ", This command is restricted to admins only.")
# admin, able to ban
irc.send('PRIVMSG' + channel + ' :' + '.ban ' + argu)
then call this function in your while loop to handle all message you get
try:
commmanHandler(botuser, botmsg)
except Exception, e:
print e
irc.send('PRIVMSG' + channel + ' :' + e)
here would be my solution, and also, don't forget to give the bot moderator privilege.
Related
I am coding an assignment and got the code to successfully send an email to my email address. How can I correctly use a loop to ask the user if they want to send another email or quit. You can see how I attempted this but it doesn't seem to work. Additionally, How do I make it ask them to log into their outlook account and/or ask them the email address of the recipient?
Many thanks for taking time to read
This is the code:
from socket import *
import ssl
import base64
# Some global variables
SMTP_MAIL_SERVER = 'smtp-mail.outlook.com'
SMTP_TLS_PORT = 587
END_MESSAGE = '\r\n.\r\n'
client_socket = None
ssl_context = None
def send_line(line):
global client_socket
print('CLIENT: ' + line.strip())
client_socket.send(line.encode())
response = client_socket.recv(1024).decode()
return response
def get_code(response):
return int(response[:3])
def connect():
global client_socket
global ssl_context
print('CLIENT: Connecting to ' + SMTP_MAIL_SERVER)
client_socket = socket(AF_INET, SOCK_STREAM)
client_socket.connect((SMTP_MAIL_SERVER, SMTP_TLS_PORT))
response = client_socket.recv(1024).decode()
return response
def send_ehlo():
helo = 'ehlo smtp-mail.outlook.com\r\n'
return send_line(helo)
def send_helo():
helo = 'helo smtp-mail.outlook.com\r\n'
return send_line(helo)
def start_tls():
global client_socket
global ssl_context
response = send_line('STARTTLS \r\n')
ssl_context = ssl._create_stdlib_context()
client_socket = ssl_context.wrap_socket(client_socket, server_hostname=SMTP_MAIL_SERVER)
return response
def send_auth_request():
return send_line('auth login \r\n')
def send_username(username):
as_bytes = username.encode('ascii')
as_b64 = base64.b64encode(as_bytes)
as_utf8 = as_b64.decode('utf-8')
return send_line(as_utf8 + '\r\n')
def send_password(password):
as_bytes = password.encode('ascii')
as_b64 = base64.b64encode(as_bytes)
as_utf8 = as_b64.decode('utf-8')
return send_line(as_utf8 + '\r\n')
'''--------------------------------------------------------------------------------
TODO - Implement the functions below this point in order to send a test
email successfully using SMTP commands
--------------------------------------------------------------------------------'''
def send_mail_from(sender):
mail_from = 'MAIL FROM: <' + sender + '>\r\n'
return send_line(mail_from)
def send_rcpt_to(recipient):
rcpt_to = 'RCPT TO: <' + recipient + '>\r\n'
return send_line(rcpt_to)
def send_begin_data():
return send_line('DATA \r\n')
def send_message(subject, message):
subject_line = 'Subject: ' + subject + '\r\n'
body = '\nMessage:' + message + '\r\n'
return send_line(subject_line + body + END_MESSAGE)
def send_quit():
return send_line('QUIT \r\n')
'''--------------------------------------------------------------------------------
TODO - Implement the functions above this point in order to send a test
email successfully using SMTP commands
--------------------------------------------------------------------------------'''
send_email_question = 1
while send_email_question == 1:
def send_one_email():
# Open a TCP connection - the reply should start '220'
reply = connect()
print('SERVER: ' + reply)
# Send a EHLO command - the reply should be a list of supported
# 'enhanced' SMTP functions each starting '250'
reply = send_ehlo()
print('SERVER: ' + reply)
# Ask the server to switch to TLS - reply should start '220'
reply = start_tls()
print('SERVER: ' + reply)
# Send a HELO command encrypted - reply should start '220'
reply = send_helo()
print('SERVER: ' + reply)
# Send an AUTH LOGIN command
reply = send_auth_request()
print('SERVER: ' + reply)
# Send your (base64 encoded username) -
reply = send_username('#sending email username')
print('SERVER: ' + reply)
# Send your (base64 encoded username) -
reply = send_password('#sending email password')
print('SERVER: ' + reply)
# Send MAILFROM command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_mail_from('#sending email') #sending email
print('SERVER: ' + reply)
# Send RCPT TO command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply=send_rcpt_to('#target email') #target email
print('SERVER: ' + reply)
# Send DATA command - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_begin_data()
print('SERVER: ' + reply)
# Send the message (including subject) - TODO - YOU IMPLEMENT THE FUNCTION BELOW
reply = send_message(subject='Nothing much', message='Hello World')
print('SERVER: ' + reply)
# Quit the SMTP session - TODO - YOU IMPLEMENT THE FUNCTION BELOW
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
if __name__ == '__main__':
send_one_email()
When doing :
send_email_question = 1
while send_email_question == 1:
def send_one_email():
# ... [snip lots of send/reply]
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
if __name__ == '__main__':
send_one_email()
you are entering the loop, which creates a function (one def instruction). Then in the if __name__ you call one time the function which was created.
Instead, you should do :
def send_one_email():
# ... [snip lots of send/reply]
if __name__ == '__main__':
send_email_question = 1
while send_email_question == 1:
send_one_email()
user_end_question = int(input("Please enter 1 if you would like to send another email 0 to end connection: "))
if user_end_question == 0:
reply = send_quit()
print('SERVER: ' + reply)
which is creating the function (only once), then in a loop sending an email and asking whether to quit. This way, the send_one_email just sends one email, and do nothing else. And your "main" part decides how many times to call it.
99% of the time, you don't want to create functions (def) inside loops.
So I have written a little bot that connects to twitch and is suppose to stay active till I close the script, but it seems after a elongated period of time the bot stops being connected to twitch and stops receiving anything. I think it is disconnecting, but I have no proof. Just the fact that it doesn't do anything after a while.
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
irc.connect((server, port))
irc.send("PASS " + password + "\n")
irc.send("NICK " + name + "\n")
irc.send("JOIN " + channel + "\n")
def main():
while True:
data = irc.recv(1204)
data = data.strip('\r\n')
sendUsr = data.split(" ")
sendUsr = sendUsr[0]
sendUsr = sendUsr.split("!")
sendUsr = sendUsr[0]
sendUsr = sendUsr.strip(":")
print (data)
if data.find('PING') != -1 :
irc.send("PONG")
if data.find('PING') != -1 :
irc.send("PONG")
Needs to be changed to:
if data.find('PING')
irc.send("PONG :tmi.twitch.tv")
Try doing that & it should work.
I have been working on a TwitchTV Python chat bot for a while now, but I'm still getting to grips with Python.
It may seem simple, but this has confused me so I decided I would ask:
I'm currently pulling messages from Twitch Chat using data = irc.recv
What I want to do is use the data pulled and turn it into a string, so that I can then check for capitals in the messages using str.isupper()
I've already tried a few ways;
data = irc.recv (4096)
msg = data()
capsTime = "30s"
str = msg
if str.isupper():
message("[-] Woah! Hold back on the caps! (Timeout " + capsTime + ")")
message("/timeout " + user + capsTime)
# variable "user" already defined
This is just one, that unfortunately didn't work.
EDIT:
This is my new code, It runs without error messages, but It doesn't function as I want it to;
while True:
data = irc.recv (4096)
user = data.split(':')[1]
user = user.split('!')[0]
caps = data.split(':')[0]
capsmsg = str(data)
print data
if data.find('PING') != -1:
irc.send('PONG ' + data.split()[1] + '\r\n')
if capsmsg.isupper():
message("[-] Woah! Hold back on the caps, " + user + "! (Timeout 30s)")
message("/timeout " + user + " 30s")
EDIT 2:
Expected output:
If a message is found in ALL caps, it will print this message and time the user out:
message("[-] Woah! Hold back on the caps, " + user + "! (Timeout 30s)")
Current output:
The bot does not pick the message up or run the scripted code.
Try this:
data = irc.recv (4096)
# msg = data()
capsTime = "30s"
mystr = repr(data)
if mystr.isupper():
message("[-] Woah! Hold back on the caps! (Timeout " + capsTime + ")")
message("/timeout " + user + capsTime)
# variable "user" already defined
Don't use reserved keyword.
I wrote a simple "POP3S to Secure SMTP over TLS" MRA script in Python (see below).
It works fine, but sometimes it returns "Connection unexpectedly closed" while trying to send via SMTP. Running the script again will deliver that message successfully.
Please give me some suggestions why it would fail to deliver a message sometimes but at the next run it delivers exactly this message successfully!?
#! /usr/bin/env python
import poplib
import email
def forward_pop3_smtp( smtp_credentials, pop3_credentials, forward_address):
pop3_server = pop3_credentials[0]
pop3_port = pop3_credentials[1]
pop3_user = pop3_credentials[2]
pop3_password = pop3_credentials[3]
message_recipient = forward_address
server = poplib.POP3_SSL( pop3_server, pop3_port)
server.user( pop3_user)
server.pass_( pop3_password)
for messages_iterator in range( len( server.list()[1])):
message_list = server.retr( messages_iterator + 1)[1]
message_string = ''
for message_line in message_list:
message_string += message_line + '\n'
message_message = email.message_from_string( message_string)
message_message_as_string = message_message.as_string()
message_sender = message_message[ 'From']
print( 'message_sender = ' + message_sender)
smtp_return = send_smtp( smtp_credentials, message_sender, message_recipient, message_message_as_string)
print( 'smtp_return = ' + str(smtp_return))
if smtp_return == 0:
print( 'Deleting message ' + message_message[ 'Subject'] + ':\n')
return_delete = server.dele( messages_iterator + 1)
print( 'return_delete = \n' + str(return_delete))
print( '\n')
server.quit()
def send_smtp( smtp_credentials, message_sender, message_recipient, message_message_as_string):
smtp_server = smtp_credentials[0]
smtp_port = smtp_credentials[1]
smtp_user = smtp_credentials[2]
smtp_password = smtp_credentials[3]
import smtplib
exception = 0
try:
server = smtplib.SMTP( smtp_server)
server.starttls()
server.login( smtp_user, smtp_password)
smtp_sendmail_return = server.sendmail( message_sender, message_recipient, message_message_as_string)
server.quit()
except Exception, e:
exception = 'SMTP Exception:\n' + str( e) + '\n' + str( smtp_sendmail_return)
return exception
if __name__ == '__main_':
print( 'This module needs to be imported!\n')
quit()
Use Port 587 for TLS. I don't see the script use smtp_port
Use like,
server = smtplib.SMTP( smtp_server, int(smtp_port)
For Secure SMTP (SMTP + SSL), use smtplib.SMTP_SSL
i been trying to code an IRC bot, while i have succeed. I am having problems implementing something i want to do. the code works fine, but i have issues in the following:
since the bot uses a While loop to read commands from the IRC when i add a second While with a time.sleep(seconds) the bot does not connect because it reads my second loop and pauses the connection not in time to response the :PING do it disconnects. i been searching but the mor ei search the more confused i get because i don't know what should i try.
stackless, multithreads, subprocess. there are so many results that i just get more confused. so what would be the best method i am trying an RSS bot the bot works fine if i use the command !rss in the IRC channel but i need it to check for new ones ever 10 minutes and if use a sleep command the main loop messes up.
here is my code:
#!/usr/bin/python
import socket, sys, string, time, feedparser, hashlib
port = 6667
nick = "RSSbot"
host = 'irc.server.com'
name = "RSSBOT"
channel = '#debug'
ident = 'rssbot'
irc = socket.socket()
irc.connect ( (host, port) )
irc.send ( 'NICK ' + nick + '\r\n' )
irc.send ( 'USER ' + ident + ' ' + ident + ' ' + ident + ' :rssbot\r\n' )
def readRss():
feedurl = feedparser.parse("http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=username")
newest = feedurl['items'][0].title
newest = newest.replace("username:","")
msg = newest.split("http://")
title = msg[0]
url = msg[1]
url = "http://" + url
e = feedurl.entries[2]
threadurl = e.link
id = hashlib.md5(url + title).hexdigest()
irc.send ("PRIVMSG #debug :Tittle:%s\r\n" % newest)
irc.send ("PRIVMSG #debug :URL: %s\r\n" % url)
irc.send ("PRIVMSG #debug :MD5: %s\r\n" % id)
while 1:
data = irc.recv ( 1024 )
print(data)
if data.find ( '376' ) != -1:
irc.send( 'JOIN ' + channel + '\r\n' )
if data.find ( 'PING' ) != -1:
irc.send( 'PONG ' + data.split() [1] + '\r\n')
if data.find ( '!rss' ) != -1:
feedurl = feedparser.parse("http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=username")
newest = feedurl['items'][0].title
newest = newest.replace("username:","")
msg = newest.split("http://")
title = msg[0]
url = msg[1]
url = "http://" + url
#e = feedurl.entries[2]
#threadurl = e.link
id = hashlib.md5(url + title).hexdigest()
irc.send ("PRIVMSG #debug :Tittle:%s\r\n" % newest)
irc.send ("PRIVMSG #debug :URL: %s\r\n" % url)
irc.send ("PRIVMSG #debug :MD5: %s\r\n" % id)
while true:
readRss()
time.sleep(300)
if i add a while :true inside the while 1: with a time.sleep(300) the sleep command conflicts with the while 1: loop which i need to do something similar so i could check for new feeds every x minutes. what could i do?
Instead of a new loop, use a separate timer.
import time
last_update = time.time()
while 1:
# the rest of your while loop as usual
now = time.time()
if now - last_update > 300:
# you've waited 300 seconds
# check feeds or whatever
last_update = now
I handled that with threading module on my irc bot check the project this may help you https://github.com/mouuff/MouBot (I called the fonction ircloop this will answer server pings and do botting stuff :)