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

Add custom function support #1241

Merged
merged 3 commits into from
Aug 20, 2024
Merged

Conversation

seratch
Copy link
Member

@seratch seratch commented Nov 21, 2023

This pull request adds remote function support, which is still in beta, to this SDK. Sorry, the duplicated PRs (due to my operation error) are confusing but this is the final version of #1239

Developers can implement a remote function and its interactivity this way:

// app.event(FunctionExecutedEvent.class, (req, ctx) -> {
// app.function("hello", (req, ctx) -> {
app.function(Pattern.compile("^he.+$"), (req, ctx) -> {
  ctx.logger.info("req: {}", req);
  ctx.client().chatPostMessage(r -> r
    .channel(req.getEvent().getInputs().get("user_id").asString())
    .text("hey!")
    .blocks(asBlocks(actions(a -> a.blockId("b").elements(asElements(
      button(b -> b.actionId("remote-function-button-success").value("clicked").text(plainText("block_actions success"))),
      button(b -> b.actionId("remote-function-button-error").value("clicked").text(plainText("block_actions error"))),
      button(b -> b.actionId("remote-function-modal").value("clicked").text(plainText("modal view")))
    )))))
  );
  return ctx.ack();
});

app.blockAction("remote-function-button-success", (req, ctx) -> {
  Map<String, Object> outputs = new HashMap<>();
  outputs.put("user_id", req.getPayload().getFunctionData().getInputs().get("user_id").asString());
  ctx.client().functionsCompleteSuccess(r -> r
    .functionExecutionId(req.getPayload().getFunctionData().getExecutionId())
    .outputs(outputs)
  );
  ctx.client().chatUpdate(r -> r
    .channel(req.getPayload().getContainer().getChannelId())
    .ts(req.getPayload().getContainer().getMessageTs())
    .text("Thank you!")
  );
  return ctx.ack();
});
app.blockAction("remote-function-button-error", (req, ctx) -> {
  ctx.client().functionsCompleteError(r -> r
    .functionExecutionId(req.getPayload().getFunctionData().getExecutionId())
    .error("test error!")
  );
  ctx.client().chatUpdate(r -> r
    .channel(req.getPayload().getContainer().getChannelId())
    .ts(req.getPayload().getContainer().getMessageTs())
    .text("Thank you!")
  );
  return ctx.ack();
});
app.blockAction("remote-function-modal", (req, ctx) -> {
  ctx.client().viewsOpen(r -> r
    .triggerId(req.getPayload().getInteractivity().getInteractivityPointer())
    .view(view(v -> v
      .type("modal")
      .callbackId("remote-function-view")
      .title(viewTitle(vt -> vt.type("plain_text").text("Remote Function test")))
      .close(viewClose(vc -> vc.type("plain_text").text("Close")))
      .submit(viewSubmit(vs -> vs.type("plain_text").text("Submit")))
      .notifyOnClose(true)
      .blocks(asBlocks(input(input -> input
        .blockId("text-block")
        .element(plainTextInput(pti -> pti.actionId("text-action").multiline(true)))
        .label(plainText(pt -> pt.text("Text").emoji(true)))
      )))
    )));
  ctx.client().chatUpdate(r -> r
    .channel(req.getPayload().getContainer().getChannelId())
    .ts(req.getPayload().getContainer().getMessageTs())
    .text("Thank you!")
  );
  return ctx.ack();
});

app.viewSubmission("remote-function-view", (req, ctx) -> {
  Map<String, Object> outputs = new HashMap<>();
  outputs.put("user_id", ctx.getRequestUserId());
  ctx.client().functionsCompleteSuccess(r -> r
    .functionExecutionId(req.getPayload().getFunctionData().getExecutionId())
    .outputs(outputs)
  );
  return ctx.ack();
});
app.viewClosed("remote-function-view", (req, ctx) -> {
  Map<String, Object> outputs = new HashMap<>();
  outputs.put("user_id", ctx.getRequestUserId());
  ctx.client().functionsCompleteSuccess(r -> r
    .functionExecutionId(req.getPayload().getFunctionData().getExecutionId())
    .outputs(outputs)
  );
  return ctx.ack();
});

References:

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

  • bolt (Bolt for Java)
  • bolt-{sub modules} (Bolt for Java - optional modules)
  • slack-api-client (Slack API Clients)
  • slack-api-model (Slack API Data Models)
  • slack-api-*-kotlin-extension (Kotlin Extensions for Slack API Clients)
  • slack-app-backend (The primitive layer of Bolt for Java)

Requirements

Please read the Contributing guidelines and Code of Conduct before creating this issue or pull request. By submitting, you agree to those rules.

@seratch seratch added enhancement M-T: A feature request for new functionality project:bolt project:slack-api-client project:slack-api-client project:slack-app-backend labels Nov 21, 2023
@seratch seratch added this to the 1.x milestone Nov 21, 2023
@seratch seratch self-assigned this Nov 21, 2023
Copy link

codecov bot commented Nov 21, 2023

Codecov Report

Attention: Patch coverage is 71.73913% with 13 lines in your changes missing coverage. Please review.

Project coverage is 74.96%. Comparing base (efa3f24) to head (9dd4118).
Report is 1 commits behind head on main.

Files Patch % Lines
bolt/src/main/java/com/slack/api/bolt/App.java 57.14% 2 Missing and 4 partials ⚠️
...m/slack/api/bolt/request/builtin/EventRequest.java 57.14% 0 Missing and 3 partials ⚠️
...ck/api/bolt/request/builtin/ViewClosedRequest.java 33.33% 1 Missing and 1 partial ⚠️
.../main/java/com/slack/api/bolt/context/Context.java 83.33% 0 Missing and 1 partial ⚠️
...k/api/bolt/request/builtin/BlockActionRequest.java 85.71% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #1241      +/-   ##
============================================
- Coverage     74.99%   74.96%   -0.03%     
- Complexity     4190     4202      +12     
============================================
  Files           452      453       +1     
  Lines         12931    12975      +44     
  Branches       1331     1342      +11     
============================================
+ Hits           9697     9727      +30     
- Misses         2463     2467       +4     
- Partials        771      781      +10     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Contributor

@WilliamBergamin WilliamBergamin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 💯

@seratch seratch force-pushed the remote-functions-2 branch 2 times, most recently from 53a2b11 to 5fae103 Compare March 29, 2024 01:53
@seratch seratch changed the title Add remote function support Add custom function support May 7, 2024
Copy link
Contributor

@WilliamBergamin WilliamBergamin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 💯

@seratch seratch merged commit 52d1c76 into slackapi:main Aug 20, 2024
6 checks passed
@seratch seratch deleted the remote-functions-2 branch August 20, 2024 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement M-T: A feature request for new functionality project:bolt project:slack-api-client project:slack-api-client project:slack-app-backend
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants