Skip to content

Commit 15ccbdc

Browse files
authored
Merge pull request #2947 from objectcomputing/feature-2946/support-custom-slack-emoji
Closes #2946 - Support custom slack emoji
2 parents 9531513 + 0c14302 commit 15ccbdc

File tree

8 files changed

+438
-538
lines changed

8 files changed

+438
-538
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.objectcomputing.checkins.services.slack;
2+
3+
import io.micronaut.cache.CacheConfiguration;
4+
import io.micronaut.http.HttpResponse;
5+
import io.micronaut.http.annotation.Controller;
6+
import io.micronaut.http.annotation.Get;
7+
import io.micronaut.scheduling.TaskExecutors;
8+
import io.micronaut.scheduling.annotation.ExecuteOn;
9+
import io.micronaut.security.annotation.Secured;
10+
import io.micronaut.security.rules.SecurityRule;
11+
import io.swagger.v3.oas.annotations.tags.Tag;
12+
import jakarta.inject.Named;
13+
14+
import java.net.URI;
15+
import java.time.Duration;
16+
import java.util.Map;
17+
import java.util.UUID;
18+
19+
import static io.micronaut.http.HttpHeaders.CACHE_CONTROL;
20+
21+
@Controller("/services/slack")
22+
@ExecuteOn(TaskExecutors.BLOCKING)
23+
@Secured(SecurityRule.IS_AUTHENTICATED)
24+
@Tag(name = "slack")
25+
public class SlackController {
26+
27+
private final SlackSearch slackSearch;
28+
private final long expiry;
29+
30+
public SlackController(@Named("slack-cache") CacheConfiguration cacheConfiguration, SlackSearch slackSearch) {
31+
// If un-configured, default to 1 hour
32+
this.expiry = cacheConfiguration.getExpireAfterWrite()
33+
.map(Duration::toSeconds)
34+
.orElseGet(() -> Duration.ofHours(1).toSeconds());
35+
this.slackSearch = slackSearch;
36+
}
37+
38+
@Get("/emoji")
39+
public HttpResponse<Map<String, String>> customEmoji() {
40+
Map<String, String> customEmoji = slackSearch.getCustomEmoji();
41+
42+
return HttpResponse
43+
.ok().header(CACHE_CONTROL, "public, max-age=%d".formatted(expiry))
44+
.headers(headers -> headers.location(URI.create("/services/slack/emoji")))
45+
.body(customEmoji);
46+
}
47+
}

server/src/main/java/com/objectcomputing/checkins/services/slack/SlackSearch.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import com.objectcomputing.checkins.configuration.CheckInsConfiguration;
44
import com.slack.api.methods.request.conversations.ConversationsInfoRequest;
5+
import com.slack.api.methods.request.emoji.EmojiListRequest;
56
import com.slack.api.methods.response.conversations.ConversationsInfoResponse;
7+
import com.slack.api.methods.response.emoji.EmojiListResponse;
68
import com.slack.api.model.block.LayoutBlock;
79
import com.slack.api.Slack;
810
import com.slack.api.methods.MethodsClient;
@@ -15,16 +17,20 @@
1517
import com.slack.api.methods.request.users.UsersInfoRequest;
1618
import com.slack.api.methods.response.users.UsersInfoResponse;
1719

20+
import io.micronaut.cache.annotation.CacheConfig;
21+
import io.micronaut.cache.annotation.Cacheable;
1822
import jakarta.inject.Singleton;
1923
import jakarta.inject.Inject;
2024

2125
import java.util.List;
2226
import java.io.IOException;
27+
import java.util.Map;
2328

2429
import jnr.ffi.annotations.In;
2530
import org.slf4j.Logger;
2631
import org.slf4j.LoggerFactory;
2732

33+
@CacheConfig("slack-cache")
2834
@Singleton
2935
public class SlackSearch {
3036
private static final Logger LOG = LoggerFactory.getLogger(SlackSearch.class);
@@ -122,5 +128,26 @@ public String findUserEmail(String userId) {
122128
}
123129
return null;
124130
}
131+
132+
133+
@Cacheable
134+
public Map<String, String> getCustomEmoji() {
135+
String token = configuration.getApplication().getSlack().getBotToken();
136+
if (token != null) {
137+
try {
138+
MethodsClient client = Slack.getInstance().methods(token);
139+
EmojiListResponse response = client.emojiList(EmojiListRequest.builder().build());
140+
141+
if (response.isOk()) {
142+
return response.getEmoji();
143+
}
144+
} catch(IOException e) {
145+
LOG.error("SlackSearch.getCustomEmoji: " + e.toString());
146+
} catch(SlackApiException e) {
147+
LOG.error("SlackSearch.getCustomEmoji: " + e.toString());
148+
}
149+
}
150+
return null;
151+
}
125152
}
126153

server/src/main/resources/application.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ micronaut:
1515
maximum-size: 600
1616
role-permission-cache:
1717
expire-after-write: 1d # 1 day
18-
18+
slack-cache:
19+
expire-after-write: 1800s # 30 minutes
1920
router:
2021
static-resources:
2122
swagger:

web-ui/src/api/emoji.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { resolve } from './api.js';
2+
3+
const emojiUrl = '/services/slack/emoji';
4+
5+
export const getCustomEmoji = async (cookie) => {
6+
return resolve({
7+
url: emojiUrl,
8+
responseType: 'json',
9+
headers: { 'X-CSRF-Header': cookie, Accept: 'application/json' }
10+
});
11+
};

0 commit comments

Comments
 (0)