Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Adding block elements through code make actions disable #2138

Closed
bilalashraf1710 opened this issue Jun 19, 2024 · 16 comments
Closed

Bug: Adding block elements through code make actions disable #2138

bilalashraf1710 opened this issue Jun 19, 2024 · 16 comments
Labels
auto-triage-skip Prevent this issue from being closed due to lack of activity bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented server-side-issue

Comments

@bilalashraf1710
Copy link

bilalashraf1710 commented Jun 19, 2024

(Filling out the following with as much detail as you can provide will help us solve your issue sooner.)

@slack/bolt version

^3.17.1

Your App and Receiver Configuration

const receiver = new ExpressReceiver({
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  stateSecret: process.env.SLACK_STATE_SECRET,
  app: expressApp,
  scopes: SLACK_APP_SCOPES,
  installerOptions: {
    userScopes: USER_SCOPES,
    directInstall: true,
    callbackOptions: { success: installer.success },
  },
  installationStore: isOffline ? new FileInstallationStore() : new DynamoDBInstallationStore(),
  // processBeforeResponse: true, // Required to avoid latency issues with AWS Lambda
})

const app = new App({
  receiver,
  logLevel: LogLevel[process.env.LOG_LEVEL] || LogLevel.WARN,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
})

Node.js runtime version

20.12.2

Steps to reproduce:

(Share the commands to run, source code, and project settings)

I am fetching Slack blocks through code and sending them to GPT to refine the messages. The refined blocks are well-formatted and work fine with Block Kit. However, when the blocks contain user_id elements within a rich-text box, buttons on the screen become unresponsive. Interestingly, if I manually edit the rich-text block by adding a space, the buttons start working. Could you please help refine this?

Expected result:

Buttons should work fine without editing the message

Actual result:

Buttons are not working and I can see the warning icon's next to button and submit button also not working.

@filmaj filmaj added needs info An issue that is claimed to be a bug and hasn't been reproduced, or otherwise needs more info and removed untriaged labels Jun 19, 2024
@filmaj
Copy link
Contributor

filmaj commented Jun 19, 2024

Could you please provide some code to reproduce the issue?

@bilalashraf1710
Copy link
Author

bilalashraf1710 commented Jun 20, 2024

@filmaj Please check the code and video
1- I opened a modal on command enter
2- I write a simple text and moved to view-2 ( now the submit button is working )
3- When I tagged to someone and move to view-2 ( submit button not working )

app.shortcut(/^ask_anything_.*/, async function ({ ack, client, body, logger }) {
      try {
        await ack()
        await client.views.open({
          trigger_id: body.trigger_id,
          view: {
            type: "modal",
            callback_id: "view_1_callback",
            title: { type: "plain_text", text: "View 1" },
            submit: { type: "plain_text", text: "Let's Go" },
            blocks: [
              {
                type: "input",
                block_id: "rich_text_block",
                label: {
                  type: "plain_text",
                  text: "Refined Text",
                },
                element: {
                  type: "rich_text_input",
                  action_id: "rich_text_input_action",
                },
              },
            ],
          },
        })
      } catch (e) {
        logger.warn("Error Occurred - aaa - aaaCommand", e)
      }
    })
app.view("view_1_callback", async function ({ view, ack, client }) {
    const modal = {
      type: "modal",
      callback_id: "view_2_callback",
      external_id: "123",
      title: { type: "plain_text", text: "View 2" },
      submit: { type: "plain_text", text: "Let's Go" },
      blocks: [
        {
          type: "input",
          block_id: "rich_text_block",
          label: {
            type: "plain_text",
            text: "Refined Text",
          },
          element: {
            type: "rich_text_input",
            action_id: "rich_text_input_action",

            initial_value: {
              type: "rich_text",
              elements: view.state.values?.rich_text_block?.rich_text_input_action?.rich_text_value?.elements,
            },
          },
        },
      ],
    }

    await ack({ response_action: "update", view: thinkingModal })
    await client.views.update({ external_id: thinkingModal.external_id, view: modal })
  })
 app.view("view_2_callback", async function ({ view, ack, client }) {

    await ack({
      response_action: "update",
      view: {
        type: "modal",
        callback_id: "view_3_callback",
        title: { type: "plain_text", text: "View 3" },
        submit: { type: "plain_text", text: "Let's Go" },
        blocks: [],
      },
    })
  })
Screen.Recording.2024-06-20.at.5.20.10.PM.mov
Screen.Recording.2024-06-20.at.5.20.48.PM.mov

@filmaj
Copy link
Contributor

filmaj commented Jun 21, 2024

@bilalashraf1710 what is the value of thinkingModal in the code you shared? I am trying to set up an app to reproduce the issue - without a reproduction, I cannot help.

@filmaj
Copy link
Contributor

filmaj commented Jun 21, 2024

Related (or maybe separate issue): the callback to your first view submission seems odd: it is trying to update two modals, the current modal (view_1) as well as a "thinking modal". That is not possible, as there can only be 1 modal shown to the user at a time. That may be why you are seeing the odd "flashing" UI that your video displays.

If I modify your view_1_callback handler to just update the current modal's title, and propagate the rich text input's elements to the new view in an update call, it works fine, even with user mentions:

app.view('view_1_callback', async ({ ack, body, view, client, logger }) => {
  const modal = { // <-- in your code snippet above, this object was not being used
    type: "modal",
    callback_id: "view_2_callback",
    external_id: "123",
    title: { type: "plain_text", text: "View 2" },
    submit: { type: "plain_text", text: "Let's Go" },
    blocks: [
      {
        type: "input",
        block_id: "rich_text_block",
        label: {
          type: "plain_text",
          text: "Refined Text",
        },
        element: {
          type: "rich_text_input",
          action_id: "rich_text_input_action",

          initial_value: {
            type: "rich_text",
            elements: view.state.values?.rich_text_block?.rich_text_input_action?.rich_text_value?.elements,
          },
        },
      },
    ],
  }

  await ack({ response_action: "update", view: modal }) // <--- in this code snippet, the new modal is now being used
  // await client.views.update({ external_id: thinkingModal.external_id, view: modal }) // <--- this should not work, as only a single modal can be viewed at a time. I commented this out in my example.

@filmaj filmaj added the question M-T: User needs support to use the project label Jun 21, 2024
@bilalashraf1710
Copy link
Author

@filmaj I intentionally added that thinking modal because view-1 rich-text sharing the same context with view-2 rich-text.

In my case, I do some DB calls while showing the Thinking modal to the user.

@filmaj
Copy link
Contributor

filmaj commented Jun 21, 2024

The following code worked fine for me (I used a setTimeout to mimic a long-running background operation like your DB operations):

app.command('/post', async ({ ack, say, body, client, logger }) => {
  await ack();
  await client.views.open({
    trigger_id: body.trigger_id,
    view: {
      type: "modal",
      callback_id: "view_1_callback",
      title: { type: "plain_text", text: "View 1" },
      submit: { type: "plain_text", text: "Let's Go" },
      blocks: [
        {
          type: "input",
          block_id: "rich_text_block",
          label: {
            type: "plain_text",
            text: "Refined Text",
          },
          element: {
            type: "rich_text_input",
            action_id: "rich_text_input_action",
          },
        },
      ],
    },
  })
});
app.view('view_1_callback', async ({ ack, body, view, client, logger }) => {
  const thinkingModal = {
    type: "modal",
    callback_id: "thinking",
    external_id: "thinking",
    title: { type: "plain_text", text: "Thinking!!!" },
    blocks: [
      {
        type: "section",
        text: {
          type: "plain_text",
          text: "Processing, please wait",
        }
      }
    ]
  }
  const modal = {
    type: "modal",
    callback_id: "view_2_callback",
    external_id: "123",
    title: { type: "plain_text", text: "View 2" },
    submit: { type: "plain_text", text: "Let's Go" },
    blocks: [
      {
        type: "input",
        block_id: "rich_text_block",
        label: {
          type: "plain_text",
          text: "Refined Text",
        },
        element: {
          type: "rich_text_input",
          action_id: "rich_text_input_action",

          initial_value: {
            type: "rich_text",
            elements: view.state.values?.rich_text_block?.rich_text_input_action?.rich_text_value?.elements,
          },
        },
      },
    ],
  }

  await ack({ response_action: "update", view: thinkingModal })
  await new Promise((res) => setTimeout(res, 5000)); // wait for 5 seconds
  await client.views.update({ external_id: thinkingModal.external_id, view: modal })
});

Here's a gif of the code in action:

GIF Recording 2024-06-21 at 8 16 36 AM

Make sure you use unique external_id, callback_id, as well as unique IDs for every block element's block_id and action_id

@bilalashraf1710
Copy link
Author

bilalashraf1710 commented Jun 21, 2024

@filmaj when you navigate to view-2. Can you please press the Lets Go button and see if it works? The issue is Let's Go button was not working until you edit the message on view-2. if you have any other button that would not work too

@filmaj
Copy link
Contributor

filmaj commented Jun 21, 2024

Hmm I see what you mean. Indeed, if there's a user mention in the rich text input and you go to submit it again, there is an error. There is a need to slightly modify the text payload in order for it to submit:

GIF Recording 2024-06-21 at 8 38 38 AM

Interestingly, it seems to me like this is an error from the Slack client itself, as the submit of view 2 errors out on the client side.

Thank you for your patience working with me through this. I think I see the problem, too. If you open the Slack client devtools (it is just like a browser!), when you go to submit the view 2 modal the first time, here is the payload sent to the underlying Slack API views.submit:

state: {"values":{"rich_text_block":{"rich_text_input_action":{"type":"rich_text_input","rich_text_value":{"type":"rich_text","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"hi "},{"type":"user","userId":"U05T59XL1E3"}]}]}}}}}

The error returned by this API is:

{
    "ok": false,
    "error": "invalid_arguments",
    "response_metadata": {
        "messages": [
            "[ERROR] failed to match any allowed schemas [json-pointer:\/state\/values\/rich_text_block\/rich_text_input_action\/rich_text_value]",
            "[ERROR] missing required field: user_id [json-pointer:\/state\/values\/rich_text_block\/rich_text_input_action\/rich_text_value\/elements\/0\/elements\/1]"
        ]
    }
}

Note: the view payload does not include user_id but rather userId for the user mention 👀

If you then change the contents of the rich text input, it works! And the payload to the views.submit API is:

state: {"values":{"rich_text_block":{"rich_text_input_action":{"type":"rich_text_input","rich_text_value":{"type":"rich_text","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"h "},{"type":"user","user_id":"U05T59XL1E3"}]}]}}}}}

Correct user_id parameter, so no error.

Thanks for reporting this. I will raise this internally.

@filmaj filmaj added bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented server-side-issue auto-triage-skip Prevent this issue from being closed due to lack of activity and removed question M-T: User needs support to use the project needs info An issue that is claimed to be a bug and hasn't been reproduced, or otherwise needs more info labels Jun 21, 2024
@bilalashraf1710
Copy link
Author

Hmm Interesting. When I print the elements on view-2 then it show user_id in a correct way.

@alessio-ragni
Copy link

Hi Slack Team and @filmaj 👋
Do you have an update here? This is something that is preventing us to go live with our product and we would love to have it fixed before applying for the Slack Application Submission. We really appreciate your help here. Thanks, Alex.

@filmaj
Copy link
Contributor

filmaj commented Jul 18, 2024

No update here unfortunately. I recommend sending an email to feedback@slack.com and link to this issue and explain how it is a blocker for you - that will help prioritize the work to fix this.

@alessio-ragni
Copy link

Thanks, I'll keep you updated 🤞

@StephenTangCook
Copy link

Hey @alessio-ragni, I'm also hitting this bug. Did you ever submit a customer report or hear about a fix?

@alessio-ragni
Copy link

alessio-ragni commented Aug 22, 2024 via email

@alessio-ragni
Copy link

Hi Slack team 👋
Do you have an update here? Thanks.

@filmaj
Copy link
Contributor

filmaj commented Oct 1, 2024

Hello everyone! The fix for this issue is now rolled out to all Slack workspaces and plans. I just tested this and everything works as desired!

Going to close this issue down but feel free to comment or open a new one if you still have issues.

@filmaj filmaj closed this as completed Oct 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-triage-skip Prevent this issue from being closed due to lack of activity bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented server-side-issue
Projects
None yet
Development

No branches or pull requests

4 participants