Beispiel #1
0
    def test_interactions(self):
        t = Thread(target=start_socket_mode_server(self, 3011))
        t.daemon = True
        t.start()
        time.sleep(2)  # wait for the server

        app = App(client=self.web_client)

        result = {"shortcut": False, "command": False}

        @app.shortcut("do-something")
        def shortcut_handler(ack):
            result["shortcut"] = True
            ack()

        @app.command("/hello-socket-mode")
        def command_handler(ack):
            result["command"] = True
            ack()

        handler = SocketModeHandler(
            app_token="xapp-A111-222-xyz",
            app=app,
            trace_enabled=True,
        )
        try:
            handler.client.ping_pong_trace_enabled = True
            handler.client.wss_uri = "ws://127.0.0.1:3011/link"

            handler.connect()
            assert handler.client.is_connected() is True
            time.sleep(2)  # wait for the message receiver

            handler.client.send_message("foo")

            time.sleep(2)
            assert result["shortcut"] is True
            assert result["command"] is True
        finally:
            handler.client.close()
            self.server.stop()
            self.server.close()
    def test_tokens_revoked(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            installation_store=MyInstallationStore(),
        )

        event_payload = {
            "token": "verification-token",
            "enterprise_id": "E111",
            "api_app_id": "A111",
            "event": {
                "type": "tokens_revoked",
                "tokens": {
                    "oauth": ["W111"],
                    "bot": ["W222"]
                },
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1606805974,
        }

        timestamp, body = str(int(time())), json.dumps(event_payload)
        request: BoltRequest = BoltRequest(body=body,
                                           headers=self.build_headers(
                                               timestamp, body))
        response = app.dispatch(request)
        assert response.status == 404

        # Enable the built-in event listeners
        app.enable_token_revocation_listeners()
        response = app.dispatch(request)
        assert response.status == 200

        # auth.test API call must be skipped
        assert_auth_test_count(self, 0)
        sleep(1)  # wait a bit after auto ack()
        assert app.installation_store.delete_bot_called is True
        assert app.installation_store.delete_installation_called is True
        assert app.installation_store.delete_all_called is False
Beispiel #3
0
    def test_uninstallation_and_revokes(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            authorize=authorize,
        )
        app._client = WebClient(
            token="uninstalled-revoked", base_url=self.mock_api_server_base_url
        )

        @app.event("app_uninstalled")
        def handler1(say: Say):
            say(channel="C111", text="What's up?")

        @app.event("tokens_revoked")
        def handler2(say: Say):
            say(channel="C111", text="What's up?")

        app_uninstalled_body = {
            "token": "verification_token",
            "team_id": "T_INSTALLED",
            "enterprise_id": "E_INSTALLED",
            "api_app_id": "A111",
            "event": {"type": "app_uninstalled"},
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
            "authorizations": [
                {
                    "enterprise_id": "E_INSTALLED",
                    "team_id": "T_INSTALLED",
                    "user_id": "W111",
                    "is_bot": True,
                    "is_enterprise_install": False,
                }
            ],
        }

        timestamp, body = str(int(time())), json.dumps(app_uninstalled_body)
        request: BoltRequest = BoltRequest(
            body=body, headers=self.build_headers(timestamp, body)
        )
        response = app.dispatch(request)
        assert response.status == 200

        tokens_revoked_body = {
            "token": "verification_token",
            "team_id": "T_INSTALLED",
            "enterprise_id": "E_INSTALLED",
            "api_app_id": "A111",
            "event": {
                "type": "tokens_revoked",
                "tokens": {"oauth": ["UXXXXXXXX"], "bot": ["UXXXXXXXX"]},
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
            "authorizations": [
                {
                    "enterprise_id": "E_INSTALLED",
                    "team_id": "T_INSTALLED",
                    "user_id": "W111",
                    "is_bot": True,
                    "is_enterprise_install": False,
                }
            ],
        }

        timestamp, body = str(int(time())), json.dumps(tokens_revoked_body)
        request: BoltRequest = BoltRequest(
            body=body, headers=self.build_headers(timestamp, body)
        )
        response = app.dispatch(request)
        assert response.status == 200

        # this should not be called when we have authorize
        assert self.mock_received_requests.get("/auth.test") is None
        sleep(1)  # wait a bit after auto ack()
        assert self.mock_received_requests["/chat.postMessage"] == 2
Beispiel #4
0
# ------------------------------------------------
# instead of slack_bolt in requirements.txt
import sys

sys.path.insert(1, "../..")
# ------------------------------------------------

import falcon
import logging
import re
from slack_bolt import App, Respond, Ack
from slack_bolt.adapter.falcon import SlackAppResource
from slack_sdk import WebClient

logging.basicConfig(level=logging.DEBUG)
app = App()


# @app.command("/bolt-py-proto", [lambda payload: payload["team_id"] == "T03E94MJU"])
def test_command(logger: logging.Logger, payload: dict, ack: Ack,
                 respond: Respond):
    logger.info(payload)
    ack("thanks!")
    respond(blocks=[{
        "type": "section",
        "block_id": "b",
        "text": {
            "type": "mrkdwn",
            "text": "You can add a button alongside text in your message. ",
        },
        "accessory": {
Beispiel #5
0
# ------------------------------------------------
# instead of slack_bolt in requirements.txt
import sys

sys.path.insert(1, "..")
# ------------------------------------------------

import logging

logging.basicConfig(level=logging.DEBUG)

from slack_bolt import App, Ack

app = App()


@app.middleware  # or app.use(log_request)
def log_request(logger, body, next):
    logger.debug(body)
    return next()


@app.command("/hello-bolt-python")
def test_command(body, client, ack, logger):
    logger.info(body)
    ack("I got it!")
    res = client.dialog_open(
        trigger_id=body["trigger_id"],
        dialog={
            "callback_id": "dialog-callback-id",
            "title": "Request a Ride",
Beispiel #6
0
import os
from dotenv import load_dotenv
from slack_bolt import App
import re

load_dotenv()

# Initializes your app with your bot token and signing secret
app = App(token=os.environ.get("SLACK_API_TOKEN"),
          signing_secret=os.environ.get("SLACK_SIGNING_SECRET"))


@app.message(":wave:")
def emoji_handler(payload, say):
    print(payload)
    say(f"Hey <@{payload['user']}>, {payload['text']}")


@app.message(re.compile("(hello|Hello)"))
def hello_handler(payload, say, context):
    say(f"Hello <@{payload['user']}>!\nHow are you?")


@app.event("reaction_added")
def reaction_added(payload, say, client):
    emoji = payload["reaction"]
    channel_id = payload["item"]["channel"]
    ts = payload["item"]["ts"]

    client.reactions_add(
        name="wave",
Beispiel #7
0
# ------------------------------------------------
# instead of slack_bolt in requirements.txt
import sys

sys.path.insert(1, "vendor")
# ------------------------------------------------

import logging

from slack_bolt import App
from slack_bolt.adapter.aws_lambda import SlackRequestHandler

# process_before_response must be True when running on FaaS
app = App(process_before_response=True)


@app.event("app_mention")
def handle_app_mentions(payload, say, logger):
    logger.info(payload)
    say("What's up?")


@app.command("/hello-bolt-python-lambda")
def respond_to_slack_within_3_seconds(ack):
    ack("Thanks!")


SlackRequestHandler.clear_all_log_handlers()
logging.basicConfig(format="%(asctime)s %(message)s", level=logging.DEBUG)

Beispiel #8
0
from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
from webhook_posting import WebhookPosting

posting_proc = WebhookPosting()

try:
    from dotenv import load_dotenv

    load_dotenv()
except ImportError:
    print(__file__ + r":環境変数の読込にdotenvを使用せず続行します。")

utan = App(
    token=os.getenv(r"UTAN_BOT_TOKEN"), signing_secret=os.getenv(r"UTAN_SIGNING_SECRET")
)

# utanに関連づけられたbotに対するメンションイベントを処理します
@utan.event(r"app_mention")
def read_mention_message(event, say):
    # イベントがトリガーされたチャンネルへ say() でメッセージを送信します

    text: str = event[r"text"]

    # ユーザーの入力テキストから、@メンション文を削除
    text = text.replace(text[text.find(r"<@") : (text.find(r">") + 1)], r"")

    # ユーザーの入力テキストから、改行を削除(対 Watson入力エラー)
    text = text.replace("\n", r"")
Beispiel #9
0
import logging

from slack_bolt import App

logging.basicConfig(level=logging.DEBUG)

# export SLACK_SIGNING_SECRET=***
# export SLACK_BOT_TOKEN=xoxb-***
app = App()


# Middleware
@app.middleware  # or app.use(log_request)
def log_request(logger, body, next):
    logger.info(body)
    return next()


# Events API: https://api.slack.com/events-api
@app.event("app_mention")
def event_test(say):
    say("What's up?")


# Interactivity: https://api.slack.com/interactivity
@app.shortcut("callback-id-here")
# @app.command("/hello-bolt-python")
def open_modal(ack, client, logger, body):
    # acknowledge the incoming request from Slack immediately
    ack()
    # open a modal
Beispiel #10
0
import logging
import os

from slack_bolt import App

logging.basicConfig(level=logging.DEBUG)
bolt_app = App()


@bolt_app.command("/hey-google-app-engine")
def hello(body, ack):
    user_id = body["user_id"]
    ack(f"Hi <@{user_id}>!")


from flask import Flask, request
from slack_bolt.adapter.flask import SlackRequestHandler

app = Flask(__name__)
handler = SlackRequestHandler(bolt_app)


@app.route("/_ah/warmup")
def warmup():
    # Handle your warmup logic here, e.g. set up a database connection pool
    return "", 200, {}


@app.route("/slack/events", methods=["POST"])
def slack_events():
    return handler.handle(request)
Beispiel #11
0
 def test_valid_multi_auth_secret_absence(self):
     with pytest.raises(BoltError):
         App(signing_secret="valid", client_id="111.222", client_secret=None)
Beispiel #12
0
 def test_valid_multi_auth(self):
     app = App(signing_secret="valid", client_id="111.222", client_secret="valid")
     assert app != None
Beispiel #13
0
 def test_valid_single_auth(self):
     app = App(signing_secret="valid", token="xoxb-xxx")
     assert app != None
Beispiel #14
0
 def test_listener_registration_error(self):
     app = App(signing_secret="valid", token="xoxb-xxx")
     with pytest.raises(BoltError):
         app.action({"type": "invalid_type", "action_id": "a"})(self.simple_listener)
Beispiel #15
0
from slack_bolt.adapter.socket_mode import SocketModeHandler
from os import environ

from miles_slack.slack_files import download_slack_file, upload_slack_file

BASE_API_URL = environ.get("BASE_API_URL").rstrip('/')
RCLONE_DRIVE = environ.get("RCLONE_DRIVE")
DRIVE_PATH_PREFIX = environ.get("DRIVE_PATH_PREFIX")
DRIVE_OUTPUT_DIR = environ.get("DRIVE_OUTPUT_DIR")
DRIVE_OUTPUT_LINK = environ.get("DRIVE_OUTPUT_LINK")

SLACK_BOT_TOKEN = environ.get("SLACK_BOT_TOKEN")
SLACK_SOCKET_TOKEN = environ.get("SLACK_SOCKET_TOKEN")


app = App(token=SLACK_BOT_TOKEN)

command_filter = re.compile(r'<@.*>(.*)')  # turns '<@U01KMRM2YTG> hello world' to 'hello world'
arg_filter = re.compile(r'\s(.*)')  # turns 'find Thomas Web' into 'Thomas Web'


@app.event("app_mention")
def event_test(say, event, client):
    say("Got it! Gimmie a hot sec....")
    logger.debug(f"Event received: {event}")
    channel = event.get("channel")
    command = command_filter.findall(event.get("text"))[0].strip()
    files = event.get("files")

    if files:
        for file in files:
Beispiel #16
0
# ------------------------------------------------
# instead of slack_bolt in requirements.txt
import sys

sys.path.insert(1, "..")
# ------------------------------------------------

import logging
import time

logging.basicConfig(level=logging.DEBUG)

from slack_bolt import App

app = App()


@app.middleware  # or app.use(log_request)
def log_request(logger, body, next):
    logger.debug(body)
    return next()


def ack_command(body, ack, logger):
    logger.info(body)
    ack("Thanks!")


def post_button_message(respond):
    respond(blocks=[{
        "type": "section",
Beispiel #17
0
    client_id=os.environ["SLACK_CLIENT_ID"],
    client_secret=os.environ["SLACK_CLIENT_SECRET"],
    scopes=[
        "channels:history",
        "commands",
        "groups:history",
        "im:history",
        "mpim:history",
        "chat:write",
    ],
    state_store=FileOAuthStateStore(expiration_seconds=600,
                                    base_dir="./data/states"),
    installation_store=FileInstallationStore(base_dir="./data/installations"),
)

app = App(signing_secret=os.environ["SLACK_SIGNING_SECRET"],
          oauth_settings=oauth_settings)
register_listeners(app)

podthai = [
    "UJM7Z5VGD", "U014KC3E9MF", "U0145C1684V", "U014CUFPNJG", "U01401MQJAJ"
]
podtrick = [
    "UJPDYE4VC", "U0146P6DJQJ", "U0145C1AG1K", "U0146VB99AP", "U014CUFJPC4"
]
dadpod = ["UJ9R66SHH", "U01401MPLUE", "U014CUFPARJ"]
kings = ["UJM7Z5VGD", "UJ9R66SHH", "UJPDYE4VC"]
test = ["UJPDYE4VC", "U01CFBL7Z8T"]

flask_app = Flask(__name__)
handler = SlackRequestHandler(app)
Beispiel #18
0
logger = logging.getLogger(__name__)
client_id, client_secret, signing_secret = (
    os.environ["SLACK_CLIENT_ID"],
    os.environ["SLACK_CLIENT_SECRET"],
    os.environ["SLACK_SIGNING_SECRET"],
)

app = App(
    signing_secret=signing_secret,
    installation_store=DjangoInstallationStore(
        client_id=client_id,
        logger=logger,
    ),
    oauth_settings=OAuthSettings(
        client_id=client_id,
        client_secret=client_secret,
        state_store=DjangoOAuthStateStore(
            expiration_seconds=120,
            logger=logger,
        ),
    ),
)


@app.event("app_mention")
def event_test(body, say, logger):
    logger.info(body)
    say("What's up?")

Beispiel #19
0
"""main"""
import os
from logging import config

from slack_bolt import App

config.fileConfig("logging.conf", disable_existing_loggers=False)

# ボットトークンと署名シークレットを使ってアプリを初期化します
app = App(token=os.environ.get("SLACK_BOT_TOKEN"),
          signing_secret=os.environ.get("SLACK_SIGNING_SECRET"))


@app.message("hello")
def message_hello(message, say):
    """message hello"""
    # イベントがトリガーされたチャンネルへ say() でメッセージを送信します
    say(f"Hey there <@{message['user']}>!")


# アプリを起動します
if __name__ == "__main__":
    app.start(port=int(os.environ.get("PORT", 3000)))
Beispiel #20
0
    # return BoltResponse(status=200, body="Thanks!")


def failure(args: FailureArgs) -> BoltResponse:
    return BoltResponse(status=args.suggested_status_code, body=args.reason)


app = App(
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET"),
    installation_store=FileInstallationStore(),
    oauth_settings=OAuthSettings(
        client_id=os.environ.get("SLACK_CLIENT_ID"),
        client_secret=os.environ.get("SLACK_CLIENT_SECRET"),
        scopes=[
            "app_mentions:read", "channels:history", "im:history", "chat:write"
        ],
        user_scopes=[],
        redirect_uri=None,
        install_path="/slack/install",
        redirect_uri_path="/slack/oauth_redirect",
        state_store=FileOAuthStateStore(expiration_seconds=600),
        callback_options=CallbackOptions(success=success, failure=failure),
    ),
)


@app.command("/hello-bolt-python")
def test_command(body, respond, client, ack, logger):
    logger.info(body)
    ack("Thanks!")
Beispiel #21
0
    from slack_bolt import App


def css(rgb_tuple):
    css3_db = CSS3_HEX_TO_NAMES
    names = []
    rgb_values = []
    for color_hex, color_name in css3_db.items():
        names.append(color_name)
        rgb_values.append(hex_to_rgb(color_hex))
    kdt_db = KDTree(rgb_values)
    distance, index = kdt_db.query(rgb_tuple)
    return names[index]


app = App(token=os.environ["TOKEN"], signing_secret=os.environ["SIGNING"])


def make_image(ack, say, command, body, client):
    ack()

    def respond(message):
        client.chat_postEphemeral(
            channel=body['channel_id'],
            user=body['user_id'],
            text=message.format(user=("<@" + body['user_id'] + ">")))

    text = body['text'].split()
    if len(text) == 1:
        url = text[0]
        width = None
Beispiel #22
0
from slack_bolt import App
import requests

from secrets import SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET, SNOOZE_CHANNEL_ID, GOOGLE_SHEETS_ENDPOINT
from util.allocations import get_allocations

app = App(
    token=SLACK_BOT_TOKEN,
    signing_secret=SLACK_SIGNING_SECRET,
)


@app.message("")
def Message(message, say):
    if message['text'].startswith("Carmel:"):
        app.client.reactions_add(
            channel=message['channel'],
            timestamp=message['ts'],
            name='party-carmel',
        )

    if message['text'].startswith("Soumil:"):
        app.client.reactions_add(
            channel=message['channel'],
            timestamp=message['ts'],
            name='partysoumil',
        )

    if message['text'].startswith("Chris:"):
        app.client.reactions_add(
            channel=message['channel'],
Beispiel #23
0
credentials are loaded from environment variables

welcome message / welcome channel are stored in TOML
"""

import os
import logging
import tomlkit

logging.basicConfig(level=logging.DEBUG)

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

# Install the Slack app and get xoxb- token in advance
app = App(token=os.environ["SLACK_OAUTH"])

# non-sensitive configuration information stored in config.toml
conf_filename = "config.toml"


def load_welcome_config():
    """
    loads the welcome message and channel from conf_filename
    can be easily expanded to load other config data
    """
    with open(conf_filename, 'r') as conf_file:
        config = tomlkit.loads(conf_file.read())
    return config["welcome"]

Beispiel #24
0
 def test_signing_secret_absence(self):
     with pytest.raises(BoltError):
         App(signing_secret=None, token="xoxb-xxx")
     with pytest.raises(BoltError):
         App(signing_secret="", token="xoxb-xxx")
Beispiel #25
0
    engine=engine,
    logger=logger,
)

try:
    engine.execute("select count(*) from slack_bots")
except Exception as e:
    installation_store.metadata.create_all(engine)
    oauth_state_store.metadata.create_all(engine)
# update ngrok/production links in slash commands and enable events page
# Initializes your app with your bot token and signing secret
app = App(
    logger=logger,
    signing_secret=signing_secret,
    installation_store=installation_store,
    oauth_settings=OAuthSettings(
        client_id=client_id,
        client_secret=client_secret,
        state_store=oauth_state_store,
    ),
)


@app.middleware
def log_request(logger: logging.Logger, body: dict, next: Callable):
    logger.debug(body)
    return next()


def extract_subtype(body: dict, context: BoltContext, next: Callable):
    context["type"] = body.get("event", {}).get("type", None)
    next()
Beispiel #26
0
 def test_valid_single_auth(self):
     app = App(signing_secret="valid", client=self.web_client)
     assert app != None
Beispiel #27
0
    def test_member_join_left_events(self):
        app = App(
            client=self.web_client,
            signing_secret=self.signing_secret,
            authorize=authorize,
        )

        join_event_body = {
            "token": "verification_token",
            "team_id": "T_SOURCE",
            "enterprise_id": "E_SOURCE",
            "api_app_id": "A111",
            "event": {
                "type": "member_joined_channel",
                "user": "******",  # not self
                "channel": "C111",
                "channel_type": "C",
                "team": "T_INSTALLED",
                "inviter": "U222",
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
            "authorizations": [
                {
                    "enterprise_id": "E_INSTALLED",
                    "team_id": "T_INSTALLED",
                    "user_id": "W111",
                    "is_bot": True,
                    "is_enterprise_install": False,
                }
            ],
        }

        left_event_body = {
            "token": "verification_token",
            "team_id": "T_SOURCE",
            "enterprise_id": "E_SOURCE",
            "api_app_id": "A111",
            "event": {
                "type": "member_left_channel",
                "user": "******",  # not self
                "channel": "C111",
                "channel_type": "C",
                "team": "T_INSTALLED",
            },
            "type": "event_callback",
            "event_id": "Ev111",
            "event_time": 1599616881,
            "authorizations": [
                {
                    "enterprise_id": "E_INSTALLED",
                    "team_id": "T_INSTALLED",
                    "user_id": "W111",
                    "is_bot": True,
                    "is_enterprise_install": False,
                }
            ],
        }

        @app.event("member_joined_channel")
        def handle_app_mention(say):
            say("What's up?")

        @app.event("member_left_channel")
        def handle_app_mention(say):
            say("What's up?")

        timestamp, body = str(int(time())), json.dumps(join_event_body)
        request: BoltRequest = BoltRequest(
            body=body, headers=self.build_headers(timestamp, body)
        )
        response = app.dispatch(request)
        assert response.status == 200
        assert_auth_test_count(self, 1)

        timestamp, body = str(int(time())), json.dumps(left_event_body)
        request: BoltRequest = BoltRequest(
            body=body, headers=self.build_headers(timestamp, body)
        )
        response = app.dispatch(request)
        assert response.status == 200

        sleep(1)  # wait a bit after auto ack()
        # the listeners should not be executed
        assert self.mock_received_requests["/chat.postMessage"] == 2
Beispiel #28
0
 def test_token_absence(self):
     with pytest.raises(BoltError):
         App(signing_secret="valid", token=None)
     with pytest.raises(BoltError):
         App(signing_secret="valid", token="")
Beispiel #29
0
# ------------------------------------------------
# instead of slack_bolt in requirements.txt
import sys

sys.path.insert(1, "../..")
# ------------------------------------------------

from slack_bolt import App
from slack_bolt.adapter.starlette import SlackRequestHandler

app = App()


@app.event("app_mention")
def handle_app_mentions(body, say, logger):
    logger.info(body)
    say("What's up?")


app_handler = SlackRequestHandler(app)

from starlette.applications import Starlette
from starlette.requests import Request
from starlette.routing import Route


async def endpoint(req: Request):
    return await app_handler.handle(req)


api = Starlette(
Beispiel #30
0
import os
import re
import CONSTS

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

app = App(token=os.environ.get("SLACK_BOT_TOKEN"))

MANAGER = os.environ.get("MANAGER", "the manager")
MAX_MESSAGE_LEN = os.environ.get("MAX_MESSAGE_LEN", CONSTS.MAX_MESSAGE_LEN)
LINK_PATTERN = re.compile('<.+?\|(.+?)>')


# Check liveness
@app.event("app_mention")
def event_test(say):
    say("Hi there!")


def strip_links(message):
    for match in LINK_PATTERN.finditer(message):
        message = re.sub(LINK_PATTERN, match.groups()[0], message, 1)
    return message


@app.event("message")
def make_it_short(client, message):
    channel_id = message["channel"]
    if message["channel_type"] in ["group", "channel"
                                   ] and "thread_ts" not in message: