0

I want to publish messages submitted on a modal view to the same channel: (https://api.slack.com/surfaces/modals/using#modal_response_url).

This is how the chatPostMessage() method looks and is invoked by the /postmessage slash command:

    app.command("/postmessage", (req, ctx) -> {
    ChatPostMessageResponse response = ctx.client().chatPostMessage(r -> r.channel(ctx.getChannelId()).text("Example Message"));
    return ctx.ack("");
});

Output (seen in the channel where /postmessage is invoked from):

Example Message

I want to call the same chatPostMessage() method to post the modal submission data to the channel where it is launched from. How can I do this?

//When user clicks "Submit" in the modal view
 app.viewSubmission("case-handoff", (req, ctx) -> {

      String privateMetadata = req.getPayload().getView().getPrivateMetadata();
      Map<String, Map<String, ViewState.Value>> stateValues = req.getPayload().getView().getState().getValues();
      String firstName = stateValues.get("firstName").get("agenda-action1").getValue();

      Map<String, String> errors = new HashMap<>();
      if (caseName.length() <= 10) {
        errors.put("agenda-block", "Agenda needs to be longer than 10 characters.");
      }
      if (!errors.isEmpty()) {
        return ctx.ack(r -> r.responseAction("errors").errors(errors));
      } else {
        return ctx.ack("");
      }
    });

Example Output (John Smith is typed into the modal text-field and user presses "Submit"), seen in the channel where /launchModal is invoked from:

John Smith

newbieJ
  • 17
  • 2

1 Answers1

0

Considering you're dealing with a view_submission modal type, the annoying thing is that you don't actually receive the channel_id in the payload by default (unlike the block_actions modal type).

You'll have to extract it from the response_urls field in the payload (or use the response_url directly to post your message to the channel, both ways should work, however in this case, you won't be able to use the chatPostMessage(...) directly, as it does not support response urls). The issue is, however, that response urls aren't available by default

view_submission payloads don’t have response_url by default. However, if you have an input block asking users a channel to post a message, payloads may provide response_urls (List<ResponseUrl> responseUrls in Java).

You'll have to use a block element in your view that is configured to generate a response_url.

To enable this, set the block element type as either channels_select or conversations_select and add "response_url_enabled": true.

The documentation on how to achieve that can be found here: https://api.slack.com/surfaces/modals/using#modal_response_url

Additional documentation on how to handle modals using Bolt SDK for Java (you can scroll down to Publishing Messages After Modal Submissions): https://slack.dev/java-slack-sdk/guides/modals

jure
  • 492
  • 5
  • 8
  • I followed the documentation and added a block element to my view that includes a response_url. I can see that it picks up the data in my modal view for the channel. From here, how can I reference the response_url in a chatPostMessage() call to post the entered data to the channel? What would that look like syntactically? – newbieJ Oct 26 '22 at 20:18
  • You won't be able to use chatPostMessage directly, as that doesn't support responding to response urls. There are two other options, however. You can use an http client (either one in the Java library or an external dependency) to make a HTTP POST request directly to the URL. The other option, more ideomatic when using Bolt SDK, is to use the `ctx` object and respond with `ctx.respond()`. Check the documentation here: https://slack.dev/java-slack-sdk/guides/interactive-components for a thorough explanation on how to use the `ctx.respond()` functionality. – jure Oct 26 '22 at 21:04
  • It seems like ctx.respond() is only useable with block_actions and not view_submission. When compiling, I get an error with calling getResponseUrl() inside viewSubmission(), even though I've added a component to the modal view that has .responseUrlEnabled(true). Am I missing something here? Otherwise, I could definitely try importing existing Java libraries to programatically execute a cURL command and use the values stored from the modal submission as arguments, but I was hoping there might be a cleaner solution. Thanks for your help btw, much appreciated! – newbieJ Oct 27 '22 at 21:49
  • Hmm, I did a quick test and it compiles fine for me. Make sure you're still calling `ctx.ack()` after the `ctx.respond()`. – jure Oct 27 '22 at 21:58
  • Yeah, I am still calling ctx.ack() after. I get "cannot find symbol [ERROR] symbol: method getResponseUrl() location: class com.slack.api.app_backend.views.payload.ViewSubmissionPayload" when compiling. – newbieJ Oct 27 '22 at 23:04
  • ``` app.viewSubmission("case-handoff", (req, ctx) -> { String privateMetadata = req.getPayload().getView().getPrivateMetadata(); Map> stateValues = req.getPayload().getView().getState().getValues(); String data = stateValues.get("data").get("agenda-action").getValue(); if (req.getPayload().getResponseUrl() != null) { ctx.respond("You've sent " + data + " by clicking the button!"); } return ctx.ack(); } });``` – newbieJ Oct 27 '22 at 23:15
  • Aha, I see the issue. You'll want to use the `getResponseUrls()`, not `getResponseUrl()`. You'll have to handle the list of urls, as opposed to just a single one, but the functionality should remain the same, once you get the desired response url from the list. – jure Oct 28 '22 at 10:39
  • Hmm, sadly although changing to getResponseUrls() compiles, I get an error with viewSubmissions picking up the response_urls: [qtp1346244856-73] ERROR com.slack.api.bolt.servlet.SlackAppServlet - Failed to handle a request - This payload doesn't have response_urls. – newbieJ Nov 01 '22 at 18:34
  • I think I will take the second approach and use an HTTP client since this seems to be tricky. Thanks for all your help, I'm sorry I can't upvote until I have at least 15 rep. Much appreciated! – newbieJ Nov 02 '22 at 21:58