Skip to content
This repository has been archived by the owner on Jan 21, 2021. It is now read-only.

Commit

Permalink
Merge pull request #8 from staticdev/new-api
Browse files Browse the repository at this point in the history
New api
  • Loading branch information
Thiago C. D'Ávila committed Jun 2, 2020
2 parents 76c374f + e34a268 commit c625a10
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 93 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ From your workspace, go to /apps/manage/custom-integrations and add Bots app. Th
## Run with Docker

```sh
sudo docker build -t staticdev/k8s-python-slackbot:0.0.3 .
sudo docker run --name k8s-python-slackbot -d -e SLACK_BOT_NAME=k8s-python-slackbot -e SLACK_BOT_TOKEN=mybot-token staticdev/k8s-python-slackbot:0.0.3
sudo docker build -t staticdev/k8s-python-slackbot:0.1.0 .
sudo docker run --name k8s-python-slackbot -d -e SLACK_BOT_NAME=k8s-python-slackbot -e SLACK_BOT_TOKEN=mybot-token staticdev/k8s-python-slackbot:0.1.0
```

## Run with Minikube
Expand All @@ -22,7 +22,7 @@ Start a new cluster using your favorite VM (kvm2 recommended) and build:
minikube start --vm-driver=kvm2
# build inside minikube
eval $(minikube docker-env)
docker build -t staticdev/k8s-python-slackbot:0.0.3 -f Dockerfile .
docker build -t staticdev/k8s-python-slackbot:0.1.0 -f Dockerfile .
```

Create a slackbot.properties file in .env folder with the following structure:
Expand Down
148 changes: 59 additions & 89 deletions echobot.py
Original file line number Diff line number Diff line change
@@ -1,136 +1,106 @@
# -*- coding: utf-8 -*-

""" Echobot using slackclient """

"""Echobot using slackclient."""
import logging
import os
import time
import sys
import urllib

import slackclient
import slack

SLACK_BOT_NAME = os.environ.get('SLACK_BOT_NAME')
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
GLOBAL_STATE = {}

SLACK_BOT_NAME = os.environ.get("SLACK_BOT_NAME")

if SLACK_BOT_NAME is None:
print('SLACK_BOT_NAME not set')
exit(1)
sys.exit("SLACK_BOT_NAME not set.")

SLACK_BOT_TOKEN = os.environ.get('SLACK_BOT_TOKEN')
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")

if SLACK_BOT_TOKEN is None:
print('SLACK_BOT_TOKEN not set')
exit(1)

SLACK_CLIENT = slackclient.SlackClient(SLACK_BOT_TOKEN)
API_CALL = SLACK_CLIENT.api_call('users.list')
if API_CALL.get('ok'):
# retrieve all users so we can find our bot
USERS = API_CALL.get('members')
for member in USERS:
if 'name' in member and member.get('name') == SLACK_BOT_NAME:
BOT_ID = member.get('id')
else:
print('Could not reach Slack with your SLACK_BOT_TOKEN. Please check if ' +
'your SLACK_BOT_TOKEN and SLACK_BOT_NAME are both correct.')
exit(1)

try:
BOT_ID
except NameError:
print('Could not find bot with the name ' + SLACK_BOT_NAME + '. Please ' +
'check if your SLACK_BOT_TOKEN and SLACK_BOT_NAME are both correct.')
exit(1)
sys.exit("SLACK_BOT_TOKEN not set.")


def get_mention(user):
"""
Returns users mention
"""
return '<@{user}>'.format(user=user)

BOT_MENTION = get_mention(BOT_ID)
"""Returns users mention."""
return "<@{user}>".format(user=user)


def add_mention(user_mention, response):
"""
Returns response mentioning the person who mentioned you
"""
response_template = '{mention} ' + response
"""Returns response mentioning the person who mentioned you."""
response_template = "{mention} " + response
return response_template.format(mention=user_mention)


def is_private(event):
"""Checks if private slack channel"""
return event.get('channel').startswith('D')
"""Checks if private slack channel."""
return event.get("channel").startswith("D")


def is_for_me(event):
"""Know if the message is dedicated to me"""
"""Know if the message is dedicated to me."""
# check if not my own event
event_type = event.get('type')
if (event_type and
event_type == 'message' and not event.get('user') == BOT_ID):
text = event.get('text')
event_type = event.get("type")
if event_type and event_type == "message" and not event.get("user") == BOT_ID:
text = event.get("text")
# in case it is a private message return true
if text and is_private(event):
return True
# in case it is not a private message check mention
if text and BOT_MENTION in text.strip().split():
if text and get_mention(BOT_ID) in text.strip().split():
return True
return None


def handle_request(message_text, channel, user):
def parse_slack_output(data):
"""Returns text, channel, ts and user."""
return data["text"], data["channel"], data["ts"], data["user"]


@slack.RTMClient.run_on(event="open")
def open_client(**payload):
web_client = payload["web_client"]
auth_result = web_client.auth_test()
GLOBAL_STATE.update({"bot_id": auth_result["bot_id"]})
LOGGER.info(f"cached: {GLOBAL_STATE}")


@slack.RTMClient.run_on(event="message")
def handle_request(**payload):
"""
Receives requests directed at the bot and determines if they
are valid requests. If so, then acts on the requests. If not,
returns back what it needs for clarification.
"""
data = payload["data"]
if data.get("bot_id", None) == GLOBAL_STATE["bot_id"]:
LOGGER.debug("Skipped as it's me")
return
web_client = payload["web_client"]
message, channel, ts, user = parse_slack_output(data)
LOGGER.debug(
"slack_message:|%s|%s|%s|%s|" % (str(message), str(channel), str(ts), str(user))
)
# removes first mention to the bot in public channels
if not channel.startswith('D'):
unmentioned_message = message_text.replace(BOT_MENTION, '', 1)
if not channel.startswith("D"):
unmentioned_message = message.replace(get_mention(BOT_ID), "", 1)
else:
unmentioned_message = message_text
unmentioned_message = message
unmentioned_message = unmentioned_message.strip()

# public channels
if not channel.startswith('D'):
if not channel.startswith("D"):
user_mention = get_mention(user)
unmentioned_message = add_mention(user_mention, unmentioned_message)

# send messages to channel
SLACK_CLIENT.api_call('chat.postMessage',
channel=channel,
text=unmentioned_message,
as_user=True)
web_client.chat_postMessage(
channel=channel, text=unmentioned_message, thread_ts=ts, as_user=True
)


def parse_slack_output(event_list):
"""
The Slack Real Time Messaging API is an events firehose.
this parsing function returns None unless a message is
directed at the Bot, based on its ID.
"""
if event_list:
for event in event_list:
if is_for_me(event):
return event['text'], \
event['channel'], \
event['ts'], \
event['user']
return None, None, None, None

if __name__ == '__main__':
print('%s running', __file__)
READ_WEBSOCKET_DELAY = 1 # 1 second delay between reading from firehose
if SLACK_CLIENT.rtm_connect():
print('%s connected', __file__)
while True:
REQUEST, CHANNEL, TS, EVENT_USER = parse_slack_output(
SLACK_CLIENT.rtm_read())
if REQUEST and CHANNEL:
print('slack_message:|%s|%s|%s|%s|',
str(REQUEST), str(CHANNEL),
str(TS), str(EVENT_USER))
handle_request(REQUEST, CHANNEL, EVENT_USER)
time.sleep(READ_WEBSOCKET_DELAY)
else:
print('Connection failed. Invalid Slack token or bot ID?')
if __name__ == "__main__":
LOGGER.info("{} running".format(__file__))
RTM_CLIENT = slack.RTMClient(token=SLACK_BOT_TOKEN)
RTM_CLIENT.start()
2 changes: 1 addition & 1 deletion manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ spec:
secretKeyRef:
key: SLACK_BOT_TOKEN
name: slackbot-secrets
image: staticdev/k8s-python-slackbot:0.0.3
image: staticdev/k8s-python-slackbot:0.1.0
name: slack
resources: {}
restartPolicy: Always
Expand Down

0 comments on commit c625a10

Please sign in to comment.