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 #9 from staticdev/new-api
Browse files Browse the repository at this point in the history
Linting and fixes
  • Loading branch information
Thiago C. D'Ávila authored Jun 2, 2020
2 parents c625a10 + f09aede commit 4ff0993
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 123 deletions.
2 changes: 2 additions & 0 deletions .darglint
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[darglint]
strictness = short
7 changes: 7 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[flake8]
select = B,B9,C,D,DAR,E,F,N,RST,S,W
ignore = E203,E501,W503
max-line-length = 80
max-complexity = 10
docstring-convention = google
per-file-ignores = tests/*:S101
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
33 changes: 33 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.1.0
hooks:
- id: check-toml
- id: check-yaml
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
- repo: https://github.com/prettier/prettier
rev: 2.0.5
hooks:
- id: prettier
- repo: https://github.com/psf/black
rev: 19.10b0
hooks:
- id: black
- repo: https://gitlab.com/pycqa/flake8
rev: 3.8.1
hooks:
- id: flake8
additional_dependencies:
- flake8-bandit==2.1.2
- flake8-bugbear==20.1.4
- flake8-docstrings==1.5.0
- flake8-rst-docstrings==0.0.13
- pep8-naming==0.10.0
- darglint==1.3.0
- repo: https://github.com/asottile/reorder_python_imports
rev: v2.3.0
hooks:
- id: reorder-python-imports
args: [--application-directories=src]
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM python:3.7.4-alpine
FROM python:3.7.6-slim-stretch

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
ADD . /app
ADD src/* requirements.txt /app/

# install requirements
RUN pip install --upgrade pip \
Expand Down
30 changes: 15 additions & 15 deletions manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ spec:
name: slack
spec:
containers:
- env:
- name: SLACK_BOT_NAME
valueFrom:
secretKeyRef:
key: SLACK_BOT_NAME
name: slackbot-secrets
- name: SLACK_BOT_TOKEN
valueFrom:
secretKeyRef:
key: SLACK_BOT_TOKEN
name: slackbot-secrets
image: staticdev/k8s-python-slackbot:0.1.0
name: slack
resources: {}
- env:
- name: SLACK_BOT_NAME
valueFrom:
secretKeyRef:
key: SLACK_BOT_NAME
name: slackbot-secrets
- name: SLACK_BOT_TOKEN
valueFrom:
secretKeyRef:
key: SLACK_BOT_TOKEN
name: slackbot-secrets
image: staticdev/k8s-python-slackbot:0.1.0
name: slack
resources: {}
restartPolicy: Always
status: {}
status: {}
231 changes: 125 additions & 106 deletions echobot.py → src/echobot.py
Original file line number Diff line number Diff line change
@@ -1,106 +1,125 @@
# -*- coding: utf-8 -*-
"""Echobot using slackclient."""
import logging
import os
import sys
import urllib

import slack

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:
sys.exit("SLACK_BOT_NAME not set.")

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

if SLACK_BOT_TOKEN is None:
sys.exit("SLACK_BOT_TOKEN not set.")


def get_mention(user):
"""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
return response_template.format(mention=user_mention)


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


def is_for_me(event):
"""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")
# 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 get_mention(BOT_ID) in text.strip().split():
return True
return None


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.replace(get_mention(BOT_ID), "", 1)
else:
unmentioned_message = message
unmentioned_message = unmentioned_message.strip()

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

# send messages to channel
web_client.chat_postMessage(
channel=channel, text=unmentioned_message, thread_ts=ts, as_user=True
)


if __name__ == "__main__":
LOGGER.info("{} running".format(__file__))
RTM_CLIENT = slack.RTMClient(token=SLACK_BOT_TOKEN)
RTM_CLIENT.start()
# -*- coding: utf-8 -*-
"""Echobot using slackclient."""
import logging
import os
import sys
import urllib

import slack

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:
sys.exit("SLACK_BOT_NAME not set.")

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

if SLACK_BOT_TOKEN is None:
sys.exit("SLACK_BOT_TOKEN not set.")


def get_mention(user: str) -> str:
"""Return users mention.
Args:
user: Slack user.
Returns:
str: mention string for user.
"""
return "<@{user}>".format(user=user)


def add_mention(user_mention: str, response: str) -> str:
"""Return response mentioning the person who mentioned you.
Args:
user_mention (str): Slack mention.
response (str): response message.
Returns:
str: response message with added mention.
"""
response_template = "{mention} " + response
return response_template.format(mention=user_mention)


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


def is_for_me(event):
"""Know if the message is dedicated to me."""
# check if not my own event
event_type = event.get("type")
bot_id = GLOBAL_STATE["bot_id"]
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 get_mention(bot_id) in text.strip().split():
return True
return None


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


@slack.RTMClient.run_on(event="open")
def open_client(**payload) -> None:
"""Gets bot id from WebClient."""
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) -> None:
"""Handle Slack requests."""
data = payload["data"]
bot_id = GLOBAL_STATE["bot_id"]
if data.get("bot_id", None) == 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.replace(get_mention(bot_id), "", 1)
else:
unmentioned_message = message
unmentioned_message = unmentioned_message.strip()

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

# send messages to channel
web_client.chat_postMessage(
channel=channel, text=unmentioned_message, thread_ts=ts, as_user=True
)


if __name__ == "__main__":
LOGGER.info("{} running".format(__file__))
RTM_CLIENT = slack.RTMClient(token=SLACK_BOT_TOKEN)
try:
RTM_CLIENT.start()
except slack.errors.SlackApiError:
sys.exit("Could not authenticate to Slack. Please verify SLACK_BOT_TOKEN.")
except urllib.error.URLError:
sys.exit("Could not reach Slack server. Please check your network.")

0 comments on commit 4ff0993

Please sign in to comment.