X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=turbot_flask%2Fturbot.py;h=ea0607ccea16d1871450dc75602a53613f02289e;hb=5f54f1ee53b8ae1b9d93df3f56c6a992f1d1bf0a;hp=df7d51e0195cce4c3ed097816db5aac4864b5d08;hpb=13839f9cacfd7aaa389bf6983c5e9b98beead6af;p=turbot diff --git a/turbot_flask/turbot.py b/turbot_flask/turbot.py index df7d51e..ea0607c 100644 --- a/turbot_flask/turbot.py +++ b/turbot_flask/turbot.py @@ -1,18 +1,105 @@ #!/usr/bin/env python3 -from flask import Flask +from flask import current_app +from slack import WebClient +from slack.signature import SignatureVerifier +from flask import Flask, request, make_response from slackeventsapi import SlackEventAdapter + import os +import requests import threading -from turbot.rot import rot_route -from turbot.slack import slack_send_message +from turbot.rot import rot from turbot.sheets import sheets_create app = Flask(__name__) -app.register_blueprint(rot_route) slack_signing_secret = os.environ['SLACK_SIGNING_SECRET'] -slack_events = SlackEventAdapter(slack_signing_secret, "/slack/events", app) +slack_events = SlackEventAdapter(slack_signing_secret, "/events", app) + +slack_bot_token = os.environ['SLACK_BOT_TOKEN'] + +signature_verifier = SignatureVerifier(slack_signing_secret) +slack_client = WebClient(slack_bot_token) + +def slack_is_valid_request(request): + """Returns true if request actually came from Slack. + + By means of checking the requests signature together with the slack + signing key. + + Note: If flask is in debug mode, this function will always return true.""" + + if current_app.debug: + return True + + data = request.get_data() + headers = request.headers + + return signature_verifier.is_valid_request(data, headers) + +def slack_send_reply(request, text): + """Send a Slack message as a reply to a specified request. + + If the request is associated with a direct message, the reply is + made by using the "response_url" from the request. Otherwise, the + reply will be sent to the channel associated with the request. + + Note: If flask is in debug mode, this function will just print the + text to stdout.""" + + app = current_app + channel_name = request.form.get('channel_name') + response_url = request.form.get('response_url') + channel = request.form.get('channel_id') + + if (app.debug): + print("Sending message to channel '{}': {}".format(channel, text)) + return + + if (channel_name == "directmessage"): + resp = requests.post(response_url, + json = {"text": text}, + headers = {"Content-type": "application/json"}) + if (resp.status_code != 200): + app.logger.error("Error posting request to Slack: " + resp.text) + else: + slack_send_message(channel, text) + +def slack_send_message(channel, text): + """Send a Slack message to a specified channel.""" + + slack_client.chat_postMessage(channel=channel, text=text) + +@app.route('/rot', methods = ['POST']) +def rot_route(): + """Implements the /rot slash command for Slack replying in Slack + + The format of this command is as follows: + + /rot [count|*] String to be rotated + + The optional count indicates an amount to rotate each character in the + string. If the count is '*' or is not present, then the string will + be rotated through all possible 25 values. + + The result of the rotation is provided as a message in Slack. If the + slash command was issued in a direct message, the response is made by + using the "response_url" from the request. This allows the bot to reply + in a direct message that it is not a member of. Otherwise, if the slash + command was issued in a channel, the bot will reply in that channel.""" + + if not slack_is_valid_request(request): + return make_response("invalid request", 403) + + text = request.form.get('text') + + reply = rot(text) + + slack_send_reply(request, reply) + + return "" + @slack_events.on("channel_created") def handle_channel_created(event_data):