@hasna/connectors 0.3.16 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/bin/index.js +71 -1
  2. package/bin/mcp.js +71 -1
  3. package/bin/serve.js +70 -0
  4. package/connectors/connect-asana/.env.example +11 -0
  5. package/connectors/connect-asana/CLAUDE.md +128 -0
  6. package/connectors/connect-asana/README.md +193 -0
  7. package/connectors/connect-asana/package.json +52 -0
  8. package/connectors/connect-asana/src/api/client.ts +119 -0
  9. package/connectors/connect-asana/src/api/index.ts +319 -0
  10. package/connectors/connect-asana/src/cli/index.ts +731 -0
  11. package/connectors/connect-asana/src/index.ts +19 -0
  12. package/connectors/connect-asana/src/types/index.ts +270 -0
  13. package/connectors/connect-asana/src/utils/config.ts +171 -0
  14. package/connectors/connect-asana/src/utils/output.ts +119 -0
  15. package/connectors/connect-asana/tsconfig.json +16 -0
  16. package/connectors/connect-clickup/.env.example +11 -0
  17. package/connectors/connect-clickup/CLAUDE.md +128 -0
  18. package/connectors/connect-clickup/README.md +193 -0
  19. package/connectors/connect-clickup/package.json +52 -0
  20. package/connectors/connect-clickup/src/api/client.ts +116 -0
  21. package/connectors/connect-clickup/src/api/index.ts +400 -0
  22. package/connectors/connect-clickup/src/cli/index.ts +625 -0
  23. package/connectors/connect-clickup/src/index.ts +19 -0
  24. package/connectors/connect-clickup/src/types/index.ts +591 -0
  25. package/connectors/connect-clickup/src/utils/config.ts +157 -0
  26. package/connectors/connect-clickup/src/utils/output.ts +119 -0
  27. package/connectors/connect-clickup/tsconfig.json +16 -0
  28. package/connectors/connect-confluence/.env.example +11 -0
  29. package/connectors/connect-confluence/CLAUDE.md +272 -0
  30. package/connectors/connect-confluence/README.md +193 -0
  31. package/connectors/connect-confluence/package.json +53 -0
  32. package/connectors/connect-confluence/scripts/release.ts +179 -0
  33. package/connectors/connect-confluence/src/api/client.ts +213 -0
  34. package/connectors/connect-confluence/src/api/example.ts +48 -0
  35. package/connectors/connect-confluence/src/api/index.ts +51 -0
  36. package/connectors/connect-confluence/src/cli/index.ts +254 -0
  37. package/connectors/connect-confluence/src/index.ts +103 -0
  38. package/connectors/connect-confluence/src/types/index.ts +237 -0
  39. package/connectors/connect-confluence/src/utils/auth.ts +274 -0
  40. package/connectors/connect-confluence/src/utils/bulk.ts +212 -0
  41. package/connectors/connect-confluence/src/utils/config.ts +326 -0
  42. package/connectors/connect-confluence/src/utils/output.ts +175 -0
  43. package/connectors/connect-confluence/src/utils/settings.ts +114 -0
  44. package/connectors/connect-confluence/src/utils/storage.ts +198 -0
  45. package/connectors/connect-confluence/tsconfig.json +16 -0
  46. package/connectors/connect-jira/.env.example +11 -0
  47. package/connectors/connect-jira/CLAUDE.md +128 -0
  48. package/connectors/connect-jira/README.md +193 -0
  49. package/connectors/connect-jira/package.json +53 -0
  50. package/connectors/connect-jira/src/api/client.ts +131 -0
  51. package/connectors/connect-jira/src/api/index.ts +266 -0
  52. package/connectors/connect-jira/src/cli/index.ts +653 -0
  53. package/connectors/connect-jira/src/index.ts +23 -0
  54. package/connectors/connect-jira/src/types/index.ts +448 -0
  55. package/connectors/connect-jira/src/utils/config.ts +179 -0
  56. package/connectors/connect-jira/src/utils/output.ts +119 -0
  57. package/connectors/connect-jira/tsconfig.json +16 -0
  58. package/connectors/connect-linear/CLAUDE.md +88 -0
  59. package/connectors/connect-linear/README.md +201 -0
  60. package/connectors/connect-linear/package.json +45 -0
  61. package/connectors/connect-linear/src/api/client.ts +62 -0
  62. package/connectors/connect-linear/src/api/index.ts +46 -0
  63. package/connectors/connect-linear/src/api/issues.ts +247 -0
  64. package/connectors/connect-linear/src/api/projects.ts +179 -0
  65. package/connectors/connect-linear/src/api/teams.ts +125 -0
  66. package/connectors/connect-linear/src/api/users.ts +112 -0
  67. package/connectors/connect-linear/src/cli/index.ts +560 -0
  68. package/connectors/connect-linear/src/index.ts +27 -0
  69. package/connectors/connect-linear/src/types/index.ts +275 -0
  70. package/connectors/connect-linear/src/utils/config.ts +249 -0
  71. package/connectors/connect-linear/src/utils/output.ts +119 -0
  72. package/connectors/connect-linear/tsconfig.json +16 -0
  73. package/connectors/connect-slack/.env.example +7 -0
  74. package/connectors/connect-slack/CLAUDE.md +69 -0
  75. package/connectors/connect-slack/README.md +150 -0
  76. package/connectors/connect-slack/package.json +44 -0
  77. package/connectors/connect-slack/src/api/channels.ts +112 -0
  78. package/connectors/connect-slack/src/api/client.ts +97 -0
  79. package/connectors/connect-slack/src/api/index.ts +42 -0
  80. package/connectors/connect-slack/src/api/messages.ts +127 -0
  81. package/connectors/connect-slack/src/api/users.ts +110 -0
  82. package/connectors/connect-slack/src/cli/index.ts +494 -0
  83. package/connectors/connect-slack/src/index.ts +21 -0
  84. package/connectors/connect-slack/src/types/index.ts +263 -0
  85. package/connectors/connect-slack/src/utils/config.ts +297 -0
  86. package/connectors/connect-slack/src/utils/output.ts +119 -0
  87. package/connectors/connect-slack/tsconfig.json +16 -0
  88. package/connectors/connect-telegram/.env.example +2 -0
  89. package/connectors/connect-telegram/package.json +49 -0
  90. package/connectors/connect-todoist/.env.example +11 -0
  91. package/connectors/connect-todoist/CLAUDE.md +104 -0
  92. package/connectors/connect-todoist/README.md +193 -0
  93. package/connectors/connect-todoist/package.json +52 -0
  94. package/connectors/connect-todoist/src/api/client.ts +117 -0
  95. package/connectors/connect-todoist/src/api/index.ts +188 -0
  96. package/connectors/connect-todoist/src/cli/index.ts +990 -0
  97. package/connectors/connect-todoist/src/index.ts +21 -0
  98. package/connectors/connect-todoist/src/types/index.ts +240 -0
  99. package/connectors/connect-todoist/src/utils/config.ts +157 -0
  100. package/connectors/connect-todoist/src/utils/output.ts +119 -0
  101. package/connectors/connect-todoist/tsconfig.json +16 -0
  102. package/connectors/connect-trello/.env.example +11 -0
  103. package/connectors/connect-trello/CLAUDE.md +128 -0
  104. package/connectors/connect-trello/README.md +193 -0
  105. package/connectors/connect-trello/package.json +53 -0
  106. package/connectors/connect-trello/src/api/client.ts +128 -0
  107. package/connectors/connect-trello/src/api/index.ts +278 -0
  108. package/connectors/connect-trello/src/cli/index.ts +737 -0
  109. package/connectors/connect-trello/src/index.ts +21 -0
  110. package/connectors/connect-trello/src/types/index.ts +314 -0
  111. package/connectors/connect-trello/src/utils/config.ts +182 -0
  112. package/connectors/connect-trello/src/utils/output.ts +119 -0
  113. package/connectors/connect-trello/tsconfig.json +16 -0
  114. package/connectors/connect-whatsapp/.env.example +11 -0
  115. package/connectors/connect-whatsapp/CLAUDE.md +113 -0
  116. package/connectors/connect-whatsapp/README.md +193 -0
  117. package/connectors/connect-whatsapp/package.json +53 -0
  118. package/connectors/connect-whatsapp/src/api/client.ts +133 -0
  119. package/connectors/connect-whatsapp/src/api/index.ts +365 -0
  120. package/connectors/connect-whatsapp/src/cli/index.ts +686 -0
  121. package/connectors/connect-whatsapp/src/index.ts +25 -0
  122. package/connectors/connect-whatsapp/src/types/index.ts +502 -0
  123. package/connectors/connect-whatsapp/src/utils/config.ts +179 -0
  124. package/connectors/connect-whatsapp/src/utils/output.ts +119 -0
  125. package/connectors/connect-whatsapp/tsconfig.json +16 -0
  126. package/dist/index.js +70 -0
  127. package/package.json +1 -1
@@ -0,0 +1,69 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code when working with this repository.
4
+
5
+ ## Project Overview
6
+
7
+ connect-slack is a TypeScript CLI and library for Slack's API. It provides channel management, messaging, and user operations with multi-profile support for managing multiple workspaces.
8
+
9
+ ## Build & Run Commands
10
+
11
+ ```bash
12
+ bun install # Install dependencies
13
+ bun run dev # Run CLI in development
14
+ bun run build # Build for distribution
15
+ bun run typecheck # Type check
16
+ ```
17
+
18
+ ## Code Style
19
+
20
+ - TypeScript with strict mode
21
+ - ESM modules (type: module)
22
+ - Async/await for all async operations
23
+ - Minimal dependencies: commander, chalk
24
+
25
+ ## Project Structure
26
+
27
+ ```
28
+ src/
29
+ ├── api/
30
+ │ ├── client.ts # HTTP client with Bearer auth
31
+ │ ├── channels.ts # Channels/Conversations API
32
+ │ ├── messages.ts # Messages API
33
+ │ ├── users.ts # Users API
34
+ │ └── index.ts # Main Slack class
35
+ ├── cli/
36
+ │ └── index.ts # CLI commands
37
+ ├── types/
38
+ │ └── index.ts # TypeScript types
39
+ ├── utils/
40
+ │ ├── config.ts # Multi-profile configuration
41
+ │ └── output.ts # CLI output formatting
42
+ └── index.ts # Library exports
43
+ ```
44
+
45
+ ## Environment Variables
46
+
47
+ | Variable | Description |
48
+ |----------|-------------|
49
+ | `SLACK_BOT_TOKEN` | Bot token (xoxb-...) |
50
+ | `SLACK_USER_TOKEN` | User token (xoxp-...) |
51
+ | `SLACK_TEAM_ID` | Team/workspace ID |
52
+
53
+ ## Multi-Profile Configuration
54
+
55
+ Configuration stored in `~/.connect/connect-slack/`:
56
+
57
+ ```
58
+ ~/.connect/connect-slack/
59
+ ├── current_profile
60
+ └── profiles/
61
+ └── default/
62
+ ├── config.json
63
+ └── tokens.json
64
+ ```
65
+
66
+ ## Dependencies
67
+
68
+ - commander: CLI framework
69
+ - chalk: Terminal styling
@@ -0,0 +1,150 @@
1
+ # @hasna/connect-slack
2
+
3
+ Slack API connector with CLI and library support. Multi-profile configuration for managing multiple workspaces.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun install -g @hasna/connect-slack
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Set your bot token
15
+ connect-slack config set-token xoxb-your-bot-token
16
+
17
+ # Test authentication
18
+ connect-slack test
19
+
20
+ # Send a message
21
+ connect-slack send general "Hello from CLI!"
22
+
23
+ # List channels
24
+ connect-slack channels list
25
+
26
+ # View message history
27
+ connect-slack messages history general --limit 10
28
+ ```
29
+
30
+ ## CLI Commands
31
+
32
+ ### Configuration
33
+
34
+ ```bash
35
+ connect-slack config set-token <token> # Set bot token
36
+ connect-slack config set-user-token <token> # Set user token
37
+ connect-slack config set-channel <channel> # Set default channel
38
+ connect-slack config show # Show configuration
39
+ connect-slack config clear # Clear configuration
40
+ ```
41
+
42
+ ### Profile Management
43
+
44
+ ```bash
45
+ connect-slack profile list # List profiles
46
+ connect-slack profile create <name> # Create profile
47
+ connect-slack profile use <name> # Switch profile
48
+ connect-slack profile delete <name> # Delete profile
49
+ connect-slack profile show # Show current profile
50
+
51
+ # Use specific profile for a command
52
+ connect-slack --profile work channels list
53
+ ```
54
+
55
+ ### Channels
56
+
57
+ ```bash
58
+ connect-slack channels list # List channels
59
+ connect-slack channels info <channel> # Get channel info
60
+ connect-slack channels join <channel> # Join channel
61
+ connect-slack channels leave <channel> # Leave channel
62
+ ```
63
+
64
+ ### Messages
65
+
66
+ ```bash
67
+ connect-slack send <channel> <text> # Quick send
68
+ connect-slack messages send <channel> <text> # Send message
69
+ connect-slack messages send <channel> <text> -t <ts> # Reply to thread
70
+ connect-slack messages history <channel> # View history
71
+ connect-slack messages search <query> # Search messages
72
+ ```
73
+
74
+ ### Users
75
+
76
+ ```bash
77
+ connect-slack users list # List users
78
+ connect-slack users info <user> # Get user info
79
+ connect-slack test # Show current user
80
+ ```
81
+
82
+ ## Library Usage
83
+
84
+ ```typescript
85
+ import { Slack } from '@hasna/connect-slack';
86
+
87
+ const slack = new Slack({
88
+ accessToken: process.env.SLACK_BOT_TOKEN,
89
+ });
90
+
91
+ // Test authentication
92
+ const auth = await slack.test();
93
+ console.log(`Logged in as ${auth.user} in ${auth.team}`);
94
+
95
+ // List channels
96
+ const channels = await slack.channels.list();
97
+ console.log(channels);
98
+
99
+ // Send a message
100
+ await slack.send('C1234567890', 'Hello from the library!');
101
+
102
+ // Get message history
103
+ const messages = await slack.messages.history({
104
+ channel: 'C1234567890',
105
+ limit: 10,
106
+ });
107
+
108
+ // List users
109
+ const users = await slack.users.list();
110
+ ```
111
+
112
+ ## Environment Variables
113
+
114
+ | Variable | Description |
115
+ |----------|-------------|
116
+ | `SLACK_BOT_TOKEN` | Bot token (xoxb-...) |
117
+ | `SLACK_USER_TOKEN` | User token (xoxp-...) |
118
+ | `SLACK_TEAM_ID` | Team/workspace ID |
119
+
120
+ ## Configuration Files
121
+
122
+ Configuration is stored in `~/.connect/connect-slack/`:
123
+
124
+ ```
125
+ ~/.connect/connect-slack/
126
+ ├── current_profile # Active profile name
127
+ └── profiles/
128
+ ├── default/
129
+ │ ├── config.json # Profile settings
130
+ │ └── tokens.json # OAuth tokens
131
+ └── work/
132
+ ├── config.json
133
+ └── tokens.json
134
+ ```
135
+
136
+ ## Getting a Bot Token
137
+
138
+ 1. Go to [Slack API Apps](https://api.slack.com/apps)
139
+ 2. Create a new app or select existing
140
+ 3. Navigate to "OAuth & Permissions"
141
+ 4. Add required scopes:
142
+ - `channels:read`, `channels:history`, `channels:join`
143
+ - `chat:write`
144
+ - `users:read`
145
+ 5. Install to your workspace
146
+ 6. Copy the Bot User OAuth Token
147
+
148
+ ## License
149
+
150
+ Apache-2.0
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@hasna/connect-slack",
3
+ "version": "0.0.1",
4
+ "description": "Slack API connector with CLI and library support",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "connect-slack": "bin/index.js"
10
+ },
11
+ "scripts": {
12
+ "dev": "bun run ./src/cli/index.ts",
13
+ "build": "bun build ./src/index.ts --outdir ./dist --target bun && bun build ./src/cli/index.ts --outdir ./bin --target bun",
14
+ "typecheck": "tsc --noEmit",
15
+ "prepublishOnly": "bun run build"
16
+ },
17
+ "keywords": [
18
+ "slack",
19
+ "api",
20
+ "cli",
21
+ "connector"
22
+ ],
23
+ "author": "Hasna",
24
+ "license": "Apache-2.0",
25
+ "dependencies": {
26
+ "chalk": "^5.3.0",
27
+ "commander": "^12.1.0"
28
+ },
29
+ "devDependencies": {
30
+ "@types/bun": "latest",
31
+ "typescript": "^5.0.0"
32
+ },
33
+ "publishConfig": {
34
+ "registry": "https://registry.npmjs.org",
35
+ "access": "restricted"
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "bin",
40
+ "src",
41
+ "README.md",
42
+ "CLAUDE.md"
43
+ ]
44
+ }
@@ -0,0 +1,112 @@
1
+ import type { SlackClient } from './client';
2
+ import type {
3
+ SlackChannel,
4
+ ConversationsListResponse,
5
+ ConversationsListOptions,
6
+ } from '../types';
7
+
8
+ /**
9
+ * Channels/Conversations API
10
+ */
11
+ export class ChannelsApi {
12
+ constructor(private readonly client: SlackClient) {}
13
+
14
+ /**
15
+ * List all conversations/channels
16
+ */
17
+ async list(options: Omit<ConversationsListOptions, 'channel'> = {}): Promise<SlackChannel[]> {
18
+ const allChannels: SlackChannel[] = [];
19
+ let cursor: string | undefined;
20
+
21
+ do {
22
+ const response = await this.client.get<ConversationsListResponse>(
23
+ 'conversations.list',
24
+ {
25
+ types: options.types || 'public_channel,private_channel',
26
+ exclude_archived: options.exclude_archived ?? true,
27
+ limit: options.limit || 200,
28
+ cursor,
29
+ }
30
+ );
31
+
32
+ allChannels.push(...response.channels);
33
+ cursor = response.response_metadata?.next_cursor;
34
+ } while (cursor && allChannels.length < (options.limit || 1000));
35
+
36
+ return allChannels;
37
+ }
38
+
39
+ /**
40
+ * Get channel info by ID
41
+ */
42
+ async info(channelId: string): Promise<SlackChannel> {
43
+ const response = await this.client.get<{ ok: boolean; channel: SlackChannel }>(
44
+ 'conversations.info',
45
+ { channel: channelId }
46
+ );
47
+ return response.channel;
48
+ }
49
+
50
+ /**
51
+ * Find a channel by name
52
+ */
53
+ async findByName(name: string): Promise<SlackChannel | undefined> {
54
+ const channels = await this.list();
55
+ const normalizedName = name.replace(/^#/, '');
56
+ return channels.find(c => c.name === normalizedName || c.name_normalized === normalizedName);
57
+ }
58
+
59
+ /**
60
+ * Join a channel
61
+ */
62
+ async join(channelId: string): Promise<SlackChannel> {
63
+ const response = await this.client.post<{ ok: boolean; channel: SlackChannel }>(
64
+ 'conversations.join',
65
+ { channel: channelId }
66
+ );
67
+ return response.channel;
68
+ }
69
+
70
+ /**
71
+ * Leave a channel
72
+ */
73
+ async leave(channelId: string): Promise<void> {
74
+ await this.client.post('conversations.leave', { channel: channelId });
75
+ }
76
+
77
+ /**
78
+ * Create a new channel
79
+ */
80
+ async create(name: string, isPrivate = false): Promise<SlackChannel> {
81
+ const response = await this.client.post<{ ok: boolean; channel: SlackChannel }>(
82
+ 'conversations.create',
83
+ { name, is_private: isPrivate }
84
+ );
85
+ return response.channel;
86
+ }
87
+
88
+ /**
89
+ * Archive a channel
90
+ */
91
+ async archive(channelId: string): Promise<void> {
92
+ await this.client.post('conversations.archive', { channel: channelId });
93
+ }
94
+
95
+ /**
96
+ * Unarchive a channel
97
+ */
98
+ async unarchive(channelId: string): Promise<void> {
99
+ await this.client.post('conversations.unarchive', { channel: channelId });
100
+ }
101
+
102
+ /**
103
+ * Get members of a channel
104
+ */
105
+ async members(channelId: string, limit = 200): Promise<string[]> {
106
+ const response = await this.client.get<{ ok: boolean; members: string[] }>(
107
+ 'conversations.members',
108
+ { channel: channelId, limit }
109
+ );
110
+ return response.members;
111
+ }
112
+ }
@@ -0,0 +1,97 @@
1
+ import type { SlackConfig, SlackApiResponse, OutputFormat } from '../types';
2
+ import { SlackApiError } from '../types';
3
+
4
+ const DEFAULT_BASE_URL = 'https://slack.com/api';
5
+
6
+ export interface RequestOptions {
7
+ method?: 'GET' | 'POST';
8
+ params?: Record<string, string | number | boolean | undefined>;
9
+ body?: Record<string, unknown>;
10
+ format?: OutputFormat;
11
+ }
12
+
13
+ export class SlackClient {
14
+ private readonly token: string;
15
+ private readonly baseUrl: string;
16
+
17
+ constructor(config: SlackConfig) {
18
+ const token = config.accessToken || config.botToken;
19
+ if (!token) {
20
+ throw new Error('Slack token is required (accessToken or botToken)');
21
+ }
22
+ this.token = token;
23
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
24
+ }
25
+
26
+ private buildUrl(path: string, params?: Record<string, string | number | boolean | undefined>): string {
27
+ const url = new URL(`${this.baseUrl}/${path}`);
28
+
29
+ if (params) {
30
+ Object.entries(params).forEach(([key, value]) => {
31
+ if (value !== undefined && value !== null && value !== '') {
32
+ url.searchParams.append(key, String(value));
33
+ }
34
+ });
35
+ }
36
+
37
+ return url.toString();
38
+ }
39
+
40
+ async request<T extends SlackApiResponse>(
41
+ path: string,
42
+ options: RequestOptions = {}
43
+ ): Promise<T> {
44
+ const { method = 'GET', params, body } = options;
45
+
46
+ const headers: Record<string, string> = {
47
+ 'Authorization': `Bearer ${this.token}`,
48
+ 'Content-Type': 'application/json; charset=utf-8',
49
+ };
50
+
51
+ const url = this.buildUrl(path, method === 'GET' ? params : undefined);
52
+
53
+ const fetchOptions: RequestInit = {
54
+ method,
55
+ headers,
56
+ };
57
+
58
+ if (body && method === 'POST') {
59
+ fetchOptions.body = JSON.stringify(body);
60
+ }
61
+
62
+ const response = await fetch(url, fetchOptions);
63
+
64
+ if (!response.ok) {
65
+ throw new SlackApiError(
66
+ `HTTP ${response.status}: ${response.statusText}`,
67
+ 'http_error',
68
+ response.status
69
+ );
70
+ }
71
+
72
+ const data = await response.json() as T;
73
+
74
+ if (!data.ok) {
75
+ throw new SlackApiError(
76
+ data.error || 'Unknown Slack API error',
77
+ data.error || 'unknown_error'
78
+ );
79
+ }
80
+
81
+ return data;
82
+ }
83
+
84
+ async get<T extends SlackApiResponse>(
85
+ path: string,
86
+ params?: Record<string, string | number | boolean | undefined>
87
+ ): Promise<T> {
88
+ return this.request<T>(path, { method: 'GET', params });
89
+ }
90
+
91
+ async post<T extends SlackApiResponse>(
92
+ path: string,
93
+ body?: Record<string, unknown>
94
+ ): Promise<T> {
95
+ return this.request<T>(path, { method: 'POST', body });
96
+ }
97
+ }
@@ -0,0 +1,42 @@
1
+ import type { SlackConfig } from '../types';
2
+ import { SlackClient } from './client';
3
+ import { ChannelsApi } from './channels';
4
+ import { MessagesApi } from './messages';
5
+ import { UsersApi } from './users';
6
+
7
+ export { SlackClient } from './client';
8
+ export { ChannelsApi } from './channels';
9
+ export { MessagesApi } from './messages';
10
+ export { UsersApi } from './users';
11
+
12
+ /**
13
+ * Main Slack API class
14
+ */
15
+ export class Slack {
16
+ private readonly client: SlackClient;
17
+
18
+ public readonly channels: ChannelsApi;
19
+ public readonly messages: MessagesApi;
20
+ public readonly users: UsersApi;
21
+
22
+ constructor(config: SlackConfig) {
23
+ this.client = new SlackClient(config);
24
+ this.channels = new ChannelsApi(this.client);
25
+ this.messages = new MessagesApi(this.client);
26
+ this.users = new UsersApi(this.client);
27
+ }
28
+
29
+ /**
30
+ * Test authentication
31
+ */
32
+ async test() {
33
+ return this.users.me();
34
+ }
35
+
36
+ /**
37
+ * Send a message to a channel (convenience method)
38
+ */
39
+ async send(channel: string, text: string) {
40
+ return this.messages.sendText(channel, text);
41
+ }
42
+ }
@@ -0,0 +1,127 @@
1
+ import type { SlackClient } from './client';
2
+ import type {
3
+ SlackMessage,
4
+ ConversationsHistoryResponse,
5
+ ConversationsHistoryOptions,
6
+ ChatPostMessageResponse,
7
+ ChatPostMessageOptions,
8
+ } from '../types';
9
+
10
+ /**
11
+ * Messages API
12
+ */
13
+ export class MessagesApi {
14
+ constructor(private readonly client: SlackClient) {}
15
+
16
+ /**
17
+ * Get message history for a channel
18
+ */
19
+ async history(options: ConversationsHistoryOptions): Promise<SlackMessage[]> {
20
+ const response = await this.client.get<ConversationsHistoryResponse>(
21
+ 'conversations.history',
22
+ {
23
+ channel: options.channel,
24
+ limit: options.limit || 100,
25
+ cursor: options.cursor,
26
+ oldest: options.oldest,
27
+ latest: options.latest,
28
+ inclusive: options.inclusive,
29
+ }
30
+ );
31
+
32
+ return response.messages;
33
+ }
34
+
35
+ /**
36
+ * Send a message to a channel
37
+ */
38
+ async send(options: ChatPostMessageOptions): Promise<ChatPostMessageResponse> {
39
+ return this.client.post<ChatPostMessageResponse>('chat.postMessage', {
40
+ channel: options.channel,
41
+ text: options.text,
42
+ blocks: options.blocks,
43
+ attachments: options.attachments,
44
+ thread_ts: options.thread_ts,
45
+ reply_broadcast: options.reply_broadcast,
46
+ unfurl_links: options.unfurl_links,
47
+ unfurl_media: options.unfurl_media,
48
+ mrkdwn: options.mrkdwn ?? true,
49
+ });
50
+ }
51
+
52
+ /**
53
+ * Send a simple text message
54
+ */
55
+ async sendText(channel: string, text: string): Promise<ChatPostMessageResponse> {
56
+ return this.send({ channel, text });
57
+ }
58
+
59
+ /**
60
+ * Reply in a thread
61
+ */
62
+ async reply(channel: string, threadTs: string, text: string): Promise<ChatPostMessageResponse> {
63
+ return this.send({ channel, text, thread_ts: threadTs });
64
+ }
65
+
66
+ /**
67
+ * Update a message
68
+ */
69
+ async update(channel: string, ts: string, text: string): Promise<SlackMessage> {
70
+ const response = await this.client.post<{ ok: boolean; message: SlackMessage }>(
71
+ 'chat.update',
72
+ { channel, ts, text }
73
+ );
74
+ return response.message;
75
+ }
76
+
77
+ /**
78
+ * Delete a message
79
+ */
80
+ async delete(channel: string, ts: string): Promise<void> {
81
+ await this.client.post('chat.delete', { channel, ts });
82
+ }
83
+
84
+ /**
85
+ * Add a reaction to a message
86
+ */
87
+ async addReaction(channel: string, timestamp: string, emoji: string): Promise<void> {
88
+ await this.client.post('reactions.add', {
89
+ channel,
90
+ timestamp,
91
+ name: emoji.replace(/:/g, ''),
92
+ });
93
+ }
94
+
95
+ /**
96
+ * Remove a reaction from a message
97
+ */
98
+ async removeReaction(channel: string, timestamp: string, emoji: string): Promise<void> {
99
+ await this.client.post('reactions.remove', {
100
+ channel,
101
+ timestamp,
102
+ name: emoji.replace(/:/g, ''),
103
+ });
104
+ }
105
+
106
+ /**
107
+ * Get thread replies
108
+ */
109
+ async thread(channel: string, ts: string, limit = 100): Promise<SlackMessage[]> {
110
+ const response = await this.client.get<{ ok: boolean; messages: SlackMessage[] }>(
111
+ 'conversations.replies',
112
+ { channel, ts, limit }
113
+ );
114
+ return response.messages;
115
+ }
116
+
117
+ /**
118
+ * Search messages
119
+ */
120
+ async search(query: string, count = 20): Promise<SlackMessage[]> {
121
+ const response = await this.client.get<{
122
+ ok: boolean;
123
+ messages: { matches: SlackMessage[] };
124
+ }>('search.messages', { query, count });
125
+ return response.messages.matches;
126
+ }
127
+ }