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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

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 are missing coverage. Please review.

Project coverage is 74.83%. Comparing base (a9a3599) to head (5b294c1).

❗ Current head 5b294c1 differs from pull request most recent head 0f27992. Consider uploading reports for the commit 0f27992 to get more accurate results

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.84%   74.83%   -0.02%     
- Complexity     4128     4141      +13     
============================================
  Files           443      444       +1     
  Lines         12786    12830      +44     
  Branches       1319     1330      +11     
============================================
+ Hits           9570     9601      +31     
- Misses         2452     2455       +3     
- Partials        764      774      +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 💯

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.

None yet

2 participants