Skip to content

Commit

Permalink
Move away from HubSpot's Slack client (#160)
Browse files Browse the repository at this point in the history
  • Loading branch information
bbaga authored Jun 26, 2022
1 parent 7da95b5 commit 26fa6c0
Show file tree
Hide file tree
Showing 13 changed files with 240 additions and 228 deletions.
12 changes: 4 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,11 @@
<artifactId>snakeyaml</artifactId>
<version>1.30</version>
</dependency>

<dependency>
<groupId>com.hubspot.slack</groupId>
<artifactId>slack-base</artifactId>
<version>1.12</version>
</dependency>
<dependency>
<groupId>com.hubspot.slack</groupId>
<artifactId>slack-java-client</artifactId>
<version>1.12</version>
<groupId>com.slack.api</groupId>
<artifactId>slack-api-client</artifactId>
<version>1.23.0</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.bbaga.githubscheduledreminderapp.application.jobs.SlackChannelMessageDelete;
import com.bbaga.githubscheduledreminderapp.domain.jobs.scheduling.InstallationScanJobScheduler;
import com.bbaga.githubscheduledreminderapp.domain.jobs.scheduling.NotificationJobScheduler;
import com.hubspot.slack.client.SlackClient;
import com.slack.api.methods.MethodsClient;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
Expand All @@ -24,7 +24,7 @@ public class SchedulerConfig {
@Qualifier("Scheduler")
public Scheduler schedulerBootstrap(
Scheduler scheduler,
@Qualifier("slack.user") ObjectProvider<SlackClient> slackUserClient
@Qualifier("slack.user") ObjectProvider<MethodsClient> slackUserClient
) throws Exception {

JobDetail job = JobBuilder.newJob(ScheduledStateDump.class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
import com.bbaga.githubscheduledreminderapp.domain.notifications.slack.ChannelMessageDeleteQueueItem;
import com.bbaga.githubscheduledreminderapp.domain.notifications.slack.SearchAndDeleteEventListener;
import com.bbaga.githubscheduledreminderapp.domain.notifications.slack.SearchMessageQueueItem;
import com.hubspot.slack.client.SlackClient;
import com.hubspot.slack.client.SlackClientFactory;
import com.hubspot.slack.client.SlackClientRuntimeConfig;
import com.slack.api.Slack;
import com.slack.api.methods.MethodsClient;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
Expand Down Expand Up @@ -35,7 +34,7 @@ public class SlackClientConfig {

@Bean
@Qualifier("slack.app")
public SlackClient slackApp() throws Exception {
public MethodsClient slackApp() throws Exception {
if (!slackApiTokenFile.isEmpty() && slackApiToken.isEmpty()) {
try(FileInputStream inputStream = new FileInputStream(slackApiTokenFile)) {
slackApiToken = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
Expand All @@ -46,16 +45,12 @@ public SlackClient slackApp() throws Exception {
throw new IllegalStateException("Slack API Token must be configured, see the SLACK_API_TOKEN and SLACK_API_TOKEN_FILE environment variables.");
}

SlackClientRuntimeConfig runtimeConfig = SlackClientRuntimeConfig.builder()
.setTokenSupplier(() -> slackApiToken)
.build();

return SlackClientFactory.defaultFactory().build(runtimeConfig);
return Slack.getInstance().methods(slackApiToken);
}

@Bean
@Qualifier("slack.user")
public SlackClient slackUser() throws Exception {
public MethodsClient slackUser() throws Exception {
if (!slackApiUserTokenFile.isEmpty() && slackApiUserToken.isEmpty()) {
try(FileInputStream inputStream = new FileInputStream(slackApiUserTokenFile)) {
slackApiUserToken = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
Expand All @@ -67,11 +62,7 @@ public SlackClient slackUser() throws Exception {
return null;
}

SlackClientRuntimeConfig runtimeConfig = SlackClientRuntimeConfig.builder()
.setTokenSupplier(() -> slackApiUserToken)
.build();

return SlackClientFactory.defaultFactory().build(runtimeConfig);
return Slack.getInstance().methods(slackApiUserToken);
}

@Bean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.bbaga.githubscheduledreminderapp.domain.notifications.slack.BoundedUniqueQueue;
import com.bbaga.githubscheduledreminderapp.domain.notifications.slack.ChannelMessageDeleteQueueItem;
import com.bbaga.githubscheduledreminderapp.domain.notifications.slack.SearchMessageQueueItem;
import com.hubspot.slack.client.SlackClient;
import com.hubspot.slack.client.methods.params.chat.ChatDeleteParams;
import com.slack.api.methods.MethodsClient;
import com.slack.api.methods.request.chat.ChatDeleteRequest;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
Expand All @@ -20,14 +20,14 @@ public class SlackChannelMessageDelete implements Job {
private final Logger logger = LoggerFactory.getLogger(SlackChannelMessageDelete.class);
private final BoundedUniqueQueue<SearchMessageQueueItem> searchMessageQueue;
private final BoundedUniqueQueue<ChannelMessageDeleteQueueItem> channelMessageDeleteQueue;
private final SlackClient slackAppClient;
private final SlackClient slackUserClient;
private final MethodsClient slackAppClient;
private final MethodsClient slackUserClient;

public SlackChannelMessageDelete(
BoundedUniqueQueue<SearchMessageQueueItem> searchMessageQueue,
BoundedUniqueQueue<ChannelMessageDeleteQueueItem> channelMessageDeleteQueue,
@Qualifier("slack.app") SlackClient slackAppClient,
@Qualifier("slack.user") SlackClient slackUserClient
@Qualifier("slack.app") MethodsClient slackAppClient,
@Qualifier("slack.user") MethodsClient slackUserClient
) {
this.searchMessageQueue = searchMessageQueue;
this.channelMessageDeleteQueue = channelMessageDeleteQueue;
Expand Down Expand Up @@ -55,17 +55,16 @@ private void processDeleteQueue() {
try {
var item = channelMessageDeleteQueue.take();

var params = ChatDeleteParams.builder()
.setChannelId(item.getChannelId())
.setMessageToDeleteTs(item.getMessageId())
.setAsUser(true)
var params = ChatDeleteRequest.builder()
.channel(item.getChannelId())
.ts(item.getMessageId())
.build();

logger.info(
"Deleting: [Channel: " + item.getChannelId() + ", Message ID: " + item.getMessageId() + "]"
);

slackAppClient.deleteMessage(params);
slackAppClient.chatDelete(params);
} catch (Exception exception) {
logger.error(exception.getLocalizedMessage());
}
Expand All @@ -80,16 +79,13 @@ private void searchAndAddMessagesToDeleteQueue() {
try {
var item = searchMessageQueue.take();
logger.info("Searching messages with: \"" + item.getParams().getQuery()+ "\"");
var results = slackUserClient.searchMessages(item.getParams()).join();
var results = slackUserClient.searchMessages(item.getParams());

results.ifOk(messages -> {
try {
messages.getMessages().getMatches().forEach(item.getAction());
} catch (Exception exception) {
logger.error(exception.getLocalizedMessage());
}
});
if (!results.isOk()) {
logger.error(results.getError());
}

results.getMessages().getMatches().forEach(item.getAction());
} catch (Exception exception) {
logger.error(exception.getLocalizedMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import com.bbaga.githubscheduledreminderapp.infrastructure.github.GitHubIssue;
import com.bbaga.githubscheduledreminderapp.infrastructure.github.GitHubPullRequest;
import com.bbaga.githubscheduledreminderapp.infrastructure.github.GitHubUser;
import com.hubspot.slack.client.models.blocks.Block;
import com.hubspot.slack.client.models.blocks.Header;
import com.hubspot.slack.client.models.blocks.Section;
import com.hubspot.slack.client.models.blocks.elements.Button;
import com.hubspot.slack.client.models.blocks.objects.Text;
import com.hubspot.slack.client.models.blocks.objects.TextType;
import static com.slack.api.model.block.Blocks.*;
import static com.slack.api.model.block.composition.BlockCompositions.*;
import static com.slack.api.model.block.element.BlockElements.*;

import com.slack.api.model.block.HeaderBlock;
import com.slack.api.model.block.LayoutBlock;
import com.slack.api.model.block.SectionBlock;
import com.slack.api.model.block.element.ButtonElement;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
Expand All @@ -31,12 +33,12 @@ public ChannelMessageBuilder(UrlBuilderInterface urlBuilder) {
}

@Override
public Block createHeader(String text) {
return Header.of(Text.of(TextType.PLAIN_TEXT, text));
public HeaderBlock createHeader(String text) {
return header(h -> h.text(plainText(text)));
}

@Override
public Block createHeaderIssues(String text, String overflowFormat, int showing, int from) {
public SectionBlock createHeaderIssues(String text, String overflowFormat, int showing, int from) {
String counter;

if (showing < from) {
Expand All @@ -50,7 +52,7 @@ public Block createHeaderIssues(String text, String overflowFormat, int showing,
}

@Override
public Block createHeaderPRs(String text, String overflowFormat, int showing, int from) {
public SectionBlock createHeaderPRs(String text, String overflowFormat, int showing, int from) {
String counter;

if (showing < from) {
Expand All @@ -64,12 +66,12 @@ public Block createHeaderPRs(String text, String overflowFormat, int showing, in
}

@Override
public Block createNoResultsMessage(String text) {
public SectionBlock createNoResultsMessage(String text) {
return markdownSection(text);
}

@Override
public Block createLine(GitHubPullRequest pullRequest, String text, Map<String, String> trackingParams) {
public SectionBlock createLine(GitHubPullRequest pullRequest, String text, Map<String, String> trackingParams) {
String login;
String mergeableState = "";
String mergeableEmoji;
Expand All @@ -78,7 +80,8 @@ public Block createLine(GitHubPullRequest pullRequest, String text, Map<String,

try {
mergeableState = pullRequest.getMergeableState();
} catch (IOException ignored) {}
} catch (IOException ignored) {
}

if (List.of("clean", "has_hooks").contains(mergeableState)) {
mergeableEmoji = ":large_green_circle:";
Expand Down Expand Up @@ -106,27 +109,30 @@ public Block createLine(GitHubPullRequest pullRequest, String text, Map<String,
deletions = 0;
}

text = text.replaceAll("\\$login", login)
.replaceAll("\\$mergeableEmoji", mergeableEmoji)
.replaceAll("\\$title", pullRequest.getTitle())
.replaceAll("\\$repository", pullRequest.getRepository().getFullName())
.replaceAll("\\$age", getIssueAge(pullRequest))
.replaceAll("\\$deletions", String.valueOf(deletions))
.replaceAll("\\$additions", String.valueOf(additions))
.replaceAll("\\$link", getUrl(pullRequest, trackingParams))
.replaceAll("\\$assignee-logins", getAssigneeLogins(pullRequest))
.replaceAll("\\$assignee-login-links", getAssigneeLoginLinks(pullRequest));

if (text.contains("$button")) {
text = text.replaceAll("\\$button", "");
return markdownSection(text).withAccessory(linkButton(pullRequest, trackingParams));
var processedText = text.replaceAll("\\$login", login)
.replaceAll("\\$mergeableEmoji", mergeableEmoji)
.replaceAll("\\$title", pullRequest.getTitle())
.replaceAll("\\$repository", pullRequest.getRepository().getFullName())
.replaceAll("\\$age", getIssueAge(pullRequest))
.replaceAll("\\$deletions", String.valueOf(deletions))
.replaceAll("\\$additions", String.valueOf(additions))
.replaceAll("\\$link", getUrl(pullRequest, trackingParams))
.replaceAll("\\$assignee-logins", getAssigneeLogins(pullRequest))
.replaceAll("\\$assignee-login-links", getAssigneeLoginLinks(pullRequest));

if (processedText.contains("$button")) {
processedText = processedText.replaceAll("\\$button", "");
var section = markdownSection(processedText);
section.setAccessory(linkButton(pullRequest, trackingParams));

return section;
}

return markdownSection(text);
return markdownSection(processedText);
}

@Override
public Block createLine(GitHubIssue issue, String text, Map<String, String> trackingParams) {
public SectionBlock createLine(GitHubIssue issue, String text, Map<String, String> trackingParams) {
String login;

try {
Expand All @@ -135,30 +141,33 @@ public Block createLine(GitHubIssue issue, String text, Map<String, String> trac
login = "Unknown";
}

text = text.replaceAll("\\$login", login)
var processedText = text.replaceAll("\\$login", login)
.replaceAll("\\$title", issue.getTitle())
.replaceAll("\\$repository", issue.getRepository().getFullName())
.replaceAll("\\$age", getIssueAge(issue))
.replaceAll("\\$assignee-logins", getAssigneeLogins(issue))
.replaceAll("\\$assignee-login-links", getAssigneeLoginLinks(issue))
.replaceAll("\\$link", getUrl(issue, trackingParams));

if (text.contains("$button")) {
text = text.replaceAll("\\$button", "");
return markdownSection(text).withAccessory(linkButton(issue, trackingParams));
if (processedText.contains("$button")) {
processedText = processedText.replaceAll("\\$button", "");
var section = markdownSection(processedText);
section.setAccessory(linkButton(issue, trackingParams));

return section;
}

return markdownSection(text);
return markdownSection(processedText);
}

private Section markdownSection(String markdown) {
return Section.of(Text.of(TextType.MARKDOWN, markdown));
private SectionBlock markdownSection(String markdown) {
return section(s -> s.text(markdownText(markdown)));
}

private Button linkButton(GitHubIssue issue, Map<String, String> trackingParams) {
private ButtonElement linkButton(GitHubIssue issue, Map<String, String> trackingParams) {
String url = getUrl(issue, trackingParams);

return Button.of(Text.of(TextType.PLAIN_TEXT, "Open"), issue.getNodeId()).withUrl(url);
return button(b -> b.text(plainText(pt -> pt.text("Open"))).value(issue.getNodeId()).url(url));
}

private String getUrl(GitHubIssue issue, Map<String, String> trackingParams) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import com.bbaga.githubscheduledreminderapp.infrastructure.github.GitHubIssue;
import com.bbaga.githubscheduledreminderapp.infrastructure.github.GitHubPullRequest;
import com.hubspot.slack.client.models.blocks.Block;
import com.slack.api.model.block.HeaderBlock;
import com.slack.api.model.block.SectionBlock;
import java.util.Map;

public interface ChannelMessageBuilderInterface {
Block createHeader(String text);
Block createHeaderIssues(String text, String overflowFormat, int showing, int from);
Block createHeaderPRs(String text, String overflowFormat, int showing, int from);
Block createLine(GitHubPullRequest pullRequest, String text, Map<String, String> trackingParams);
Block createLine(GitHubIssue issue, String text, Map<String, String> trackingParams);
Block createNoResultsMessage(String text);
HeaderBlock createHeader(String text);
SectionBlock createHeaderIssues(String text, String overflowFormat, int showing, int from);
SectionBlock createHeaderPRs(String text, String overflowFormat, int showing, int from);
SectionBlock createLine(GitHubPullRequest pullRequest, String text, Map<String, String> trackingParams);
SectionBlock createLine(GitHubIssue issue, String text, Map<String, String> trackingParams);
SectionBlock createNoResultsMessage(String text);
}
Loading

0 comments on commit 26fa6c0

Please sign in to comment.