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

botMessage handler in Assistant middleware does not work when other event listeners do not exist #1414

Closed
rbioteau opened this issue Jan 9, 2025 · 4 comments
Labels
bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented project:bolt
Milestone

Comments

@rbioteau
Copy link

rbioteau commented Jan 9, 2025

When implementing the following example provided in the documentation an NPE prevent the proper execution of the use case.

App app = new App(AppConfig.builder()
  .singleTeamBotToken(System.getenv("SLACK_BOT_TOKEN"))
  .ignoringSelfAssistantMessageEventsEnabled(false)
  .build());

Assistant assistant = new Assistant(app.executorService());

assistant.threadStarted((req, ctx) -> {
  try {
    ctx.say(r -> r
      .text("Hi, how can I help you today?")
      .blocks(Arrays.asList(
        section(s -> s.text(plainText("Hi, how I can I help you today?"))),
        actions(a -> a.elements(Collections.singletonList(
          button(b -> b.actionId("assistant-generate-numbers").text(plainText("Generate numbers")))
        )))
      ))
    );
  } catch (Exception e) {
    ctx.logger.error("Failed to handle assistant thread started event: {e}", e);
  }
});

app.blockAction("assistant-generate-numbers", (req, ctx) -> {
  app.executorService().submit(() -> {
    Map<String, Object> eventPayload = new HashMap<>();
    eventPayload.put("num", 20);
    try {
      ctx.client().chatPostMessage(r -> r
        .channel(req.getPayload().getChannel().getId())
        .threadTs(req.getPayload().getMessage().getThreadTs())
        .text("OK, I will generate numbers for you!")
        .metadata(new Message.Metadata("assistant-generate-numbers", eventPayload))
      );
    } catch (Exception e) {
      ctx.logger.error("Failed to post a bot message: {e}", e);
    }
  });
  return ctx.ack();
});

assistant.botMessage((req, ctx) -> {
  if (req.getEvent().getMetadata() != null
    && req.getEvent().getMetadata().getEventType().equals("assistant-generate-numbers")) {
  try {
    ctx.setStatus("is typing...");
    Double num = (Double) req.getEvent().getMetadata().getEventPayload().get("num");
    Set<String> numbers = new HashSet<>();
    SecureRandom random = new SecureRandom();
    while (numbers.size() < num) {
      numbers.add(String.valueOf(random.nextInt(100)));
    }
    Thread.sleep(1000L);
    ctx.say(r -> r.text("Her you are: " + String.join(", ", numbers)));
  } catch (Exception e) {
    ctx.logger.error("Failed to handle assistant bot message event: {e}", e);
  }
  }
});

assistant.userMessage((req, ctx) -> {
  try {
    ctx.setStatus("is typing...");
    ctx.say(r -> r.text("Sorry, I couldn't understand your comment."));
  } catch (Exception e) {
    ctx.logger.error("Failed to handle assistant user message event: {e}", e);
    try {
      ctx.say(r -> r.text(":warning: Sorry, something went wrong during processing your request!"));
    } catch (Exception ee) {
      ctx.logger.error("Failed to inform the error to the end-user: {ee}", ee);
    }
  }
});

app.assistant(assistant);

In the above example we register a botMessage and a userMessage on the Assistant. However, when executing this simple app, these messages are never returned to my chat.

The problem occurs in the com.slack.api.bolt.util.EventsApiPayloadParser#buildEventPayload method where my eventClass is null. It seems to rely on a cache to retrieve a given Event class for an event name. The is cache is empty in my case and I need to explicitly call EventsApiPayloadParser.getEventTypeAndSubtype(MessageEvent.class) in my code to initialize the map.

Reproducible in:

[INFO] com.bonitasoft:my-slackbot:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:3.4.1:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:3.4.1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:3.4.1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:3.4.1:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:3.4.1:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.5.12:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.5.12:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.24.3:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.24.3:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:2.0.16:compile
[INFO] |  |  +- jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:2.3:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:3.4.1:compile
[INFO] |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.18.2:compile
[INFO] |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.18.2:compile
[INFO] |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.18.2:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.18.2:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.18.2:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.18.2:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:3.4.1:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.34:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.34:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.34:compile
[INFO] |  +- org.springframework:spring-web:jar:6.2.1:compile
[INFO] |  |  +- org.springframework:spring-beans:jar:6.2.1:compile
[INFO] |  |  \- io.micrometer:micrometer-observation:jar:1.14.2:compile
[INFO] |  |     \- io.micrometer:micrometer-commons:jar:1.14.2:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:6.2.1:compile
[INFO] |     +- org.springframework:spring-aop:jar:6.2.1:compile
[INFO] |     +- org.springframework:spring-context:jar:6.2.1:compile
[INFO] |     \- org.springframework:spring-expression:jar:6.2.1:compile
[INFO] +- com.slack.api:bolt-jakarta-servlet:jar:1.45.0:compile
[INFO] |  +- com.slack.api:slack-api-model:jar:1.45.0:compile
[INFO] |  |  \- com.google.code.gson:gson:jar:2.11.0:compile
[INFO] |  |     \- com.google.errorprone:error_prone_annotations:jar:2.27.0:compile
[INFO] |  +- com.slack.api:slack-api-client:jar:1.45.0:compile
[INFO] |  |  +- com.squareup.okhttp3:okhttp:jar:4.12.0:compile
[INFO] |  |  |  +- com.squareup.okio:okio:jar:3.6.0:compile
[INFO] |  |  |  |  \- com.squareup.okio:okio-jvm:jar:3.6.0:compile
[INFO] |  |  |  |     \- org.jetbrains.kotlin:kotlin-stdlib-common:jar:1.9.25:compile
[INFO] |  |  |  \- org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:1.9.25:compile
[INFO] |  |  |     +- org.jetbrains.kotlin:kotlin-stdlib:jar:1.9.25:compile
[INFO] |  |  |     |  \- org.jetbrains:annotations:jar:13.0:compile
[INFO] |  |  |     \- org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:1.9.25:compile
[INFO] |  |  \- org.slf4j:slf4j-api:jar:2.0.16:compile
[INFO] |  +- com.slack.api:slack-app-backend:jar:1.45.0:compile
[INFO] |  \- com.slack.api:bolt:jar:1.45.0:compile
[INFO] |     \- org.apache.commons:commons-text:jar:1.13.0:compile
[INFO] |        \- org.apache.commons:commons-lang3:jar:3.17.0:compile
[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:3.4.1:test
[INFO]    +- org.springframework.boot:spring-boot-test:jar:3.4.1:test
[INFO]    +- org.springframework.boot:spring-boot-test-autoconfigure:jar:3.4.1:test
[INFO]    +- com.jayway.jsonpath:json-path:jar:2.9.0:test
[INFO]    +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.2:test
[INFO]    |  \- jakarta.activation:jakarta.activation-api:jar:2.1.3:test
[INFO]    +- net.minidev:json-smart:jar:2.5.1:test
[INFO]    |  \- net.minidev:accessors-smart:jar:2.5.1:test
[INFO]    |     \- org.ow2.asm:asm:jar:9.6:test
[INFO]    +- org.assertj:assertj-core:jar:3.26.3:test
[INFO]    |  \- net.bytebuddy:byte-buddy:jar:1.15.11:test
[INFO]    +- org.awaitility:awaitility:jar:4.2.2:test
[INFO]    +- org.hamcrest:hamcrest:jar:2.2:test
[INFO]    +- org.junit.jupiter:junit-jupiter:jar:5.11.4:test
[INFO]    |  +- org.junit.jupiter:junit-jupiter-api:jar:5.11.4:test
[INFO]    |  |  +- org.opentest4j:opentest4j:jar:1.3.0:test
[INFO]    |  |  +- org.junit.platform:junit-platform-commons:jar:1.11.4:test
[INFO]    |  |  \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO]    |  +- org.junit.jupiter:junit-jupiter-params:jar:5.11.4:test
[INFO]    |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.11.4:test
[INFO]    |     \- org.junit.platform:junit-platform-engine:jar:1.11.4:test
[INFO]    +- org.mockito:mockito-core:jar:5.14.2:test
[INFO]    |  +- net.bytebuddy:byte-buddy-agent:jar:1.15.11:test
[INFO]    |  \- org.objenesis:objenesis:jar:3.3:test
[INFO]    +- org.mockito:mockito-junit-jupiter:jar:5.14.2:test
[INFO]    +- org.skyscreamer:jsonassert:jar:1.5.3:test
[INFO]    |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO]    +- org.springframework:spring-core:jar:6.2.1:compile
[INFO]    |  \- org.springframework:spring-jcl:jar:6.2.1:compile
[INFO]    +- org.springframework:spring-test:jar:6.2.1:test
[INFO]    \- org.xmlunit:xmlunit-core:jar:2.10.0:test

The Slack SDK version

[INFO] +- com.slack.api:bolt-jakarta-servlet:jar:1.45.0:compile
[INFO] | +- com.slack.api:slack-api-model:jar:1.45.0:compile
[INFO] | +- com.slack.api:slack-api-client:jar:1.45.0:compile
[INFO] | +- com.slack.api:slack-app-backend:jar:1.45.0:compile
[INFO] | - com.slack.api:bolt:jar:1.45.0:compile

Java Runtime version

openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Temurin-21.0.4+7 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.4+7 (build 21.0.4+7-LTS, mixed mode, sharing)

OS info

Distributor ID: Ubuntu
Description: Ubuntu 24.04.1 LTS
Release: 24.04
Codename: noble

Steps to reproduce:

Run the springboot example with the code sample for Agent & Assistant from the documentation, See snippet above.

Expected result:

The botMessage handler should be executed.

Actual result:

The botMessage handler is not executed due to a NPE when retrieving the botId in the Assistant#apply method.

Requirements

Please make sure if this topic is specific to this SDK. For general questions/issues about Slack API platform or its server-side, could you submit questions at https://my.slack.com/help/requests/new instead. 🙇

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

@seratch
Copy link
Member

seratch commented Jan 10, 2025

Hi @rbioteau, thanks for asking the question. I've checked the code snippet using Socket Mode and I couldn't reproduce the NPE you've faced.

One thing I am wonderfing is this error may be due to how you configure the Spring Boot app. As mentioned in this document page, bolt-java works properly only when using WebServiet + no additional request body parser in the Spring app: https://tools.slack.dev/java-slack-sdk/guides/supported-web-frameworks#spring-boot

If your Spring Boot app already follows the above guidance, could you share the whole project (as minimal working example) and the stacktrace you've got when the NPE occurs?

@rbioteau
Copy link
Author

Thanks to take the time to have a look.

Here is a minimal reproducer.

I do not use Websocket, and the NPE is not logged (occurs in a FutureTask).

@seratch seratch added bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented and removed needs info labels Jan 11, 2025
@seratch seratch added this to the 1.45.1 milestone Jan 11, 2025
@seratch seratch changed the title NPE in Assistant handler botMessage handler in Assistant middleware does not work when other event listeners do not exist Jan 11, 2025
seratch added a commit to seratch/java-slack-sdk that referenced this issue Jan 11, 2025
… work when other event listeners do not exist
@seratch
Copy link
Member

seratch commented Jan 11, 2025

Thank you so much for reporting this issue. I just submitted a pull request #1415 resolving this issue. If the CI builds pass, I will release a patch version shortly.

@seratch
Copy link
Member

seratch commented Jan 11, 2025

@rbioteau Thanks again for taking the time to report this issue and we're sorry for the disruption. The latest version 1.45.1 should resolve the issue for you! https://github.com/slackapi/java-slack-sdk/releases/tag/v1.45.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug M-T: confirmed bug report. Issues are confirmed when the reproduction steps are documented project:bolt
Projects
None yet
Development

No branches or pull requests

2 participants