Bolt-js: Submission values not accessible through action object

Created on 13 Sep 2019  路  12Comments  路  Source: slackapi/bolt-js

Description

After receiving a submission event, the submission object is inaccessible on the action object.

What type of issue is this? (place an x in one of the [ ])

  • [x] bug
  • [ ] enhancement (feature request)
  • [ ] question
  • [ ] documentation related
  • [ ] testing related
  • [ ] discussion

Requirements (place an x in each of the [ ])

  • [x] I've read and understood the Contributing guidelines and have done my best effort to follow them.
  • [x] I've read and agree to the Code of Conduct.
  • [x] I've searched for any related issues and avoided creating a duplicate issue.

Bug Report

When trying to access content from a dialog submission, both the action and body objects don't provide an accessor for the submission values.

Steps to reproduce:

  1. Receive an action for a submitted dialog
  2. Try to access the submission values

Expected result:

Values are accessible

Actual result:

Values are inaccessible and requires casting action to a {[key: string]: any} object, which makes linters angry.

Property 'submission' does not exist on type 'ButtonAction | UsersSelectAction | StaticSelectAction | ConversationsSelectAction | ChannelsSelectAction | ExternalSelectAction | OverflowAction | DatepickerAction | ButtonClick | MenuSelect | DialogSubmitAction | MessageAction'.

Workaround

By using the generic in your signature, you're able to access submission (credit to @shanedewael)

app.action<DialogSubmitAction>({ callback_id: callbackId }, ({ ack, action, body, payload }) => {
  const { submission } = action;
});

All 12 comments

@aoberoi I feel like I'm doing something really stupid here. Any chance you could verify this? Pasting the example from the Slack example docs still results in an error:
image

@SpencerKaiser have you been able to receive standard, block-level actions (ones that don't have a callback id) in these newer releases of bolt? I've been banging my head against the wall all day and still couldn't get my app to receive the events. I see the POST request coming to the server, but it's almost like bolt is swallowing the action. I never even see a simple console.log() message I added in the listener.

@shauntarves I had all sorts of issues setting it up, but here are my biggest tips:

  1. make sure your app is configured to send events to the right endpoint (/slack/events)
  2. pass a LogLevel.DEBUG Into the app initializer so you can see if the app received an action but didn鈥檛 act on it
  3. you鈥檙e passing a dictionary (like the one I have above) into the app.action method; it鈥檒l accept a string and then do nothing with it
  4. Double check your callback_id everywhere to make sure they鈥檙e consistent
  5. Check the ngrok portal thing (usually 127.0.0.1:4040) and take a look at the request

If none of that works, post back here and I鈥檒l take a look at what I did

@SpencerKaiser Thank you for your help. Point 3 from above was my issue - I wasn't using the dictionary object.

@SpencerKaiser I wasn't able to reproduce this and didn't need to type cast the DialogSubmitAction.

Did your steps in https://github.com/slackapi/bolt/issues/251#issuecomment-531420665 resolve your issues? If not, I can help try to troubleshoot what's happening, but the construction of your method looks correct to me.

@shanedewael Those steps were mostly just general debugging around receiving an event via an action, so they don't help with this issue.

Just retested after running npm update @slack/bolt and didn't have any success:

Screen Shot 2019-10-02 at 11 06 31 AM

Error from compiler:

[build:watch] src/Commands/sev.ts:49:13 - error TS2339: Property 'submission' does not exist on type 'ButtonAction | UsersSelectAction | StaticSelectAction | ConversationsSelectAction | ChannelsSelectAction | ExternalSelectAction | OverflowAction | DatepickerAction | ButtonClick | MenuSelect | DialogSubmitAction | MessageAction'.
[build:watch] 
[build:watch] 49     const { submission } = action;

Is there something I'm doing wrong there?

Sorry, I had something wrong with the types that I was getting in VSCode and I'm able to reproduce this now. For now, the workaround you highlighted works or I prefer using generics:

app.action<DialogSubmitAction>({ callback_id: 'YOUR_CALLBACK_ID' }, async ({ ack, action, body }) => {
   const { submission } = action;
   // Some other stuff
});

In the future, one solution may be moving dialog payloads into their own dialog() method like @seratch outlined in #263 or finding a different way to flow the types.

I did something similar in my actual implementation:

const { submission } = action as DialogSubmitAction;

Without the typecasting there I get an error...

(I forgot to add the actual generic. I updated the code now 馃槄)

Haha no worries! Just updated my workaround in the issue description.

Same comment as with #252. I feel like a change to the docs should be made before this is closed.

sorry for jumping in so late, I have a few thoughts to add.

@SpencerKaiser if you're using TypeScript for your project, i def recommend using the generic parameter as @shanedewael and you figured out. however, there's still a way to do this from just JavaScript or when you don't want to specify a generic parameter. Example below (once again cribbed from the docs):

app.action({ callback_id: 'ticket_submit' }, ({ action, ack }) => {
  // it鈥檚 a valid email, accept the submission
  if (action.submission !== undefined && isEmail.test(action.submission.email)) {
      ack();
  } else {
      /* ... */
  }
});

the difference is just adding action.submission !== undefined && in the conditional check. this works because the type of action is the union of a bunch of types (as you see in the error message), but only DialogSubmitAction actually has a submission property. so as far as Bolt knows, the listener you're defining could be called any any of those kinds of actions - it has no idea that you've been diligent enough to make sure that callback_id is only set on dialogs. by adding the conditional, you've let the typechecker narrow down the type of action to just DialogSubmitAction.

@shanedewael I think we should make this adjustment in the docs. what do you think?

Was this page helpful?
0 / 5 - 0 ratings