Search code examples
modal-dialogslackbolt

How to pass the value of input to the next view of a modal in slack bolt framework?


I'm building a Slack API using bolt (on glitch). I'm new to this so and not sure about how to do this particular idea.

Using a slash command I open a modal that lists three radio inputs and has an action button that will use client.views.update to present a multi-line input.

I would like the option chosen to be the initial value of the multi-line code.

// this is required: github.com/slackapi/bolt

app.command("/slashcommand", async ({ ack, payload, context }) => {
  // Acknowledge the command request
  ack();

  try {
    const result = app.client.views.open({
      token: context.botToken,
      // Pass a valid trigger_id within 3 seconds of receiving it
      trigger_id: payload.trigger_id,
      // View payload
      view: {
        type: "modal",
        callback_id: 'modal_1',
        title: {
          type: "plain_text",
          text: "Initiate Feedback",
          emoji: true
        }, /*
        submit: {
          type: "plain_text",
          text: "Submit",
          emoji: true
        }, */
        close: {
          type: "plain_text",
          text: "Cancel",
          emoji: true
        },
        blocks: [
          {
            type: "context",
            elements: [
              {
                type: "mrkdwn",
                text:
                  "Modal first view"
              }
            ]
          },
          {
            type: "divider"
          },
          {
            type: "section",
            block_id: 'radio_block',
            text: {
              type: "mrkdwn",
              text: "Select from one of the following options:"
            },
            accessory: {
              type: "radio_buttons",
              action_id: 'radio_input',
              initial_option: {
                text: {
                  type: "plain_text",
                  text: "One"
                },
                value: "one",
                description: {
                  type: "plain_text",
                  text: "describe one"
                }
              },
              options: [
                {
                  text: {
                    type: "plain_text",
                    text: "One"
                  },
                  value: "one",
                  description: {
                    type: "plain_text",
                    text: "describe one"
                  }
                },
                {
                  text: {
                    type: "plain_text",
                    text: "Two"
                  },
                  value: "two",
                  description: {
                    type: "plain_text",
                    text: "describe two"
                  }
                },
                {
                  text: {
                    type: "plain_text",
                    text: "Three"
                  },
                  value: "three",
                  description: {
                    type: "plain_text",
                    text: "describe three"
                  }
                }
              ]
            }
          },
          {
            type: "actions",
            elements: [
              {
                type: "button",
                text: {
                  type: "plain_text",
                  text: "Next",
                  emoji: true
                },
                action_id: "next_1"
              }
            ]
          }
        ]
      }
    });
    console.log(result);
  } catch (error) {
    console.error(error);
  }
});

// Listen for a button invocation with action_id `next_1` (assume it's inside of a modal)
app.action("next_1", async ({ ack, body, context }) => {

  // VALUE FROM RADIO INPUT
  // const val = Radio input value;


  // Acknowledge the button request
  ack();

  try {
    const result = app.client.views.update({
      token: context.botToken,
      // Pass the view_id
      view_id: body.view.id,
      // View payload with updated blocks
      view: {
        type: "modal",
        // View identifier
        callback_id: 'feed_1',
        title: {
          type: "plain_text",
          text: "Share Feedback: message"
        },
        blocks: [
          {
            type: "section",
            text: {
              type: "plain_text",
              text: 'You choose '
            }
          },
          {
            type: "input",
            element: {
              type: "plain_text_input",
              // HERE IS WHERE THE RADIO OPTION GOES
              initial_value: `One `,
              multiline: true
            },
            label: {
              type: "plain_text",
              text: "Message",
              emoji: true
            }
          }
        ],
        submit: {
          type: "plain_text",
          text: "Submit"
        }
      }
    });
    console.log(result);
  } catch (error) {
    console.error(error);
  }
});

Solution

  • Ok figured this out finally! 1) make sure your radio buttons are not in any input blocks! 2) output your returned payload in your action using body.actions

    once you see what your returning it will be easier to target that value.

    '''

    app.action("next_1", async ({ ack, body, context }) => {
    
    // Result of option selected
        const val = JSON.stringify(body['actions'][0]);
    // see the values
        console.log(val);
    // Acknowledge the button request
        ack();
    
    });
    

    '''

    Further details: https://api.slack.com/reference/interaction-payloads/actions