Skip to content

Commit e33a267

Browse files
authored
Merge pull request #69 from seratch/pr-56
Update #56 - Accept usage of Flask Blueprints as app instance
2 parents 49b8800 + cc75d59 commit e33a267

File tree

4 files changed

+78
-11
lines changed

4 files changed

+78
-11
lines changed

example/blueprint/example.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# ------------------
2+
# Only for running this script here
3+
import logging
4+
import sys
5+
from os.path import dirname
6+
7+
sys.path.insert(1, f"{dirname(__file__)}/../..")
8+
logging.basicConfig(level=logging.DEBUG)
9+
# ------------------
10+
11+
from slackeventsapi import SlackEventAdapter
12+
from slack import WebClient
13+
import os
14+
15+
from flask import Flask, Blueprint
16+
slack_events = Blueprint('slack_events', __name__)
17+
18+
# Our app's Slack Event Adapter for receiving actions via the Events API
19+
slack_signing_secret = os.environ["SLACK_SIGNING_SECRET"]
20+
slack_events_adapter = SlackEventAdapter(slack_signing_secret, "/slack/events", slack_events)
21+
22+
# Create a SlackClient for your bot to use for Web API requests
23+
slack_bot_token = os.environ["SLACK_BOT_TOKEN"]
24+
slack_client = WebClient(slack_bot_token)
25+
26+
# Example responder to greetings
27+
@slack_events_adapter.on("message")
28+
def handle_message(event_data):
29+
message = event_data["event"]
30+
# If the incoming message contains "hi", then respond with a "Hello" message
31+
if message.get("subtype") is None and "hi" in message.get('text'):
32+
channel = message["channel"]
33+
message = "Hello <@%s>! :tada:" % message["user"]
34+
slack_client.chat_postMessage(channel=channel, text=message)
35+
36+
37+
# Example reaction emoji echo
38+
@slack_events_adapter.on("reaction_added")
39+
def reaction_added(event_data):
40+
event = event_data["event"]
41+
emoji = event["reaction"]
42+
channel = event["item"]["channel"]
43+
text = ":%s:" % emoji
44+
slack_client.chat_postMessage(channel=channel, text=text)
45+
46+
# Error events
47+
@slack_events_adapter.on("error")
48+
def error_handler(err):
49+
print("ERROR: " + str(err))
50+
51+
52+
app = Flask(__name__)
53+
app.register_blueprint(slack_events)
54+
55+
# FLASK_APP=example.py FLASK_ENV=development flask run --port 3000

example/blueprint/requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
slackclient>=2.7.1
2+
slackeventsapi>=2.1.0
3+
flask>=1

slackeventsapi/server.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from flask import Flask, request, make_response
1+
from flask import Flask, request, make_response, Blueprint
22
import json
33
import platform
44
import sys
@@ -18,10 +18,10 @@ def __init__(self, signing_secret, endpoint, emitter, server):
1818
# If a server is passed in, bind the event handler routes to it,
1919
# otherwise create a new Flask instance.
2020
if server:
21-
if isinstance(server, Flask):
21+
if isinstance(server, Flask) or isinstance(server, Blueprint):
2222
self.bind_route(server)
2323
else:
24-
raise TypeError("Server must be an instance of Flask")
24+
raise TypeError("Server must be an instance of Flask or Blueprint")
2525
else:
2626
Flask.__init__(self, __name__)
2727
self.bind_route(self)

tests/test_server.py

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import json
2-
from flask import Flask
3-
import pytest
4-
import sys
51
import hmac
62
import time
3+
4+
import pytest
5+
from flask import Flask, Blueprint, make_response
6+
77
from slackeventsapi import SlackEventAdapter
88
from slackeventsapi.server import SlackEventAdapterException
9-
from slackeventsapi.version import __version__
109

1110

1211
def test_existing_flask():
@@ -19,9 +18,19 @@ def test_server_not_flask():
1918
with pytest.raises(TypeError) as e:
2019
invalid_flask = "I am not a Flask"
2120
SlackEventAdapter("SIGNING_SECRET", "/slack/events", invalid_flask)
22-
assert e.value.args[0] == 'Server must be an instance of Flask'
21+
assert e.value.args[0] == 'Server must be an instance of Flask or Blueprint'
2322

2423

24+
def test_blueprint_server():
25+
simple_page = Blueprint('simple_page', __name__)
26+
@simple_page.route('/', defaults={'page': 'index'})
27+
@simple_page.route('/<page>')
28+
def show(page):
29+
return make_response("This is page " + page)
30+
31+
valid_adapter = SlackEventAdapter("SIGNING_SECRET", "/slack/events", simple_page)
32+
assert isinstance(valid_adapter, SlackEventAdapter)
33+
2534
def test_event_endpoint_get(client):
2635
# GET on '/slack/events' should 404
2736
res = client.get('/slack/events')
@@ -74,7 +83,7 @@ def test_invalid_request_timestamp(client):
7483
slack_adapter = SlackEventAdapter("SIGNING_SECRET")
7584

7685
data = pytest.reaction_event_fixture
77-
timestamp = int(time.time()+1000)
86+
timestamp = int(time.time() + 1000)
7887
signature = "bad timestamp"
7988

8089
with pytest.raises(SlackEventAdapterException) as excinfo:
@@ -100,7 +109,7 @@ def test_compare_digest_fallback(client, monkeypatch):
100109

101110
data = pytest.reaction_event_fixture
102111
timestamp = int(time.time())
103-
signature =pytest.create_signature(slack_adapter.signing_secret, timestamp, data)
112+
signature = pytest.create_signature(slack_adapter.signing_secret, timestamp, data)
104113

105114
res = client.post(
106115
'/slack/events',

0 commit comments

Comments
 (0)