Skip to content

Commit

Permalink
Make cards/attachments available
Browse files Browse the repository at this point in the history
fix #28
  • Loading branch information
Vaelor committed Oct 9, 2017
1 parent e2c946b commit 524986b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 20 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,19 @@ BOT_IDENTITY = {
'insecure': False, # Default = False. Set to true for self signed certificates
'scheme': 'https', # Default = https
'port': 8065, # Default = 8065
'timeout': 30 # Default = 30. If the webserver disconnects idle connections later/earlier change this value
'timeout': 30, # Default = 30. If the webserver disconnects idle connections later/earlier change this value
'cards_hook': 'incomingWebhookId' # Needed for cards/attachments
}
```

- If the bot has problems doing some actions, you should make it system admin, some actions won't work otherwise.

### Cards/Attachments
Cards are called attachments in Mattermost.
If you want to send attachments, you need to create an incoming Webhook in Mattermost
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.

### FAQ

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.1.0
Version = 1.2.0
Website = https://github.com/Vaelor/errbot-mattermost-backend
86 changes: 69 additions & 17 deletions mattermost.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from errbot.backends.base import (
Message, Presence, ONLINE, AWAY, UserDoesNotExistError,
RoomDoesNotExistError, RoomOccupant,
)
Card)
from errbot.core import ErrBot
from errbot.rendering import md
from errbot.utils import split_string_after
Expand All @@ -29,6 +29,15 @@
# to keep the connection alive
DEFAULT_TIMEOUT = 30

COLORS = {
'white': '#FFFFFF',
'cyan': '#00FFFF',
'blue': '#0000FF',
'red': '#FF0000',
'green': '#008000',
'yellow': '#FFA500',
}


class MattermostBackend(ErrBot):
def __init__(self, config):
Expand All @@ -41,6 +50,7 @@ def __init__(self, config):
self.team = identity.get('team')
self._scheme = identity.get('scheme', 'https')
self._port = identity.get('port', 8065)
self.cards_hook = identity.get('cards_hook', None)
self.url = identity.get('server').rstrip('/')
self.insecure = identity.get('insecure', False)
self.timeout = identity.get('timeout', DEFAULT_TIMEOUT)
Expand Down Expand Up @@ -309,25 +319,29 @@ def serve_once(self):
log.debug("Triggering disconnect callback")
self.disconnect_callback()

def send_message(self, message):
super().send_message(message)
def _prepare_message(self, message):
to_name = "<unknown>"
try:
if message.is_group:
to_channel_id = message.to.id
if message.to.name:
to_name = message.to.name
else:
self.channelid_to_channelname(channelid=to_channel_id)
if message.is_group:
to_channel_id = message.to.id
if message.to.name:
to_name = message.to.name
else:
to_name = message.to.username
self.channelid_to_channelname(channelid=to_channel_id)
else:
to_name = message.to.username

if isinstance(message.to, RoomOccupant): # private to a room occupant -> this is a divert to private !
log.debug("This is a divert to private message, sending it directly to the user.")
channel = self.get_direct_channel(self.userid, self.username_to_userid(to_name))
to_channel_id = channel['id']
else:
to_channel_id = message.to.channelid
return to_name, to_channel_id

if isinstance(message.to, RoomOccupant): # private to a room occupant -> this is a divert to private !
log.debug("This is a divert to private message, sending it directly to the user.")
channel = self.get_direct_channel(self.userid, self.username_to_userid(to_name))
to_channel_id = channel['id']
else:
to_channel_id = message.to.channelid
def send_message(self, message):
super().send_message(message)
try:
to_name, to_channel_id = self._prepare_message(message)

message_type = "direct" if message.is_direct else "channel"
log.debug('Sending %s message to %s (%s)' % (message_type, to_name, to_channel_id))
Expand All @@ -349,6 +363,44 @@ def send_message(self, message):
"to %s: %s" % (to_name, message.body)
)

def send_card(self, card: Card):
if isinstance(card.to, RoomOccupant):
card.to = card.to.room
to_humanreadable, to_channel_id = self._prepare_message(card)
attachment = {}
if card.summary:
attachment['pretext'] = card.summary
if card.title:
attachment['title'] = card.title
if card.link:
attachment['title_link'] = card.link
if card.image:
attachment['image_url'] = card.image
if card.thumbnail:
attachment['thumb_url'] = card.thumbnail
attachment['text'] = card.body

if card.color:
attachment['color'] = COLORS[card.color] if card.color in COLORS else card.color

if card.fields:
attachment['fields'] = [{'title': key, 'value': value, 'short': True} for key, value in card.fields]

data = {
'attachments': [attachment]
}

try:
log.debug('Sending data:\n%s', data)
# 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.client.make_request('post', '/' + self.cards_hook, options=data, basepath='/hooks')
except Exception:
log.exception(
"An exception occurred while trying to send a card to %s.[%s]" % (to_humanreadable, card)
)

def prepare_message_body(self, body, size_limit):
"""
Returns the parts of a message chunked and ready for sending.
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mattermostdriver>=2.2
mattermostdriver>=2.3

0 comments on commit 524986b

Please sign in to comment.