import logging import os import json from logging.config import dictConfig from slack_sdk import WebClient from slack_sdk.signature import SignatureVerifier from slack_sdk.errors import SlackApiError from slugify import slugify from flask import Flask, request, make_response from app.ux import SlackInterface app = Flask(__name__) client = WebClient(token=os.getenv('SLACK_API_TOKEN')) signature_verifier = SignatureVerifier(os.getenv('SLACK_SIGNING_SECRET')) # client.api_test() dictConfig({ 'version': 1, 'disable_existing_loggers': True, 'formatters': { 'default': { 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s', }, 'access': { 'format': '%(message)s', } }, 'handlers': { 'console': { 'level': 'INFO', 'class': 'logging.StreamHandler', 'formatter': 'default', 'stream': 'ext://sys.stdout', } }, 'loggers': { 'gunicorn.error': { 'handlers': ['console'], 'level': 'INFO', 'propagate': False, }, 'gunicorn.access': { 'handlers': ['console'], 'level': 'INFO', 'propagate': False, } }, 'root': { 'level': 'DEBUG', 'handlers': ['console'], } }) def verify_slack(req: request): signature_verifier = SignatureVerifier(os.getenv('SLACK_SIGNING_SECRET')) if not signature_verifier.is_valid_request(req.get_data(), req.headers): return make_response('invalid request', 403) @app.route('/slack/command', methods=['POST']) def slack_command(): verify_slack(request) logging.info(request.form) client.views_open( trigger_id=request.form.get('trigger_id'), view=SlackInterface().select_action_modal() ) return make_response('', 200) @app.route('/slack/events', methods=['POST']) def slack_events(): verify_slack(request) if 'payload' in request.form: payload = json.loads(request.form.get('payload')) print('debug: %s \n' % payload) if 'actions' in payload: action_id = payload['actions'][0]['action_id'] trigger_id = payload['trigger_id'] if action_id == 'create_new_channel_modal': client.views_push( trigger_id=trigger_id, view=SlackInterface().new_channel_modal(payload['user']['id']) ) elif action_id == 'generate_documents_modal': client.views_push( trigger_id=trigger_id, view=SlackInterface().generate_docs_modal() ) return make_response('', 200) elif 'view' in payload: callback_id = payload['view']['callback_id'] if callback_id == 'submit_new_channel': users_to_add = list() values = payload['view']['state']['values'] cx_name = values['customer_name']['customer_name']['value'] cx_slug = slugify(cx_name) selected_users = values['users_to_add']['users_to_add']['selected_users'] for i in selected_users: username = client.users_info(user=i) users_to_add.append(username['user']['name']) # Create channel try: res = client.conversations_create(name=cx_slug) # Notify da peeps client.chat_postMessage( channel=res['channel']['id'], text=f'sup bros! {" ".join(["@" + i for i in users_to_add])}' ) return make_response('', 200) except SlackApiError as e: logging.error("Error creating conversation: {}".format(e)) return make_response('', 403) elif callback_id == 'generate_documents': pass else: return make_response('', 404) # # // Handle actions based upon user selection and inputs # if ( body.view.callback_id == 'submit_new_channel' ) { # console.log('[+] Creating new channel for @' + body.user.username); # # // Gather vars and setup slug from customer name # let cx_name = body.view.state.values.customer_name.customer_name.value; # let cx_char = cx_name.charAt(0); # let cx_slug = slugify(cx_name, { # strict: true, # lower: true # }); # # // Check if first character is a number so it can go into numeric group # if ( !isNaN(cx_char) ) { # var gdrive_prefix = '0-9'; # } else { # var gdrive_prefix = cx_char.toUpperCase(); # } # # // Create users array to add to channel # const users = body.view.state.values.users_to_add.users_to_add.selected_users.map(async function(item) { # var result = await api.callSlackAPI('users.info', { # user: item # }); # let slack_username = '@' + result.user.name; # return slack_username # }); # # await Promise.all(users).then(async function(result) { # // Post to Zapier to run Zap to create new channel # await api.postZapierWebhook(process.env.ZAPIER_WEBHOOK_submit_new_channel, { # 'customer_name': cx_name, # 'gdrive_prefix': gdrive_prefix, # 'slack_channel': cx_slug, # 'users': result # }); # }) # } else if ( body.view.callback_id == 'generate_documents' ) { # console.log('[+] Generating documents for @' + body.user.username); # # // Gather vars and setup slug from customer name # let cx_name = body.view.state.values.customer_name.customer_name.value; # let opp_name = body.view.state.values.opportunity_name.opportunity_name.value; # let cx_char = cx_name.charAt(0); # # // Check if first character is a number so it can go into numeric group # if ( !isNaN(cx_char) ) { # var gdrive_prefix = '0-9'; # } else { # var gdrive_prefix = cx_char.toUpperCase(); # } # # // Post to Zapier to run Zap to generate new docs in the channel # await api.postZapierWebhook(process.env.ZAPIER_WEBHOOK_generate_documents, { # 'customer_name': cx_name, # 'gdrive_prefix': gdrive_prefix, # 'gdrive_item': cx_name + ' - ' + opp_name, # 'slack_channel': body.view.state.values.channel_to_post_to.channel_to_post_to.selected_channels[0], # }); # } if __name__ == '__main__': app.run()