-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into feature-2802/pageable-pulse-responses
- Loading branch information
Showing
14 changed files
with
386 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
37 changes: 37 additions & 0 deletions
37
...er/src/main/java/com/objectcomputing/checkins/notifications/social_media/SlackPoster.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.objectcomputing.checkins.notifications.social_media; | ||
|
||
import com.objectcomputing.checkins.configuration.CheckInsConfiguration; | ||
import io.micronaut.http.HttpRequest; | ||
import io.micronaut.http.HttpResponse; | ||
import io.micronaut.http.HttpStatus; | ||
import io.micronaut.http.client.BlockingHttpClient; | ||
import io.micronaut.http.client.HttpClient; | ||
|
||
import jakarta.inject.Singleton; | ||
import jakarta.inject.Inject; | ||
|
||
import java.util.List; | ||
|
||
@Singleton | ||
public class SlackPoster { | ||
@Inject | ||
private HttpClient slackClient; | ||
|
||
@Inject | ||
private CheckInsConfiguration configuration; | ||
|
||
public HttpResponse post(String slackBlock) { | ||
// See if we can have a webhook URL. | ||
String slackWebHook = configuration.getApplication().getNotifications().getSlack().getWebhookUrl(); | ||
if (slackWebHook != null) { | ||
// POST it to Slack. | ||
BlockingHttpClient client = slackClient.toBlocking(); | ||
HttpRequest<String> request = HttpRequest.POST(slackWebHook, | ||
slackBlock); | ||
return client.exchange(request); | ||
} | ||
return HttpResponse.status(HttpStatus.GONE, | ||
"Slack Webhook URL is not configured"); | ||
} | ||
} | ||
|
80 changes: 80 additions & 0 deletions
80
...er/src/main/java/com/objectcomputing/checkins/notifications/social_media/SlackSearch.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.objectcomputing.checkins.notifications.social_media; | ||
|
||
import com.objectcomputing.checkins.configuration.CheckInsConfiguration; | ||
import com.slack.api.model.block.LayoutBlock; | ||
import com.slack.api.Slack; | ||
import com.slack.api.methods.MethodsClient; | ||
import com.slack.api.model.Conversation; | ||
import com.slack.api.methods.SlackApiException; | ||
import com.slack.api.methods.request.conversations.ConversationsListRequest; | ||
import com.slack.api.methods.response.conversations.ConversationsListResponse; | ||
import com.slack.api.methods.request.users.UsersLookupByEmailRequest; | ||
import com.slack.api.methods.response.users.UsersLookupByEmailResponse; | ||
|
||
import jakarta.inject.Singleton; | ||
import jakarta.inject.Inject; | ||
|
||
import java.util.List; | ||
import java.io.IOException; | ||
|
||
import jnr.ffi.annotations.In; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
@Singleton | ||
public class SlackSearch { | ||
private static final Logger LOG = LoggerFactory.getLogger(SlackSearch.class); | ||
|
||
private CheckInsConfiguration configuration; | ||
|
||
public SlackSearch(CheckInsConfiguration checkInsConfiguration) { | ||
this.configuration = checkInsConfiguration; | ||
} | ||
|
||
public String findChannelId(String channelName) { | ||
String token = configuration.getApplication().getNotifications().getSlack().getBotToken(); | ||
if (token != null) { | ||
try { | ||
MethodsClient client = Slack.getInstance().methods(token); | ||
ConversationsListResponse response = client.conversationsList( | ||
ConversationsListRequest.builder().build() | ||
); | ||
|
||
if (response.isOk()) { | ||
for (Conversation conversation: response.getChannels()) { | ||
if (conversation.getName().equals(channelName)) { | ||
return conversation.getId(); | ||
} | ||
} | ||
} | ||
} catch(IOException e) { | ||
LOG.error("SlackSearch.findChannelId: " + e.toString()); | ||
} catch(SlackApiException e) { | ||
LOG.error("SlackSearch.findChannelId: " + e.toString()); | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
public String findUserId(String userEmail) { | ||
String token = configuration.getApplication().getNotifications().getSlack().getBotToken(); | ||
if (token != null) { | ||
try { | ||
MethodsClient client = Slack.getInstance().methods(token); | ||
UsersLookupByEmailResponse response = client.usersLookupByEmail( | ||
UsersLookupByEmailRequest.builder().email(userEmail).build() | ||
); | ||
|
||
if (response.isOk()) { | ||
return response.getUser().getId(); | ||
} | ||
} catch(IOException e) { | ||
LOG.error("SlackSearch.findUserId: " + e.toString()); | ||
} catch(SlackApiException e) { | ||
LOG.error("SlackSearch.findUserId: " + e.toString()); | ||
} | ||
} | ||
return null; | ||
} | ||
} | ||
|
114 changes: 114 additions & 0 deletions
114
server/src/main/java/com/objectcomputing/checkins/services/kudos/KudosConverter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package com.objectcomputing.checkins.services.kudos; | ||
|
||
import com.objectcomputing.checkins.notifications.social_media.SlackSearch; | ||
import com.objectcomputing.checkins.services.kudos.kudos_recipient.KudosRecipientServices; | ||
import com.objectcomputing.checkins.services.kudos.kudos_recipient.KudosRecipient; | ||
import com.objectcomputing.checkins.services.memberprofile.MemberProfileServices; | ||
import com.objectcomputing.checkins.services.memberprofile.MemberProfileUtils; | ||
import com.objectcomputing.checkins.services.memberprofile.MemberProfile; | ||
|
||
import com.slack.api.model.block.LayoutBlock; | ||
import com.slack.api.model.block.RichTextBlock; | ||
import com.slack.api.model.block.element.RichTextElement; | ||
import com.slack.api.model.block.element.RichTextSectionElement; | ||
import com.slack.api.util.json.GsonFactory; | ||
import com.google.gson.Gson; | ||
|
||
import jakarta.inject.Singleton; | ||
|
||
import java.util.UUID; | ||
import java.util.List; | ||
import java.util.ArrayList; | ||
|
||
@Singleton | ||
public class KudosConverter { | ||
private record InternalBlock( | ||
List<LayoutBlock> blocks | ||
) {} | ||
|
||
private final MemberProfileServices memberProfileServices; | ||
private final KudosRecipientServices kudosRecipientServices; | ||
private final SlackSearch slackSearch; | ||
|
||
public KudosConverter(MemberProfileServices memberProfileServices, | ||
KudosRecipientServices kudosRecipientServices, | ||
SlackSearch slackSearch) { | ||
this.memberProfileServices = memberProfileServices; | ||
this.kudosRecipientServices = kudosRecipientServices; | ||
this.slackSearch = slackSearch; | ||
} | ||
|
||
public String toSlackBlock(Kudos kudos) { | ||
// Build the message text out of the Kudos data. | ||
List<RichTextElement> content = new ArrayList<>(); | ||
content.add( | ||
RichTextSectionElement.Text.builder() | ||
.text("Kudos from ") | ||
.style(boldItalic()) | ||
.build() | ||
); | ||
content.add(memberAsRichText(kudos.getSenderId())); | ||
content.addAll(recipients(kudos)); | ||
|
||
content.add( | ||
RichTextSectionElement.Text.builder() | ||
.text("\n" + kudos.getMessage() + "\n") | ||
.style(boldItalic()) | ||
.build() | ||
); | ||
|
||
// Bring it all together. | ||
RichTextSectionElement element = RichTextSectionElement.builder() | ||
.elements(content).build(); | ||
RichTextBlock richTextBlock = RichTextBlock.builder() | ||
.elements(List.of(element)).build(); | ||
InternalBlock block = new InternalBlock(List.of(richTextBlock)); | ||
Gson mapper = GsonFactory.createSnakeCase(); | ||
return mapper.toJson(block); | ||
} | ||
|
||
private RichTextSectionElement.TextStyle boldItalic() { | ||
return RichTextSectionElement.TextStyle.builder() | ||
.bold(true).italic(true).build(); | ||
} | ||
|
||
private RichTextSectionElement.LimitedTextStyle limitedBoldItalic() { | ||
return RichTextSectionElement.LimitedTextStyle.builder() | ||
.bold(true).italic(true).build(); | ||
} | ||
|
||
private RichTextElement memberAsRichText(UUID memberId) { | ||
// Look up the user id by email address on Slack | ||
MemberProfile profile = memberProfileServices.getById(memberId); | ||
String userId = slackSearch.findUserId(profile.getWorkEmail()); | ||
if (userId == null) { | ||
String name = MemberProfileUtils.getFullName(profile); | ||
return RichTextSectionElement.Text.builder() | ||
.text("@" + name) | ||
.style(boldItalic()) | ||
.build(); | ||
} else { | ||
return RichTextSectionElement.User.builder() | ||
.userId(userId) | ||
.style(limitedBoldItalic()) | ||
.build(); | ||
} | ||
} | ||
|
||
private List<RichTextElement> recipients(Kudos kudos) { | ||
List<RichTextElement> list = new ArrayList<>(); | ||
List<KudosRecipient> recipients = | ||
kudosRecipientServices.getAllByKudosId(kudos.getId()); | ||
String separator = " to "; | ||
for (KudosRecipient recipient : recipients) { | ||
list.add(RichTextSectionElement.Text.builder() | ||
.text(separator) | ||
.style(boldItalic()) | ||
.build()); | ||
list.add(memberAsRichText(recipient.getMemberId())); | ||
separator = ", "; | ||
} | ||
return list; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.