Skip to content

Instantly share code, notes, and snippets.

@ppsirg
Last active February 25, 2019 15:53
Show Gist options
  • Save ppsirg/f871fa9438910a2ded223b28dbabe82b to your computer and use it in GitHub Desktop.
Save ppsirg/f871fa9438910a2ded223b28dbabe82b to your computer and use it in GitHub Desktop.
slackbot with steroids
"""
slack bot with steroids
get tokens here: https://slack.dev/python-slackclient/auth.html
slack dev kit: https://slack.dev/python-slackclient/index.html
requirements:
pip install slackclient
"""
import os
import re
import json
from copy import deepcopy
from datetime import datetime
from threading import Thread
from slackclient import SlackClient
baned_tags_regexp = re.compile('^<[/]?[t|d|h|i|m]')
link_header = re.compile('https*:[/]{2}')
DOMAIN = 'my_thing.com'
def catalogue(func):
"""Handle error, produce safe string."""
def error_handler(*args, **kwargs):
obj = args[0]
if obj is None:
obj = 'None object'
obj_type = type(obj)
try:
text = func(*args, **kwargs)
response = str(text)
except Exception as e:
text = 'set with items without str representation, error: {}'.format(e)
response = '[{}] - {}'.format(obj_type, text)
return response
return error_handler
@catalogue
def cast_str_smart(thing):
"""Transform data to str."""
if thing is None:
return 'None object detected'
elif type(thing) is str:
return thing
elif type(thing) is dict:
return json.dumps(thing, indent=4, sort_keys=True)
elif type(thing) in (tuple, list):
return '\n-'.join([cast_str_smart(a) for a in thing])
else:
return str(thing)
@catalogue
def replace_fixes(message):
"""fix text incompatible with slack"""
# bugfix for url malformation
if 'http:///' in message:
msj = message.replace('http:///', '{}/'.format(DOMAIN))
response = msj
else:
response = message
# quick delete html to decrease message length
filtered = [a.strip() for a in response.split('\n') if a.strip() != '' and not baned_tags_regexp.match(a.strip())]
flag = False
response = []
for line in filtered:
if 'style>' in line:
flag = not flag
if not flag:
response.append(line)
return '\n'.join(response)
def add_header(message, locations={}):
"""Add headers for message tracking."""
timestamp = datetime.now().strftime('%d-%m-%Y_%H:%M:%S')
try:
user = os.getlogin()
except:
user = 'bad_console'
try:
machine = os.uname().nodename
except:
machine = 'windows_machine'
header = '`[{timestamp}] {user} from {machine} says:`\n'.format(**{
'timestamp': timestamp,
'user': user,
'machine': machine
})
return header + message
class Steroid(object):
def __init__(self, credentials=None, channel='my_channel'):
self.base_location = os.path.dirname(__file__)
self.credentials = dict()
self.channel = channel
self.credentials = {
'token': 'my_token',
}
self.sc = SlackClient(self.credentials['token'])
def log(self, message):
"""Sends slack-safe message to slack."""
# show message
# create a copy avoid modify original
msj = deepcopy(message)
# process message
msj = cast_str_smart(msj)
msj = replace_fixes(msj)
# add identification headers to message
msj = add_header(msj, locations=self.known_locations)
# send message in no-wait mode
t = Thread(
target=self.sc.api_call,
args=('chat.postMessage',),
kwargs={'channel': '#{}'.format(self.channel), 'text': msj}
)
t.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment