danludwig
danludwig

Reputation: 47375

Slack app opening new modal after previous modal submit is inconsistent, why?

I created a new free slack workspace to learn the slack bot app API. I have an action handler that listens to a global shortcut and opens an input modal in response. There is another action handler that listens to the modal input submit callback_id, does some work, and then uses the trigger_id to open another modal.

app.view('do_thing_b.submit', async (slack) => {

  try {
    await slack.ack()
    console.info(`Received modal submit`)

    // TODO: actual work to save the data

    const view = {
      type: 'modal',
      callback_id: 'do_thing_b.received_submission',
      title: {
        text: 'Thing B Done',
        type: 'plain_text',
      },
      blocks: [
        {
          type: 'section',
          text: {
            text: 'My Plain Text',
            type: 'plain_text',
            emoji: true,
          },
        },
      ],
      close: {
        text: 'Close',
        type: 'plain_text'
      }
    }

    const openViewParams = {
      trigger_id: slack.body.trigger_id,
      view,
    }
    console.log(`Opening Done Modal with open view params ${JSON.stringify(openViewParams)}`)
    const result = await slack.client.views.open(openViewParams)
    console.log(`=============================== Done modal opened?`)

    console.debug(result)
  }
  catch (err) {
    console.error(`Error submitting Thing B modal:`)
    console.error(err)
  }
})

The inconsistency is that this works as expected only when running the app in SocketMode against local code.

When I deploy the app and disable socket mode, the form submission never triggers the second modal to be displayed. I am able to see in the logs the same evidence of code behaviors that I see when running locally. The await slack.client.views.open(openViewParams) invocation succeeds and the result log indicates a 200 ok response from slack.

I have the same request URL set for events and interactivity as I do for the global shortcut. In fact, I also have a slash command that posts an ephemeral help screen to the user, similar to what the /polly command does. That message contains a button that also triggers this modal form to be displayed. Clicking that button to open the modal locally shows the same exact behavior: it works as expected when running locally with the app in Socket Mode, but never shows the followup modal after submission.

Follow-up question:

If this is not supposed to be allowed, how should slack apps respond to data input submission events? I also tried pushing a new view onto the modal, but closing the submit confirmation view just slides back to the original form, where I want it to close out the entire model. Do I need to send the user an ephemeral message to follow up after their data input submission?

Upvotes: 3

Views: 2942

Answers (1)

danludwig
danludwig

Reputation: 47375

Turns out I didn't need to open a modal, all I needed to do was update the existing modal. Instead of calling await slack.client.views.open with a trigger_id, I should have done this:

app.view('do_thing_b.submit', async (slack) => {

  try {
    console.info(`Received modal submit`)

    // TODO: actual work to save the data

    const view = {
      type: 'modal',
      callback_id: 'do_thing_b.received_submission',
      title: {
        text: 'Thing B Done',
        type: 'plain_text',
      },
      blocks: [
        {
          type: 'section',
          text: {
            text: 'My Plain Text',
            type: 'plain_text',
            emoji: true,
          },
        },
      ],
      close: {
        text: 'Close',
        type: 'plain_text'
      }
    }

    const result = await slack.ack({
      response_action: 'update', view
    })

  }
  catch (err) {
    console.error(`Error submitting Thing B modal:`)
    console.error(err)
  }
})

The docs I kept missing are these:

Upvotes: 6

Related Questions