slackapi / bolt-python

A framework to build Slack apps using Python
https://tools.slack.dev/bolt-python/
MIT License
1.08k stars 248 forks source link

Unable to Send a Modal from Lambda using bolt SDK #809

Closed bishwabikash closed 1 year ago

bishwabikash commented 1 year ago

I am trying to trigger a modal when a user sends /leavereq or triggers a shortcut from the channel. However, even though I see the ack message successfully, I am unable to figure out why the views_open part of the code is not triggering any modal into the slack workspace. I am sure this is something silly that I am doing, but there is no approach showed for running modal using bolt-python (using aws Lambda)

The back-end is using AWS Lambda.

using bolt and blockkit-builder (UI)

Reproducible in:

slack-bolt==1.16.1 slack-sdk==3.19.5 python 3.8 x86_64

The slack_bolt version

(Paste the output of pip freeze | grep slack)

Python runtime version

(Paste the output of python --version)

OS info (AWS Lambda)

Steps to reproduce:

Source:

secrets=get_secret()
app = App(
    token=secrets["SLACK_BOT_TOKEN"],
    signing_secret=secrets["SLACK_SIGNING_SECRET"],
)

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

@app.command('/slack/events')
def handle_event():
    print("slack/events")
    return

@app.shortcut("init_leave_req")
def init_leave_req(ack, shortcut, client, body, logger):
    logger.info(body)
    ack("Initated Leave request {}",datetime.date)
    client.views_open(
        trigger_id=shortcut["trigger_id"],
        view={
            "type": "modal",
            "callback_id":"leave_req_modal",
            "title": {
                "type": "plain_text",
                "text": "Leave Request Form",

            },
            "submit": {
                "type": "plain_text",
                "text": "Submit",

            },
            "close": {
                "type": "plain_text",
                "text": "Cancel",

            },
            "blocks":[ 
                {
                    "type": "header",
                    "text": {
                        "type": "plain_text",
                        "text": "Leave Request Submission Form",

                    }
                },
                {
                    "type": "divider"
                },
                {
                    "type": "divider"
                },
                {
                    "type": "input",
                    "element": {
                        "type": "plain_text_input",
                        "action_id": "user_alias"
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Enter your Alias",

                    }
                },
                {
                    "type": "input",
                    "element": {
                        "type": "static_select",
                        "placeholder": {
                            "type": "plain_text",
                            "text": "Select the Leave Type",

                        },
                        "options": [
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Casual Leave",

                                },
                                "value": "Casual_Leave"
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Sick Leave",

                                },
                                "value": "Sick_leave"
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Mandatory leave",

                                },
                                "value": "Mandatory_leave"
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Time-Off in Liew",

                                },
                                "value": "TOIL"
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Annual Leave",

                                },
                                "value": "Annual_Leave"
                            }
                        ],
                        "action_id": "leave_type"
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Select Leave Type",

                    }
                },
                {
                    "type": "input",
                    "element": {
                        "type": "datepicker",
                        "initial_date": datetime.today().strftime("%Y-%m-%d"),
                        "placeholder": {
                            "type": "plain_text",
                                    "text": "Select a date",

                        },
                        "action_id": "leave_from"
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Leave From",

                    }
                },
                {
                    "type": "input",
                    "element": {
                        "type": "datepicker",
                        "initial_date": datetime.today().strftime("%Y-%m-%d"),
                        "placeholder": {
                            "type": "plain_text",
                                    "text": "Select a date",

                        },
                        "action_id": "leave_to"
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Leave To",

                    }
                }
            ]
        },
    )

Expected result:

Modal to be shown on slack as a response.

Actual result:

No Modal output to slack

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you are agreeing to those rules.

seratch commented 1 year ago

Hi @bishwabikash, thanks for asking the question! I've checked your code in my sample app, and it works without any issues. The only missing things were:

Also, please double-check Request URL in your app settings under http://api.slack.com/apps (especially the one on the "Interactivity & Shortcuts" page)

FYI, here is the code I've verified it working:

from datetime import datetime

@app.shortcut("init_leave_req")
def foo(ack, shortcut, client):
    ack()
    client.views_open(
        trigger_id=shortcut["trigger_id"],
        view={
            "type": "modal",
            "callback_id": "leave_req_modal",
            "title": {
                "type": "plain_text",
                "text": "Leave Request Form",
            },
            "submit": {
                "type": "plain_text",
                "text": "Submit",
            },
            "close": {
                "type": "plain_text",
                "text": "Cancel",
            },
            "blocks": [
                {
                    "type": "header",
                    "text": {
                        "type": "plain_text",
                        "text": "Leave Request Submission Form",
                    },
                },
                {"type": "divider"},
                {"type": "divider"},
                {
                    "type": "input",
                    "element": {"type": "plain_text_input", "action_id": "user_alias"},
                    "label": {
                        "type": "plain_text",
                        "text": "Enter your Alias",
                    },
                },
                {
                    "type": "input",
                    "element": {
                        "type": "static_select",
                        "placeholder": {
                            "type": "plain_text",
                            "text": "Select the Leave Type",
                        },
                        "options": [
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Casual Leave",
                                },
                                "value": "Casual_Leave",
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Sick Leave",
                                },
                                "value": "Sick_leave",
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Mandatory leave",
                                },
                                "value": "Mandatory_leave",
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Time-Off in Liew",
                                },
                                "value": "TOIL",
                            },
                            {
                                "text": {
                                    "type": "plain_text",
                                    "text": "Annual Leave",
                                },
                                "value": "Annual_Leave",
                            },
                        ],
                        "action_id": "leave_type",
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Select Leave Type",
                    },
                },
                {
                    "type": "input",
                    "element": {
                        "type": "datepicker",
                        "initial_date": datetime.today().strftime("%Y-%m-%d"),
                        "placeholder": {
                            "type": "plain_text",
                            "text": "Select a date",
                        },
                        "action_id": "leave_from",
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Leave From",
                    },
                },
                {
                    "type": "input",
                    "element": {
                        "type": "datepicker",
                        "initial_date": datetime.today().strftime("%Y-%m-%d"),
                        "placeholder": {
                            "type": "plain_text",
                            "text": "Select a date",
                        },
                        "action_id": "leave_to",
                    },
                    "label": {
                        "type": "plain_text",
                        "text": "Leave To",
                    },
                },
            ],
        },
    )
bishwabikash commented 1 year ago

Thanks @seratch , I managed to get this working last night after some tinkering. However, the fresh behaviour that I see is an error while trying to submit the modal. (running on AWS Lambda)

Screenshot 2023-01-28 at 11 57 34 PM

even with a lazy_listener, I am seeing this error.

Screenshot 2023-01-28 at 11 58 58 PM

Not sure if I am doing anything wrong. This is my first ever attempt at developing a slack app.

seratch commented 1 year ago

@bishwabikash In response to a view_submission request (meaning app.view() in bolt apps), either ack() or ack({ response_action: "...", ...}) is allowed to return. Your code tries to send the "Submission done" string, but it does not work. You cannot post a message using ack(string) in app.view() handlers.

msrshahrukh100 commented 1 year ago

@bishwabikash I have this issue as well with lazy listeners.

seratch commented 1 year ago

@bishwabikash Thanks for your ❤️ reaction! Let me close this issue now. @msrshahrukh100 ack() is not available in lazy listeners. Also, when you handle a modal data submission, sending a reply using ack() does not work. If you have a specific question, please feel free to open a new SDK question issue on your issue!