slack-client.ts•2.19 kB
import { WebClient } from '@slack/web-api';
import { SlackConfig } from '../types/slack.js';
export class SlackClientWrapper {
private client: WebClient;
constructor(config: SlackConfig) {
this.client = new WebClient(config.token);
}
/**
* Get the underlying Slack WebClient
*/
getClient(): WebClient {
return this.client;
}
/**
* Handle Slack API errors and convert to readable error messages
*/
handleError(error: any): never {
if (error.data?.error) {
const slackError = error.data.error;
const errorMessages: Record<string, string> = {
'not_authed': 'Authentication failed. Please check your SLACK_BOT_TOKEN.',
'invalid_auth': 'Invalid authentication token.',
'account_inactive': 'Account is inactive.',
'token_revoked': 'Token has been revoked.',
'no_permission': 'The token does not have permission for this operation.',
'org_login_required': 'Organization login required.',
'ekm_access_denied': 'EKM access denied.',
'missing_scope': 'Missing required OAuth scope.',
'not_allowed_token_type': 'Token type not allowed for this operation.',
'method_deprecated': 'This method is deprecated.',
'deprecated_method': 'This method is deprecated.',
'two_factor_setup_required': 'Two-factor authentication setup required.',
'team_access_not_granted': 'Team access not granted.',
'channel_not_found': 'Channel not found.',
'user_not_found': 'User not found.',
'name_taken': 'Name is already taken.',
'restricted_action': 'Restricted action.',
'invalid_name': 'Invalid name format.',
'rate_limited': 'Rate limited. Please try again later.',
};
const message = errorMessages[slackError] || `Slack API error: ${slackError}`;
throw new Error(message);
}
throw new Error(`Slack API error: ${error.message || 'Unknown error'}`);
}
/**
* Make a safe API call with error handling
*/
async safeCall<T>(
method: () => Promise<T>
): Promise<T> {
try {
return await method();
} catch (error) {
this.handleError(error);
}
}
}