@ixo/slack
v1.0.0
Published
A powerful and type-safe Slack integration package that provides a wrapper around the Slack Bolt SDK with robust Socket Mode connection management and error handling.
Readme
@ixo/slack
A powerful and type-safe Slack integration package that provides a wrapper around the Slack Bolt SDK with robust Socket Mode connection management and error handling.
Features
- 🚀 Easy-to-use wrapper around Slack's Bolt SDK
- 📝 Full TypeScript support
- 🔒 Enhanced Socket Mode support with automatic reconnection
- 🔄 Robust error handling and connection management
- 💬 Rich messaging capabilities with markdown support
- 🧵 Thread management
- 👥 User management and profile handling
- ⚡ Ephemeral message support
- ✏️ Message editing and deletion
- 📄 Automatic handling of long messages with block splitting
- 🏥 Health monitoring and connection status reporting
Socket Mode Connection Management
The enhanced Slack client provides robust Socket Mode connection management to prevent server failures and ensure reliable operation:
Key Features
- Automatic Reconnection: Automatically attempts to reconnect on connection failures
- Exponential Backoff: Uses exponential backoff strategy for reconnection attempts
- Error Classification: Intelligently identifies Socket Mode-specific errors
- Health Monitoring: Periodic health checks to monitor connection status
- Graceful Shutdown: Proper cleanup when the application stops
- Connection Status: Real-time connection status and statistics
Error Handling
The client handles various Socket Mode connection issues:
- WebSocket disconnections
- Network timeouts (ETIMEDOUT)
- Connection resets (ECONNRESET)
- DNS resolution failures (ENOTFOUND)
- Socket hang-ups
Configuration Options
You can configure the Socket Mode behavior using environment variables:
# Maximum number of reconnection attempts (default: 10)
SLACK_MAX_RECONNECT_ATTEMPTS=10
# Initial reconnection delay in milliseconds (default: 1000)
SLACK_RECONNECT_DELAY_MS=1000Installation
pnpm add @ixo/slackUsage
Initialize the Slack Client
import { Slack } from '@ixo/slack';
const slack = new Slack(
'xoxb-your-bot-token', // Bot OAuth Token
'xapp-your-app-token', // App-Level Token with connection:write scope
);
// Start the Slack app with enhanced error handling
await slack.start();
// Check connection status
console.log('Connected:', slack.isConnected());
console.log('Stats:', slack.getConnectionStats());
// Stop the Slack app gracefully
await slack.stop();Using with NestJS
The package includes a NestJS service with lifecycle management:
import { SlackService } from '@ixo/slack';
@Injectable()
export class MyService {
constructor(private readonly slackService: SlackService) {}
async sendNotification() {
// Check if Slack is available before using
const status = this.slackService.getStatus();
if (!status.isConfigured || !status.isConnected) {
console.log('Slack not available');
return;
}
await this.slackService.postMessage({
channel: 'C1234567890',
text: 'Hello from a resilient connection!',
});
}
}Health Check Integration
Monitor Slack connection health in your application:
// GET /health endpoint returns:
{
"status": "healthy",
"timestamp": "2024-01-01T00:00:00.000Z",
"services": {
"slack": {
"status": "connected", // "connected", "disconnected", or "disabled"
"isConnected": true,
"isConfigured": true,
"connectionStats": {
"isConnected": true,
"reconnectAttempts": 0,
"maxReconnectAttempts": 10
}
}
}
}Posting Messages
// Simple text message
await slack.postMessage({
channel: 'C1234567890',
text: 'Hello, world!',
});
// Message with markdown formatting
await slack.postMessage({
channel: 'C1234567890',
text: '**Bold** and _italic_ text',
format: true,
});
// Message in a thread
await slack.postMessage({
channel: 'C1234567890',
text: 'Reply in thread',
threadTs: '1234567890.123456',
});Working with Threads
// Get chat history in a thread
const messages = await slack.getChatHistoryInThread(
'C1234567890',
'1234567890.123456',
);Ephemeral Messages
// Send a message visible only to a specific user
await slack.postEphemeral({
channel: 'C1234567890',
user: 'U1234567890',
text: 'Only you can see this message',
});Message Management
// Update a message
await slack.updateMessage({
channel: 'C1234567890',
ts: '1234567890.123456',
text: 'Updated message',
});
// Delete a message
await slack.deleteMessage({
channel: 'C1234567890',
ts: '1234567890.123456',
});User Management
// List workspace members
const { members, nextCursor } = await slack.listMembers();
// Get user profile
const userProfile = await slack.getUserProfile('U1234567890');
// Get bot's own profile
const botProfile = await slack.getCurrentUserProfile();Troubleshooting Socket Mode Issues
Common Issues and Solutions
Server Restarts Due to Socket Disconnections
- The enhanced client now handles disconnections gracefully
- Check logs for reconnection attempts
- Monitor the
/healthendpoint for connection status
Frequent Reconnections
- Check network stability
- Verify Slack tokens are valid
- Monitor the
reconnectAttemptsin connection stats
Application Won't Start
- Verify
SLACK_BOT_OAUTH_TOKENandSLACK_APP_TOKENare set correctly if you want Slack integration - The application will continue without Slack if tokens are not provided
- Check logs for specific error messages
- Verify
Monitoring
- Use the
/healthendpoint to monitor connection status - Check application logs for connection events
- Monitor the
reconnectAttemptsmetric for connection stability
API Reference
Slack Class
Constructor
constructor(BOT_OAUTH_TOKEN: string, SLACK_APP_TOKEN: string)
Methods
postMessage(params: PostMessageParams): Promise<ChatPostMessageResponse>getChatHistoryInThread(channel: string, threadId: string): Promise<MessageElement[]>postEphemeral(params: PostEphemeralParams): Promise<ChatPostMessageResponse>updateMessage(params: ChatUpdateArguments): Promise<void>deleteMessage(params: ChatDeleteArguments): Promise<void>listMembers(cursor?: string, limit?: number): Promise<ListMembersResponse>getUserProfile(userId: string): Promise<Profile & { userId: string } | undefined>getCurrentUserProfile(): Promise<Profile & { userId: string } | undefined>start(): Promise<void>stop(): Promise<void>isConnected(): booleangetConnectionStats(): { isConnected: boolean; reconnectAttempts: number; maxReconnectAttempts: number }
Development
# Install dependencies
pnpm install
# Build the package
pnpm build
# Run tests
pnpm testLicense
Private package - All rights reserved.
Contributing
This is a private package. Please refer to the internal contribution guidelines.
