From 48a7521706ad205f22e743bcd94446ac0069fe0a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 25 Sep 2020 19:57:59 -0700 Subject: [PATCH] Add Slack dependencies and minimum boilerplate to our flask app This entirely replaces our flask setup, (which also breaks our current WSGI setup too) but is based on the exact demo code from: https://github.com/slackapi/python-slack-events-api/blob/main/example/example.py I want to start with this to ensure I can at least get a correct challenge working. After I get this working this way, I'll plan to put direct flask code back in place and integrated with the web server via WSGI. --- requirements.in | 3 +- requirements.txt | 88 +++++++++++++++++++++++++++++++++++++++++++++--- turbot.py | 63 ++++++++++------------------------ 3 files changed, 104 insertions(+), 50 deletions(-) diff --git a/requirements.in b/requirements.in index c025edd..1ec97a8 100644 --- a/requirements.in +++ b/requirements.in @@ -1,4 +1,5 @@ flask flask_restful python-dotenv - +slackclient +slackeventsapi diff --git a/requirements.txt b/requirements.txt index 96afde4..95004d3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,10 +4,36 @@ # # pip-compile --allow-unsafe --generate-hashes --no-index # +aiohttp==3.6.2 \ + --hash=sha256:1e984191d1ec186881ffaed4581092ba04f7c61582a177b187d3a2f07ed9719e \ + --hash=sha256:259ab809ff0727d0e834ac5e8a283dc5e3e0ecc30c4d80b3cd17a4139ce1f326 \ + --hash=sha256:2f4d1a4fdce595c947162333353d4a44952a724fba9ca3205a3df99a33d1307a \ + --hash=sha256:32e5f3b7e511aa850829fbe5aa32eb455e5534eaa4b1ce93231d00e2f76e5654 \ + --hash=sha256:344c780466b73095a72c616fac5ea9c4665add7fc129f285fbdbca3cccf4612a \ + --hash=sha256:460bd4237d2dbecc3b5ed57e122992f60188afe46e7319116da5eb8a9dfedba4 \ + --hash=sha256:4c6efd824d44ae697814a2a85604d8e992b875462c6655da161ff18fd4f29f17 \ + --hash=sha256:50aaad128e6ac62e7bf7bd1f0c0a24bc968a0c0590a726d5a955af193544bcec \ + --hash=sha256:6206a135d072f88da3e71cc501c59d5abffa9d0bb43269a6dcd28d66bfafdbdd \ + --hash=sha256:65f31b622af739a802ca6fd1a3076fd0ae523f8485c52924a89561ba10c49b48 \ + --hash=sha256:ae55bac364c405caa23a4f2d6cfecc6a0daada500274ffca4a9230e7129eac59 \ + --hash=sha256:b778ce0c909a2653741cb4b1ac7015b5c130ab9c897611df43ae6a58523cb965 \ + # via slackclient aniso8601==8.0.0 \ --hash=sha256:529dcb1f5f26ee0df6c0a1ee84b7b27197c3c50fc3a6321d66c544689237d072 \ --hash=sha256:c033f63d028b9a58e3ab0c2c7d0532ab4bfa7452bfc788fbfe3ddabd327b181a \ # via flask-restful +async-timeout==3.0.1 \ + --hash=sha256:0c3c816a028d47f659d6ff5c745cb2acf1f966da1fe5c19c77a70282b25f4c5f \ + --hash=sha256:4291ca197d287d274d0b6cb5d6f8f8f82d434ed288f962539ff18cc9012f9ea3 \ + # via aiohttp +attrs==20.2.0 \ + --hash=sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594 \ + --hash=sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc \ + # via aiohttp +chardet==3.0.4 \ + --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \ + --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 \ + # via aiohttp click==7.1.2 \ --hash=sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a \ --hash=sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc \ @@ -19,15 +45,19 @@ flask-restful==0.3.8 \ flask==1.1.2 \ --hash=sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060 \ --hash=sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557 \ - # via -r requirements.in, flask-restful + # via -r requirements.in, flask-restful, slackeventsapi +idna==2.10 \ + --hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \ + --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 \ + # via yarl itsdangerous==1.1.0 \ --hash=sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19 \ --hash=sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749 \ - # via flask + # via flask, slackeventsapi jinja2==2.11.2 \ --hash=sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0 \ --hash=sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035 \ - # via flask + # via flask, slackeventsapi markupsafe==1.1.1 \ --hash=sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473 \ --hash=sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161 \ @@ -62,7 +92,30 @@ markupsafe==1.1.1 \ --hash=sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2 \ --hash=sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7 \ --hash=sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be \ - # via jinja2 + # via jinja2, slackeventsapi +multidict==4.7.6 \ + --hash=sha256:1ece5a3369835c20ed57adadc663400b5525904e53bae59ec854a5d36b39b21a \ + --hash=sha256:275ca32383bc5d1894b6975bb4ca6a7ff16ab76fa622967625baeebcf8079000 \ + --hash=sha256:3750f2205b800aac4bb03b5ae48025a64e474d2c6cc79547988ba1d4122a09e2 \ + --hash=sha256:4538273208e7294b2659b1602490f4ed3ab1c8cf9dbdd817e0e9db8e64be2507 \ + --hash=sha256:5141c13374e6b25fe6bf092052ab55c0c03d21bd66c94a0e3ae371d3e4d865a5 \ + --hash=sha256:51a4d210404ac61d32dada00a50ea7ba412e6ea945bbe992e4d7a595276d2ec7 \ + --hash=sha256:5cf311a0f5ef80fe73e4f4c0f0998ec08f954a6ec72b746f3c179e37de1d210d \ + --hash=sha256:6513728873f4326999429a8b00fc7ceddb2509b01d5fd3f3be7881a257b8d463 \ + --hash=sha256:7388d2ef3c55a8ba80da62ecfafa06a1c097c18032a501ffd4cabbc52d7f2b19 \ + --hash=sha256:9456e90649005ad40558f4cf51dbb842e32807df75146c6d940b6f5abb4a78f3 \ + --hash=sha256:c026fe9a05130e44157b98fea3ab12969e5b60691a276150db9eda71710cd10b \ + --hash=sha256:d14842362ed4cf63751648e7672f7174c9818459d169231d03c56e84daf90b7c \ + --hash=sha256:e0d072ae0f2a179c375f67e3da300b47e1a83293c554450b29c900e50afaae87 \ + --hash=sha256:f07acae137b71af3bb548bd8da720956a3bc9f9a0b87733e0899226a2317aeb7 \ + --hash=sha256:fbb77a75e529021e7c4a8d4e823d88ef4d23674a202be4f5addffc72cbb91430 \ + --hash=sha256:fcfbb44c59af3f8ea984de67ec7c306f618a3ec771c2843804069917a8f2e255 \ + --hash=sha256:feed85993dbdb1dbc29102f50bca65bdc68f2c0c8d352468c25b54874f23c39d \ + # via aiohttp, yarl +pyee==7.0.4 \ + --hash=sha256:0667fd696f55ffdf9f2646fa60557b4eeae1a427315d3938b614ee40755d18b6 \ + --hash=sha256:15c6bcc14de2c2b3d8ee8923283fca182bcfab4155975a5165c66fc4bf44b680 \ + # via slackeventsapi python-dotenv==0.14.0 \ --hash=sha256:8c10c99a1b25d9a68058a1ad6f90381a62ba68230ca93966882a4dbc3bc9c33d \ --hash=sha256:c10863aee750ad720f4f43436565e4c1698798d763b63234fb5021b6c616e423 \ @@ -75,7 +128,34 @@ six==1.15.0 \ --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ # via flask-restful +slackclient==2.9.1 \ + --hash=sha256:214edd4a494cc74353c8084ec184ff97a116d4b12cde287f805a9af948ef39ae \ + --hash=sha256:3a3e84fd4f13d9715740c13ce6c3c25b970147aeeeec22ef137d796124dfcf08 \ + # via -r requirements.in +slackeventsapi==2.2.1 \ + --hash=sha256:1582964860b9e00b721ddfc7402defdd02bdf73f48d4cee7fb952a3b27db45fb \ + --hash=sha256:6baa2bf12b5a9d312bf02836720f3ea3b730377449d67ea92ec63fc7c02c7c30 \ + # via -r requirements.in werkzeug==1.0.1 \ --hash=sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43 \ --hash=sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c \ # via flask +yarl==1.6.0 \ + --hash=sha256:04a54f126a0732af75e5edc9addeaa2113e2ca7c6fce8974a63549a70a25e50e \ + --hash=sha256:3cc860d72ed989f3b1f3abbd6ecf38e412de722fb38b8f1b1a086315cf0d69c5 \ + --hash=sha256:5d84cc36981eb5a8533be79d6c43454c8e6a39ee3118ceaadbd3c029ab2ee580 \ + --hash=sha256:5e447e7f3780f44f890360ea973418025e8c0cdcd7d6a1b221d952600fd945dc \ + --hash=sha256:61d3ea3c175fe45f1498af868879c6ffeb989d4143ac542163c45538ba5ec21b \ + --hash=sha256:67c5ea0970da882eaf9efcf65b66792557c526f8e55f752194eff8ec722c75c2 \ + --hash=sha256:6f6898429ec3c4cfbef12907047136fd7b9e81a6ee9f105b45505e633427330a \ + --hash=sha256:7ce35944e8e61927a8f4eb78f5bc5d1e6da6d40eadd77e3f79d4e9399e263921 \ + --hash=sha256:b7c199d2cbaf892ba0f91ed36d12ff41ecd0dde46cbf64ff4bfe997a3ebc925e \ + --hash=sha256:c15d71a640fb1f8e98a1423f9c64d7f1f6a3a168f803042eaf3a5b5022fde0c1 \ + --hash=sha256:c22607421f49c0cb6ff3ed593a49b6a99c6ffdeaaa6c944cdda83c2393c8864d \ + --hash=sha256:c604998ab8115db802cc55cb1b91619b2831a6128a62ca7eea577fc8ea4d3131 \ + --hash=sha256:d088ea9319e49273f25b1c96a3763bf19a882cff774d1792ae6fba34bd40550a \ + --hash=sha256:db9eb8307219d7e09b33bcb43287222ef35cbcf1586ba9472b0a4b833666ada1 \ + --hash=sha256:e31fef4e7b68184545c3d68baec7074532e077bd1906b040ecfba659737df188 \ + --hash=sha256:e32f0fb443afcfe7f01f95172b66f279938fbc6bdaebe294b0ff6747fb6db020 \ + --hash=sha256:fcbe419805c9b20db9a51d33b942feddbf6e7fb468cb20686fd7089d4164c12a \ + # via aiohttp diff --git a/turbot.py b/turbot.py index 1cb6e68..d447905 100755 --- a/turbot.py +++ b/turbot.py @@ -1,52 +1,25 @@ #!/usr/bin/env python3 -from flask import Flask -from flask_restful import reqparse, abort, Api, Resource +from slackeventsapi import SlackEventAdapter +from slack import WebClient +import os -app = Flask(__name__) -api = Api(app) +slack_signing_secret = os.environ['SLACK_SIGNING_SECRET'] +slack_bot_token = os.environ['SLACK_BOT_TOKEN'] -TODOS = {} +slack_events = SlackEventAdapter(slack_signing_secret, "/slack/events") +slack_client = WebClient(slack_bot_token) -def abort_if_todo_doesnt_exist(todo_id): - if todo_id not in TODOS: - abort(404, message="Todo {} doesn't exist".format(todo_id)) +@slack_events.on("message") +def handle_message(data): + message = data["event"] + if message.get("subtype") is None and "hi" in message.get("text"): + channel = message["channel"] + response = "Hello {}! :tada:".format(message["user"]) + slack_client.chat_postMessage(channel=channel, text=response) -parser = reqparse.RequestParser() -parser.add_argument('task') +@slack_events.on("error") +def handle_error(err): + print("ERROR: " + str(err)) -class Todo(Resource): - def get(self, todo_id): - abort_if_todo_doesnt_exist(todo_id) - return TODOS[todo_id] - - def delete(self, todo_id): - abort_if_todo_doesnt_exist(todo_id) - del TODOS[todo_id] - return '', 204 - - def put(self, todo_id): - args = parser.parse_args() - task = {'task': args['task']} - TODOS[todo_id] = task - return task, 201 - -class TodoList(Resource): - def get(self): - return TODOS - - def post(self): - args = parser.parse_args() - try: - todo_id = int(max(TODOS.keys()).lstrip('todo')) + 1 - except: - todo_id = 1 - todo_id = 'todo%i' % todo_id - TODOS[todo_id] = {'task': args['task']} - return TODOS[todo_id], 201 - -api.add_resource(TodoList, '/todos') -api.add_resource(Todo, '/todos/') - -if __name__ == '__main__': - app.run(debug=True) +slack_events.start(port=3000) -- 2.43.0