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 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."""
+
+ 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:
+ try:
+ slack_client.chat_postMessage(channel=channel, text=text)
+ except SlackApiError as e:
+ app.logger.error("Slack API error: " + e.response["error"])
+
def rot_string(str, n=13):
"""Return a rotated version of a string
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."""
- data = request.get_data()
- headers = request.headers
- response_url = request.form.get('response_url')
- channel_name = request.form.get('channel_name')
- channel = request.form.get('channel_id')
- query = request.form.get('text')
-
- if not signature_verifier.is_valid_request(data, headers):
+ if not slack_is_valid_request(request):
return make_response("invalid request", 403)
- match = re.match('^([0-9]+|\*) (.*)$', query)
+ query = request.form.get('text')
+ match = re.match(r'^([0-9]+|\*) (.*)$', query)
if (match):
try:
count = int(match.group(1))
reply += "```"
- if (channel_name == "directmessage"):
- resp = requests.post(response_url,
- json = {"text": reply},
- headers = {"Content-type": "application/json"})
- if (resp.status_code != 200):
- app.logger.error("Error posting request to Slack: " + resp.text)
- else:
- try:
- slack_client.chat_postMessage(channel=channel, text=reply)
- except SlackApiError as e:
- app.logger.error("Slack API error: " + e.response["error"])
+ slack_send_reply(request, reply)
+
return ""
@slack_events.on("error")
def handle_error(error):
app.logger.error("Error from Slack: " + str(error))
-
-if __name__ == '__main__':
- app.run(debug=True)