From e5938e164521a8bf11b64294bc17c8006c0f5840 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Fri, 10 Jan 2025 08:01:27 -0600 Subject: [PATCH] Added a slack post containing the slack blocks that make up the Pulse form. --- .../services/pulse/PulseServices.java | 2 +- .../services/pulse/PulseServicesImpl.java | 6 +- .../services/pulse/PulseSlackPoster.java | 60 +++++++ .../CheckServicesImpl.java | 2 +- server/src/main/resources/slack/README.md | 10 ++ .../resources/slack/pulse_slack_blocks.json | 158 ++++++++++++++++++ 6 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseSlackPoster.java create mode 100644 server/src/main/resources/slack/README.md create mode 100644 server/src/main/resources/slack/pulse_slack_blocks.json diff --git a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServices.java b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServices.java index 2170d8ae2e..772a489683 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServices.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServices.java @@ -3,5 +3,5 @@ import java.time.LocalDate; public interface PulseServices { - public void sendPendingEmail(LocalDate now); + public void notifyUsers(LocalDate now); } diff --git a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java index 8f3ec0788c..2b73d0ecc9 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseServicesImpl.java @@ -47,6 +47,9 @@ private class Frequency { @Inject private PulseEmail email; + @Inject + private PulseSlackPoster slackPoster; + private final DayOfWeek emailDay = DayOfWeek.MONDAY; private String setting = "bi-weekly"; @@ -69,7 +72,7 @@ public PulseServicesImpl( this.automatedEmailRepository = automatedEmailRepository; } - public void sendPendingEmail(LocalDate check) { + public void notifyUsers(LocalDate check) { if (check.getDayOfWeek() == emailDay) { LOG.info("Checking for pending Pulse email"); // Start from the first of the year and move forward to ensure that we @@ -103,6 +106,7 @@ public void sendPendingEmail(LocalDate check) { if (sent.isEmpty()) { LOG.info("Sending Pulse Email"); email.send(); + slackPoster.send(); automatedEmailRepository.save(new AutomatedEmail(key)); } else { LOG.info("The Pulse Email has already been sent today"); diff --git a/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseSlackPoster.java b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseSlackPoster.java new file mode 100644 index 0000000000..c64ffb04dd --- /dev/null +++ b/server/src/main/java/com/objectcomputing/checkins/services/pulse/PulseSlackPoster.java @@ -0,0 +1,60 @@ +package com.objectcomputing.checkins.services.pulse; + +import com.objectcomputing.checkins.configuration.CheckInsConfiguration; + +import io.micronaut.http.HttpRequest; +import io.micronaut.http.client.BlockingHttpClient; +import io.micronaut.http.client.HttpClient; +import io.micronaut.context.annotation.Value; +import io.micronaut.core.io.Readable; +import io.micronaut.core.io.IOUtils; + +import jakarta.inject.Singleton; +import jakarta.inject.Inject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; + +@Singleton +public class PulseSlackPoster { + private static final Logger LOG = LoggerFactory.getLogger(PulseSlackPoster.class); + + @Inject + private HttpClient slackClient; + + @Inject + private CheckInsConfiguration configuration; + + @Value("classpath:slack/pulse_slack_blocks.json") + private Readable pulseSlackBlocks; + + public void send() { + String slackBlocks = getSlackBlocks(); + + // See if we can have a webhook URL. + String slackWebHook = configuration.getApplication() + .getPulseResponse() + .getSlack().getWebhookUrl(); + if (slackWebHook != null && !slackBlocks.isEmpty()) { + // POST it to Slack. + BlockingHttpClient client = slackClient.toBlocking(); + HttpRequest request = HttpRequest.POST(slackWebHook, + slackBlocks); + client.exchange(request); + } + } + + private String getSlackBlocks() { + try { + return IOUtils.readText( + new BufferedReader(pulseSlackBlocks.asReader())); + + } catch(Exception ex) { + LOG.error(ex.toString()); + return ""; + } + } +} + diff --git a/server/src/main/java/com/objectcomputing/checkins/services/request_notifications/CheckServicesImpl.java b/server/src/main/java/com/objectcomputing/checkins/services/request_notifications/CheckServicesImpl.java index 49cb86f041..baba523e35 100644 --- a/server/src/main/java/com/objectcomputing/checkins/services/request_notifications/CheckServicesImpl.java +++ b/server/src/main/java/com/objectcomputing/checkins/services/request_notifications/CheckServicesImpl.java @@ -41,7 +41,7 @@ public boolean sendScheduledEmails() { req.setStatus("sent"); feedbackRequestRepository.update(req); } - pulseServices.sendPendingEmail(today); + pulseServices.notifyUsers(today); reviewPeriodServices.sendNotifications(today); return true; } diff --git a/server/src/main/resources/slack/README.md b/server/src/main/resources/slack/README.md new file mode 100644 index 0000000000..8313956e7b --- /dev/null +++ b/server/src/main/resources/slack/README.md @@ -0,0 +1,10 @@ +# Slack Blocks + +Place Slack Blocks jSON here. + +### Micronaut Usage + +```java +@Value("classpath:slack/filename.json") +private Readable slackBlocks; +``` diff --git a/server/src/main/resources/slack/pulse_slack_blocks.json b/server/src/main/resources/slack/pulse_slack_blocks.json new file mode 100644 index 0000000000..bdfd32a132 --- /dev/null +++ b/server/src/main/resources/slack/pulse_slack_blocks.json @@ -0,0 +1,158 @@ +{ + "type": "modal", + "title": { + "type": "plain_text", + "text": "Check-Ins Pulse", + "emoji": true + }, + "submit": { + "type": "plain_text", + "text": "Submit", + "emoji": true + }, + "close": { + "type": "plain_text", + "text": "Cancel", + "emoji": true + }, + "blocks": [ + { + "type": "section", + "text": { + "type": "plain_text", + "text": "How are you feeling about work today?" + }, + "accessory": { + "type": "radio_buttons", + "action_id": "internalScore", + "options": [ + { + "value": "1", + "text": { + "type": "plain_text", + "text": "😦", + "emoji": true + } + }, + { + "value": "2", + "text": { + "type": "plain_text", + "text": "🙁", + "emoji": true + } + }, + { + "value": "3", + "text": { + "type": "plain_text", + "text": "😐", + "emoji": true + } + }, + { + "value": "4", + "text": { + "type": "plain_text", + "text": "🙂", + "emoji": true + } + }, + { + "value": "5", + "text": { + "type": "plain_text", + "text": "😀", + "emoji": true + } + } + ] + } + }, + { + "type": "input", + "element": { + "type": "plain_text_input", + "action_id": "internalFeelings", + "placeholder": { + "type": "plain_text", + "text": "Comment" + } + }, + "label": { + "type": "plain_text", + "text": "Comment", + "emoji": true + } + }, + { + "type": "section", + "text": { + "type": "plain_text", + "text": "How are you feeling about life outside of work?" + }, + "accessory": { + "type": "radio_buttons", + "action_id": "externalScore", + "options": [ + { + "value": "1", + "text": { + "type": "plain_text", + "text": "😦", + "emoji": true + } + }, + { + "value": "2", + "text": { + "type": "plain_text", + "text": "🙁", + "emoji": true + } + }, + { + "value": "3", + "text": { + "type": "plain_text", + "text": "😐", + "emoji": true + } + }, + { + "value": "4", + "text": { + "type": "plain_text", + "text": "🙂", + "emoji": true + } + }, + { + "value": "5", + "text": { + "type": "plain_text", + "text": "😀", + "emoji": true + } + } + ] + } + }, + { + "type": "input", + "element": { + "type": "plain_text_input", + "action_id": "externalFeelings", + "placeholder": { + "type": "plain_text", + "text": "Comment" + } + }, + "label": { + "type": "plain_text", + "text": "Comment", + "emoji": true + } + } + ] +}