LPgenerator/mattermost_bot

Mattermost changed their api

Closed this issue · 10 comments

Just upgraded from mattermost 3.4 to 3.5 (team version) and they seem to have changed their api again.

Channel id has moved from msg['channel_id'] to msg['data']['post']['channel_id']. Not sure if there any other breakages. There very well could be, this is just the first one I hit. user_id seems to be the same.

Looks like they've switched at least one endpoint too. api/v3/users/profiles/{team_id}.

Thought it would be a more trivial fix than it seems to be, only given it a quick surface glance though...

PR?

I changed some stuff but I still get an error (a route that changed/got removed I think)

{'status_code': 404, 'id': 'api.context.404.app_error', 'detailed_error': "There doesn't appear to be an api call for the url='/api/v3/users/profiles/8ekt3esjwibi3p89rmzybn88ar'. Typo? are you missing a team_id or user_id as part of the url?", 'message': 'Sorry, we could not find the page.'}

I quickly looked at the 3.5 changelog but I don't know what route should be used instead...

Yeah I don't think they replaced it with an endpoint returning precisely the same data.

I think this was the new endpoint to use.

I'm planning to take a look tomorrow if I get the chance.

I think:

https://github.com/LPgenerator/mattermost_bot/blob/master/mattermost_bot/mattermost.py#L85

to

return self.get('/teams/%s/users/0/100' % self.team_id)

Although now it's paginated too.

Don't have access to mattermost 3.5 atm to check, so can't be sure.

^ This fixes most stuff but I still get problems when the bot checks if a post if from itself. i.e if the boy listen_to "haha" and replies "haha" it will be stuck in an infinite loop of him replying "haha"...

Thanks for the updates.

I'm not very good in python, but I managed to fix it locally by changing the messages function (plus applying the changes from @thorlock12).

    def messages(self, ignore_own_msg=False, filter_action=None):
        if not self.connect_websocket():
            return
        while True:
            data = self.websocket.recv()
            if data:
                try:
                    post = json.loads(data)
                    if filter_action and post.get('event') != filter_action:
                        continue
                    if ignore_own_msg is True and json.loads((post.get("data")['post'])).get("user_id"):
                        if self.user["id"] == json.loads((post.get("data")['post'])).get("user_id"):
                            continue
                    if post.get('props', {}).get('post'):
                        post['props']['post'] = json.loads(
                            post['props']['post'])
                    yield post
                except ValueError:
                    pass

Because of there is double quotes instead of single quotes, post['data']['post'] content is string instead of dict, so you need to do

json.loads((post.get("data")['post'])).get("user_id")

to parse content :(
In msg at dispatcher.py, there is single quotes in whole response

Can you copy the response you mean, I'm unsure what exactly you mean. I would have thought mattermost would use JSON properly, rather than force that sort of weirdness. (It will be a problem for any JSON parser at the end of the day, including their own).

Although if I am following you correctly then I think single quotes would just be an error instead(ValueError: No JSON Object could be decoded, I think), so the problem isn't the type of quotes but more that it's quoted at all? Single quotes in JSON need to be inside double quotes.

When I gave it a test I managed to receive messages fine, without the additional json.loads. Which is strange.

msg typically looks like:

{'data': {'post': {'original_id': '', 'props': {}, 'pending_post_id': 'z4pmdiu48i8djeecnuryg53j9o:1479933422457', 'hashtags': '', 'parent_id': '', 'message': 'commit', 'id': 'ytxu4eu1xt8ftx98x7xfygkiww', 'user_id': 'z4pmdiu48i8djeecnuryg53j9o', 'update_at': 1479933422765, 'delete_at': 0, 'channel_id': '7mk5gsfqnpb1bd5pfz3wwod59y', 'create_at': 1479933422765, 'type': '', 'root_id': ''}, 'channel_type': 'D', 'sender_name': 'vortex', 'channel_display_name': '', 'mentions': ['8yqtosdusfg5umsa88ycoq3zih'], 'team_id': 'krq1en963jfo3jk8sfz3bakxdh'}, 'broadcast': {'omit_users': None, 'team_id': '', 'channel_id': '7mk5gsfqnpb1bd5pfz3wwod59y', 'user_id': ''}, 'event': 'posted'}

post:

{'event': 'posted', 'broadcast': {'user_id': '', 'channel_id': '7mk5gsfqnpb1bd5pfz3wwod59y', 'team_id': '', 'omit_users': None}, 'data': {'post': '{"id":"zfk968u93irofnrjbfs85wcqoy","create_at":1479933691410,"update_at":1479933691410,"delete_at":0,"user_id":"8yqtosdusfg5umsa88ycoq3zih","channel_id":"7mk5gsfqnpb1bd5pfz3wwod59y","root_id":"","parent_id":"","original_id":"","message":"Bad command \\"c\\u0026p fail\\", You can ask me one of the following questions:\\n\\n`^busy|jobs$` Show num of busy workers\\n`hello$` \\n`^\\\\!info$` \\n`hello_formatting` \\n`sleep (.*)` Sleep time\\n`^admin$` \\n`^\\\\!help$` \\n`ping` Send pong\\n`hello_decorators` \\n`hello_web_api` \\n`commit` suggest a commit message","type":"","props":{},"hashtags":"","pending_post_id":"8yqtosdusfg5umsa88ycoq3zih:1479933691242"}', 'team_id': 'krq1en963jfo3jk8sfz3bakxdh', 'channel_type': 'D', 'sender_name': 'mmhook.admin', 'channel_display_name': '', 'mentions': '["z4pmdiu48i8djeecnuryg53j9o"]'}}

UPD:
sorry, that's because

{'post': '{"id":"zfk968u93irofnrjbfs85wcqoy","create_at":1479933691410,"update_at":1479933691410,"delete_at":0,"user_id":"8yqtosdusfg5umsa88ycoq3zih","channel_id":"7mk5gsfqnpb1bd5pfz3wwod59y","root_id":"","parent_id":"","original_id":"","messa

It is a string inside post['data']['post']
It must be something like:

{'post': {"id":"zfk968u93irofnrjbfs85wcqoy","create_at":1479933691410,"update_at":1479933691410,"delete_at":0,"user_id":"8yqtosdusfg5umsa88ycoq3zih","channel_id":"7mk5gsfqnpb1bd5pfz3wwod59y","root_id":"","parent_id":"","original_id":"","messa

New version now is available at PyPi. Can you check please.

Many thanks. It works now.