Skip to content

Commit

Permalink
Update to the latest mattermostdriver and refactor api calls
Browse files Browse the repository at this point in the history
Major version bump because the dependencies are updated and plugins
may have a problem with that.
  • Loading branch information
Vaelor committed Nov 26, 2017
1 parent 7d877fe commit 81bae25
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 48 deletions.
30 changes: 11 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
# Errbot Backend for Mattermost

## APIv4 Support
The master branch is now set to use the new APIv4 for mattermost.
Some things have changed, please see the updated requirements and
changed BOT_IDENTITY parameters.

- 'email' is now 'login'
- 'server' is the url without https:// or the port. Port and scheme have their own option now.
- You need to `pip install mattermostdriver`

### APIv3
Use the APIv3 branch for that.

**Attention**: The `BOT_IDENTITY` config options have changed!

### KNOWN (POSSIBLE) ISSUES

- Channelmentions in messages aren't accounted for (Unsure if they need to be)

### REQUIREMENTS
- Mattermost with APIv4
- Python >= 3.4
- websockets 3.2
- [mattermostdriver](https://github.com/Vaelor/python-mattermost-driver) > 2.2.0
- [mattermostdriver](https://github.com/Vaelor/python-mattermost-driver) > 4.0

### INSTALLATION

Expand Down Expand Up @@ -63,6 +46,15 @@ and add the webhook id to your errbot `config.py` in `BOT_IDENTITY`.
This is not an ideal solution, but AFAIK Mattermost does not support sending attachments
over the api like slack does.

### APIv3
Use the APIv3 branch for that. It is no longer supported and not guaranteed to work!

**Attention**: The `BOT_IDENTITY` config options are different for V3 and V4!

### KNOWN (POSSIBLE) ISSUES

- Channelmentions in messages aren't accounted for (Unsure if they need to be)

### FAQ

##### The Bot does not answer my direct messages
Expand Down
2 changes: 1 addition & 1 deletion mattermost.plug
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ Module = mattermost
[Documentation]
Description = A Mattermost backend for errbot.
Author = Christian Plümer
Version = 1.2.1
Version = 2.0.0
Website = https://github.com/Vaelor/errbot-mattermost-backend
20 changes: 10 additions & 10 deletions mattermost.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def mode(self):
def username_to_userid(self, name):
"""Converts a name prefixed with @ to the userid"""
name = name.lstrip('@')
user = self.driver.api['users'].get_user_by_username(username=name)
user = self.driver.users.get_user_by_username(username=name)
if user is None:
raise UserDoesNotExistError("Cannot find user {}".format(name))
return user['id']
Expand Down Expand Up @@ -233,7 +233,7 @@ def get_direct_channel(self, userid, other_user_id):
If it does not exist, it will be created.
"""
try:
return self.driver.api['channels'].create_direct_message_channel(options=[userid, other_user_id])
return self.driver.channels.create_direct_message_channel(options=[userid, other_user_id])
except (InvalidOrMissingParameters, NotEnoughPermissions):
raise RoomDoesNotExistError("Could not find Direct Channel for users with ID {} and {}".format(
userid, other_user_id
Expand Down Expand Up @@ -298,8 +298,8 @@ def serve_once(self):
})
self.driver.login()

self.teamid = self.driver.api['teams'].get_team_by_name(name=self.team)['id']
userid = self.driver.api['users'].get_user(user_id='me')['id']
self.teamid = self.driver.teams.get_team_by_name(name=self.team)['id']
userid = self.driver.users.get_user(user_id='me')['id']

self.token = self.driver.client.token

Expand Down Expand Up @@ -353,7 +353,7 @@ def send_message(self, message):
parts = self.prepare_message_body(body, limit)

for part in parts:
self.driver.api['posts'].create_post(options={
self.driver.posts.create_post(options={
'channel_id': to_channel_id,
'message': part,
})
Expand Down Expand Up @@ -401,7 +401,7 @@ def send_card(self, card: Card):
# We need to send a webhook - mattermost has no api endpoint for attachments/cards
# For this reason, we need to build our own url, since we need /hooks and not /api/v4
# Todo: Reminder to check if this is still the case
self.driver.api['webhooks'].call_webhook(self.cards_hook, options=data)
self.driver.webhooks.call_webhook(self.cards_hook, options=data)
except (
InvalidOrMissingParameters,
NotEnoughPermissions,
Expand Down Expand Up @@ -476,7 +476,7 @@ def get_public_channels(self):
page = 0
channel_page_limit = 200
while True:
channel_list = self.driver.api['channels'].get_public_channels(
channel_list = self.driver.channels.get_public_channels(
team_id=self.teamid,
params={'page': page, 'per_page': channel_page_limit}
)
Expand All @@ -489,7 +489,7 @@ def get_public_channels(self):

def channels(self, joined_only=False):
channels = []
channels.extend(self.driver.api['channels'].get_channels_for_user(user_id=self.userid, team_id=self.teamid))
channels.extend(self.driver.channels.get_channels_for_user(user_id=self.userid, team_id=self.teamid))
if not joined_only:
public_channels = self.get_public_channels()
for channel in public_channels:
Expand All @@ -505,7 +505,7 @@ def rooms(self):

def channelid_to_channelname(self, channelid):
"""Convert the channelid in the current team to the channel name"""
channel = self.driver.api['channels'].get_channel(channel_id=channelid)
channel = self.driver.channels.get_channel(channel_id=channelid)
if 'name' not in channel:
raise RoomDoesNotExistError("No channel with ID {} exists in team with ID {}".format(
id, self.teamid
Expand All @@ -514,7 +514,7 @@ def channelid_to_channelname(self, channelid):

def channelname_to_channelid(self, name):
"""Convert the channelname in the current team to the channel id"""
channel = self.driver.api['channels'].get_channel_by_name(team_id=self.teamid, channel_name=name)
channel = self.driver.channels.get_channel_by_name(team_id=self.teamid, channel_name=name)
if 'id' not in channel:
raise RoomDoesNotExistError("No channel with name {} exists in team with ID {}".format(
name, self.teamid
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mattermostdriver>=2.3
mattermostdriver>=4.0
4 changes: 2 additions & 2 deletions src/mattermostPerson.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def userid(self) -> str:

@property
def username(self) -> str:
user = self._driver.api['users'].get_user(user_id=self.userid)
user = self._driver.users.get_user(user_id=self.userid)
if 'username' not in user:
log.error("Can't find username for user with ID {}".format(self._userid))
return "<{}>".format(self._userid)
Expand Down Expand Up @@ -48,7 +48,7 @@ def domain(self) -> str:

@property
def fullname(self):
user = self._driver.api['users'].get_user(user_id=self.userid)
user = self._driver.users.get_user(user_id=self.userid)
if 'first_name' not in user and 'last_name' not in user:
log.error("No first or last name for user with ID {}".format(self._userid))
return "<{}>".format(self._userid)
Expand Down
30 changes: 15 additions & 15 deletions src/mattermostRoom.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def id(self):

@property
def _channel(self):
channel = self.driver.api['channels'].get_channel_by_name(team_id=self.teamid, channel_name=self.name)
channel = self.driver.channels.get_channel_by_name(team_id=self.teamid, channel_name=self.name)
if 'status_code' in channel and channel['status_code'] != 200:
raise RoomDoesNotExistError("{}: {}".format(channel['status_code'], channel['message']))
return channel
Expand All @@ -60,7 +60,7 @@ def private(self):
@property
def exists(self):
channels = []
channels.extend(self.driver.api['channels'].get_channels_for_user(user_id='me', team_id=self.teamid))
channels.extend(self.driver.channels.get_channels_for_user(user_id='me', team_id=self.teamid))
public_channels = self._bot.get_public_channels()
for channel in public_channels:
if channel not in channels:
Expand All @@ -69,7 +69,7 @@ def exists(self):

@property
def joined(self):
channels = self.driver.api['channels'].get_channels_for_user(user_id='me', team_id=self.teamid)
channels = self.driver.channels.get_channels_for_user(user_id='me', team_id=self.teamid)
return len([c for c in channels if c['name'] == self.name]) > 0

@property
Expand All @@ -81,7 +81,7 @@ def topic(self):

@topic.setter
def topic(self, topic):
self.driver.api['channels'].update_channel(
self.driver.channels.update_channel(
channel_id=self.id,
options={'header': topic, 'id': self.id}
)
Expand All @@ -95,19 +95,19 @@ def purpose(self):

@purpose.setter
def purpose(self, purpose):
self.driver.api['channels'].update_channel(
self.driver.channels.update_channel(
channel_id=self.id,
options={'purpose': purpose, 'id': self.id}
)

@property
def occupants(self):
member_count = self.driver.api['channels'].get_channel_statistics(channel_id=self.id)['member_count']
member_count = self.driver.channels.get_channel_statistics(channel_id=self.id)['member_count']
members = {}
user_page_limit = 200
for start in range(0, member_count, user_page_limit):
members.update(
self.driver.api['channels'].get_channel_members(
self.driver.channels.get_channel_members(
channel_id=self.id,
params={'page': start, 'per_page': user_page_limit}
)
Expand All @@ -122,13 +122,13 @@ def create(self, private=False):
else:
log.info("Creating public channel {}".format(str(self)))
try:
self.driver.api['channels'].create_channel(options={
self.driver.channels.create_channel(options={
'team_id': self.teamid,
'name': self.name,
'display_name': self.name,
'type': channel_type
})
self.driver.api['channels'].get_channel_by_name(team_id=self.teamid, channel_name=self.name)
self.driver.channels.get_channel_by_name(team_id=self.teamid, channel_name=self.name)
self._bot.callback_room_joined(self)
except (NotEnoughPermissions, ResourceNotFound) as e:
raise RoomError(e)
Expand All @@ -139,7 +139,7 @@ def join(self, username: str=None, password: str=None):
self.create() # This always creates a public room!
log.info("Joining channel {}".format(str(self)))
try:
self.driver.api['channels'].add_user(
self.driver.channels.add_user(
channel_id=self._id,
options={
'user_id': self._bot.userid
Expand All @@ -152,26 +152,26 @@ def join(self, username: str=None, password: str=None):
def leave(self, reason: str=None):
log.info('Leaving channel {} ({})'.format(str(self), self.id))
try:
self.driver.api['channels'].remove_user_from_channel(channel_id=self.id, user_id=self._bot.id)
self.driver.channels.remove_user_from_channel(channel_id=self.id, user_id=self._bot.id)
self._bot.callback_room_left(self)
except (InvalidOrMissingParameters, NotEnoughPermissions) as e:
raise RoomError(e)

def destroy(self):
try:
self.driver.api['channels'].delete_channel(channel_id=self.id)
self.driver.channels.delete_channel(channel_id=self.id)
self._bot.callback_room_left(self)
except (InvalidOrMissingParameters, NotEnoughPermissions) as e:
log.debug('Could not delete the channel. Are you a member of the channel?')
raise RoomError(e)
self._id = None

def invite(self, *args):
user_count = self.driver.api['teams'].get_team_stats(team_id=self.teamid)['total_member_count']
user_count = self.driver.teams.get_team_stats(team_id=self.teamid)['total_member_count']
user_page_limit = 200
users_not_in_channel = []
for start in range(0, user_count, user_page_limit):
users_not_in_channel.extend(self.driver.api['users'].get_users(
users_not_in_channel.extend(self.driver.users.get_users(
params={
'page': start,
'per_page': user_page_limit,
Expand All @@ -188,7 +188,7 @@ def invite(self, *args):
log.info('Inviting {} into {} ({})'.format(user, str(self), self.id))

try:
self.driver.api['channels'].add_user(channel_id=self.id, options={'user_id': users[user]})
self.driver.channels.add_user(channel_id=self.id, options={'user_id': users[user]})
except (InvalidOrMissingParameters, NotEnoughPermissions):
raise RoomError("Unable to invite {} to channel {} ({})".format(
user, str(self), self.id
Expand Down

0 comments on commit 81bae25

Please sign in to comment.