maxux / python-rocketchat-bot

rocket.chat python basic bot
Apache License 2.0
29 stars 18 forks source link

some items might be deprecated #2

Open dfpena opened 7 years ago

dfpena commented 7 years ago

self.client.subscribe('stream-messages', [], self.cb1)

'stream-messages' might be deprecated

looked through the hubot for what it might be now https://github.com/RocketChat/hubot-rocketchat/blob/master/src/rocketchat_driver.coffee

seems like they use 'stream-room-messages' with a room id parameter after they determine all rooms the bot is logged into.

def callback_function(error, result):
    if error:
        print(error)
        return
    for i in result:
        print(i)
    return result

client.call("subscriptions/get", [], callback_function)

will give the subscriptions and the room ids

self.client.subscribe('stream-messages', [room id], self.cb1)

will get the messages in that room

WELLL ALMOST.... THERE IS AN UPSTREAM ISSUE with the meteor client as the first call of the subscription will normally be empty so you will get a key error.

I edited:

MeteorClient.py in sites-packages:

class CollectionData(object):
    def __init__(self):
        self.data = {}

    def add_data(self, collection, id, fields):
        if collection not in self.data:
            self.data[collection] = {}
        if not id in self.data[collection]:
            self.data[collection][id] = {}
        for key, value in fields.items():
            self.data[collection][id][key] = value

    def change_data(self, collection, id, fields, cleared):
        try:
            for key, value in fields.items():
                self.data[collection][id][key] = value

            for key in cleared:
                del self.data[collection][id][key]
        except KeyError:
            self.add_data(collection,id,fields)

    def remove_data(self, collection, id):
        del self.data[collection][id]

probably not the way you should do that but...

Then I had to comment out from the same file

#  if name in self.subscriptions:
#      raise MeteorClientException('Already subcribed to {}'.format(name))

After all of that.... here is what ended up working... someone should make all of the non hackerish corrections

from MeteorClient import MeteorClient
import time

class RocketChatBot():
    def __init__(self, user, password, server='demo.rocket.chat'):
        self.username = user
        self.password = password
        self.server = server
        self.debug = True

        self._prefixs = []

        self.client = client = MeteorClient('wss://'+server+'/websocket')

        # registering internal handlers
        self.client.on('connected', self._connected)
        self.client.on('closed', self._closed)
        self.client.on('logging_in', self._logging_in)
        self.client.on('failed', self._failed)
        self.client.on('added', self._added)
        self.client.on('changed', self._changed)
        self.client.on('unsubscribed', self._unsubscribed)
        self.client.on('subscribed', self._subscribed)

    """
    Internal events handlers
    """
    def _connected(self):
        self.client.call("subscriptions/get", [], callback=self.cb2)
        #print("[+] rocketchat: connected")
        #self.client.subscribe("stream-room-messages",[], callback=self.cb1)

    def _closed(self, code, reason):
        print('[-] rocketchat: connection closed: %s (%d)' % (reason, code))

    def _logging_in(self):
        print('[+] rocketchat: logging in')

    def _failed(self, collection, data):
        print('[-] %s' % str(data))

    def _added(self, collection, id, fields):
        print('[+] %s: %s' % (collection, id))

        if not fields.get('args'):
            return

        args = fields['args']

        if args[0] == "GENERAL":
            print("[+] message: general, skipping")
            return

        if args[1].get('msg'):
            return self._incoming(args[1])

        if args[1].get('attachments'):
            return self._downloading(args[1])

        print(args)
        print(args[0])
        print(args[1])

        # for key, value in fields.items():
        #    print('[+]  %s: %s' % (key, value))

    def _changed(self, collection, id, fields, cleared):
        print('[+] changed: %s %s' % (collection, id))

        for key, value in fields.items():
            print('[+]  field %s: %s' % (key, value))

        for key, value in cleared.items():
            print('[+]  cleared %s: %s' % (key, value))
        args = fields['args'][0]

        if args.get('msg'):
            return self._incoming(args)

        if args.get('attachments'):
            return self._downloading(args)

    def _subscribed(self, subscription):
        print('[+] subscribed: %s' % subscription)

    def _unsubscribed(self, subscription):
        print('[+] unsubscribed: %s' % subscription)

    """
    Internal callback handlers
    """
    def cb(self, error, data):
        if not error:
            if self.debug:
                print(data)

            return

        print('[-] callback error:')
        print(error)

    def cb1(self, data):
        print(data)
        if not self.debug:
            return

        if(data):
            print(data)

        else:
            print("[+] callback success")

    def cb2(self,error, result):
        if error:
            print(error)
            return
        rids = []
        time.sleep(3)

        for i in result:
            rid =i['rid']
            print("[+] rocketchat: connected" , rid)
            self.client.subscribe("stream-room-messages",[rid], callback=self.cb1)
        return result
    """
    Internal dispatcher
    """
    def _incoming(self, data):
        print("[+] Message from %s: %s" % (data['alias'], data['msg']))

        for prefix in self._prefixs:
            if data['msg'].startswith(prefix['prefix']):
                prefix['handler'](self, data)

    def _downloading(self, data):
        print("[+] attachement from %s: %d files" % (data['u']['username'], len(data['attachments'])))

    """
    Public initializers
    """
    def start(self):
        self.client.connect()
        self.client.login(self.username, self.password.encode('utf-8'), callback=self.cb)

        # let's yeld to background task
        while True:
            time.sleep(3600)

    def addPrefixHandler(self, prefix, handler):
        self._prefixs.append({'prefix': prefix, 'handler': handler})

    def sendMessage(self, id, message):
        self.client.call('sendMessage', [{'msg': message, 'rid': id}], self.cb)
maxux commented 6 years ago

Hello, thanks for your interest and sorry for the long reply. I'll inspect a little bit what happen, this was mostly a PoC, sorry. If you found any cool solution since, feel free to make a pull request :)