slack.service.ts•5.79 kB
import {
ISlackClient,
ISlackService,
} from "../../core/interfaces/slack.interface.js";
import { IStorageService } from "../../core/interfaces/storage.interface.js";
import {
AddReactionRequest,
GetChannelHistoryRequest,
GetThreadRepliesRequest,
GetUserProfileRequest,
GetUsersRequest,
ListChannelsRequest,
PostMessageRequest,
ReplyToThreadRequest,
SlackChannel,
SlackMessage,
SlackOperationResult,
SlackUser,
SlackUserProfile,
} from "../../core/types/slack.types.js";
export class SlackService implements ISlackService {
constructor(
private readonly slackClient: ISlackClient,
private readonly cacheStorage?: IStorageService
) {}
async listChannels(request: ListChannelsRequest): Promise<
SlackOperationResult<{
channels: SlackChannel[];
next_cursor?: string;
}>
> {
const cacheKey = `channels_${request.limit || 100}_${
request.cursor || "first"
}`;
// Try cache first
if (this.cacheStorage) {
const cached = this.cacheStorage.get(cacheKey);
if (cached) {
return {
success: true,
data: cached,
};
}
}
const result = await this.slackClient.listChannels(request);
// Cache successful results
if (result.success && result.data && this.cacheStorage) {
this.cacheStorage.set(cacheKey, result.data);
}
return result;
}
async postMessage(
request: PostMessageRequest
): Promise<SlackOperationResult<SlackMessage>> {
if (!request.channel_id?.trim()) {
return {
success: false,
error: "Channel ID is required",
};
}
if (!request.text?.trim()) {
return {
success: false,
error: "Message text is required",
};
}
return await this.slackClient.postMessage(request);
}
async replyToThread(
request: ReplyToThreadRequest
): Promise<SlackOperationResult<SlackMessage>> {
if (!request.channel_id?.trim()) {
return {
success: false,
error: "Channel ID is required",
};
}
if (!request.thread_ts?.trim()) {
return {
success: false,
error: "Thread timestamp is required",
};
}
if (!request.text?.trim()) {
return {
success: false,
error: "Reply text is required",
};
}
return await this.slackClient.replyToThread(request);
}
async addReaction(
request: AddReactionRequest
): Promise<SlackOperationResult<void>> {
if (!request.channel_id?.trim()) {
return {
success: false,
error: "Channel ID is required",
};
}
if (!request.timestamp?.trim()) {
return {
success: false,
error: "Message timestamp is required",
};
}
if (!request.reaction?.trim()) {
return {
success: false,
error: "Reaction name is required",
};
}
return await this.slackClient.addReaction(request);
}
async getChannelHistory(request: GetChannelHistoryRequest): Promise<
SlackOperationResult<{
messages: SlackMessage[];
}>
> {
if (!request.channel_id?.trim()) {
return {
success: false,
error: "Channel ID is required",
};
}
const cacheKey = `history_${request.channel_id}_${request.limit || 10}`;
// Try cache first (shorter cache time for messages)
if (this.cacheStorage) {
const cached = this.cacheStorage.get(cacheKey);
if (cached) {
return {
success: true,
data: cached,
};
}
}
const result = await this.slackClient.getChannelHistory(request);
// Cache successful results for a shorter time
if (result.success && result.data && this.cacheStorage) {
this.cacheStorage.set(cacheKey, result.data);
}
return result;
}
async getThreadReplies(request: GetThreadRepliesRequest): Promise<
SlackOperationResult<{
messages: SlackMessage[];
}>
> {
if (!request.channel_id?.trim()) {
return {
success: false,
error: "Channel ID is required",
};
}
if (!request.thread_ts?.trim()) {
return {
success: false,
error: "Thread timestamp is required",
};
}
return await this.slackClient.getThreadReplies(request);
}
async getUsers(request: GetUsersRequest): Promise<
SlackOperationResult<{
users: SlackUser[];
next_cursor?: string;
}>
> {
const cacheKey = `users_${request.limit || 100}_${
request.cursor || "first"
}`;
// Try cache first
if (this.cacheStorage) {
const cached = this.cacheStorage.get(cacheKey);
if (cached) {
return {
success: true,
data: cached,
};
}
}
const result = await this.slackClient.getUsers(request);
// Cache successful results
if (result.success && result.data && this.cacheStorage) {
this.cacheStorage.set(cacheKey, result.data);
}
return result;
}
async getUserProfile(
request: GetUserProfileRequest
): Promise<SlackOperationResult<SlackUserProfile>> {
if (!request.user_id?.trim()) {
return {
success: false,
error: "User ID is required",
};
}
const cacheKey = `user_profile_${request.user_id}`;
// Try cache first
if (this.cacheStorage) {
const cached = this.cacheStorage.get(cacheKey);
if (cached) {
return {
success: true,
data: cached,
};
}
}
const result = await this.slackClient.getUserProfile(request);
// Cache successful results
if (result.success && result.data && this.cacheStorage) {
this.cacheStorage.set(cacheKey, result.data);
}
return result;
}
}