openclaw-zulip 0.1.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 (88) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/dist/actions.d.ts +3 -0
  4. package/dist/actions.d.ts.map +1 -0
  5. package/dist/actions.js +149 -0
  6. package/dist/actions.js.map +1 -0
  7. package/dist/agent-prompt.d.ts +3 -0
  8. package/dist/agent-prompt.d.ts.map +1 -0
  9. package/dist/agent-prompt.js +21 -0
  10. package/dist/agent-prompt.js.map +1 -0
  11. package/dist/allowlist.d.ts +3 -0
  12. package/dist/allowlist.d.ts.map +1 -0
  13. package/dist/allowlist.js +50 -0
  14. package/dist/allowlist.js.map +1 -0
  15. package/dist/bindings.d.ts +24 -0
  16. package/dist/bindings.d.ts.map +1 -0
  17. package/dist/bindings.js +281 -0
  18. package/dist/bindings.js.map +1 -0
  19. package/dist/commands.d.ts +3 -0
  20. package/dist/commands.d.ts.map +1 -0
  21. package/dist/commands.js +7 -0
  22. package/dist/commands.js.map +1 -0
  23. package/dist/config-schema.d.ts +2 -0
  24. package/dist/config-schema.d.ts.map +1 -0
  25. package/dist/config-schema.js +34 -0
  26. package/dist/config-schema.js.map +1 -0
  27. package/dist/config.d.ts +5 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +53 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/directory.d.ts +3 -0
  32. package/dist/directory.d.ts.map +1 -0
  33. package/dist/directory.js +68 -0
  34. package/dist/directory.js.map +1 -0
  35. package/dist/gateway.d.ts +4 -0
  36. package/dist/gateway.d.ts.map +1 -0
  37. package/dist/gateway.js +324 -0
  38. package/dist/gateway.js.map +1 -0
  39. package/dist/groups.d.ts +3 -0
  40. package/dist/groups.d.ts.map +1 -0
  41. package/dist/groups.js +28 -0
  42. package/dist/groups.js.map +1 -0
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +9 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/messaging.d.ts +3 -0
  48. package/dist/messaging.d.ts.map +1 -0
  49. package/dist/messaging.js +47 -0
  50. package/dist/messaging.js.map +1 -0
  51. package/dist/outbound.d.ts +24 -0
  52. package/dist/outbound.d.ts.map +1 -0
  53. package/dist/outbound.js +114 -0
  54. package/dist/outbound.js.map +1 -0
  55. package/dist/plugin.d.ts +5 -0
  56. package/dist/plugin.d.ts.map +1 -0
  57. package/dist/plugin.js +66 -0
  58. package/dist/plugin.js.map +1 -0
  59. package/dist/resolver.d.ts +3 -0
  60. package/dist/resolver.d.ts.map +1 -0
  61. package/dist/resolver.js +39 -0
  62. package/dist/resolver.js.map +1 -0
  63. package/dist/security.d.ts +4 -0
  64. package/dist/security.d.ts.map +1 -0
  65. package/dist/security.js +15 -0
  66. package/dist/security.js.map +1 -0
  67. package/dist/setup.d.ts +2 -0
  68. package/dist/setup.d.ts.map +1 -0
  69. package/dist/setup.js +25 -0
  70. package/dist/setup.js.map +1 -0
  71. package/dist/status.d.ts +14 -0
  72. package/dist/status.d.ts.map +1 -0
  73. package/dist/status.js +74 -0
  74. package/dist/status.js.map +1 -0
  75. package/dist/threading.d.ts +3 -0
  76. package/dist/threading.d.ts.map +1 -0
  77. package/dist/threading.js +25 -0
  78. package/dist/threading.js.map +1 -0
  79. package/dist/types.d.ts +42 -0
  80. package/dist/types.d.ts.map +1 -0
  81. package/dist/types.js +4 -0
  82. package/dist/types.js.map +1 -0
  83. package/dist/zulip-client.d.ts +115 -0
  84. package/dist/zulip-client.d.ts.map +1 -0
  85. package/dist/zulip-client.js +232 -0
  86. package/dist/zulip-client.js.map +1 -0
  87. package/openclaw.plugin.json +33 -0
  88. package/package.json +53 -0
@@ -0,0 +1,232 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Zulip REST API client — Phase 1 endpoints
3
+ // ---------------------------------------------------------------------------
4
+ export class ZulipClient {
5
+ baseUrl;
6
+ authHeader;
7
+ constructor(config) {
8
+ this.baseUrl = config.serverUrl.replace(/\/+$/, "");
9
+ this.authHeader =
10
+ "Basic " + Buffer.from(`${config.email}:${config.apiKey}`).toString("base64");
11
+ }
12
+ // -------------------------------------------------------------------------
13
+ // Internal helpers
14
+ // -------------------------------------------------------------------------
15
+ async request(method, path, params, retryCount = 0) {
16
+ const url = new URL(`/api/v1${path}`, this.baseUrl);
17
+ const init = {
18
+ method,
19
+ headers: {
20
+ Authorization: this.authHeader,
21
+ },
22
+ };
23
+ if (method === "GET" && params) {
24
+ for (const [k, v] of Object.entries(params)) {
25
+ if (v !== undefined)
26
+ url.searchParams.set(k, String(v));
27
+ }
28
+ }
29
+ else if (params) {
30
+ const body = new URLSearchParams();
31
+ for (const [k, v] of Object.entries(params)) {
32
+ if (v !== undefined)
33
+ body.set(k, String(v));
34
+ }
35
+ init.body = body.toString();
36
+ init.headers["Content-Type"] =
37
+ "application/x-www-form-urlencoded";
38
+ }
39
+ const res = await fetch(url.toString(), init);
40
+ if (res.status === 429) {
41
+ if (retryCount >= 3) {
42
+ throw new Error(`Zulip API rate limited after ${retryCount} retries (${path})`);
43
+ }
44
+ const retryAfter = Number(res.headers.get("retry-after") || "1");
45
+ await new Promise((r) => setTimeout(r, retryAfter * 1000));
46
+ return this.request(method, path, params, retryCount + 1);
47
+ }
48
+ const json = (await res.json());
49
+ if (json.result !== "success") {
50
+ const msg = typeof json.msg === "string" ? json.msg : JSON.stringify(json);
51
+ throw new Error(`Zulip API error (${path}): ${msg}`);
52
+ }
53
+ return json;
54
+ }
55
+ async requestMultipart(method, path, formData, retryCount = 0) {
56
+ const url = new URL(`/api/v1${path}`, this.baseUrl);
57
+ const res = await fetch(url.toString(), {
58
+ method,
59
+ headers: { Authorization: this.authHeader },
60
+ body: formData,
61
+ });
62
+ if (res.status === 429) {
63
+ if (retryCount >= 3) {
64
+ throw new Error(`Zulip API rate limited after ${retryCount} retries (${path})`);
65
+ }
66
+ const retryAfter = Number(res.headers.get("retry-after") || "1");
67
+ await new Promise((r) => setTimeout(r, retryAfter * 1000));
68
+ return this.requestMultipart(method, path, formData, retryCount + 1);
69
+ }
70
+ const json = (await res.json());
71
+ if (json.result !== "success") {
72
+ const msg = typeof json.msg === "string" ? json.msg : JSON.stringify(json);
73
+ throw new Error(`Zulip API error (${path}): ${msg}`);
74
+ }
75
+ return json;
76
+ }
77
+ // -------------------------------------------------------------------------
78
+ // Messages
79
+ // -------------------------------------------------------------------------
80
+ async sendMessage(params) {
81
+ const body = {
82
+ type: params.type,
83
+ to: typeof params.to === "string" ? params.to : JSON.stringify(params.to),
84
+ content: params.content,
85
+ };
86
+ if (params.topic)
87
+ body.topic = params.topic;
88
+ const res = await this.request("POST", "/messages", body);
89
+ return { id: res.id };
90
+ }
91
+ // -------------------------------------------------------------------------
92
+ // Event queue
93
+ // -------------------------------------------------------------------------
94
+ async registerEventQueue(params) {
95
+ const body = {};
96
+ if (params?.eventTypes) {
97
+ body.event_types = JSON.stringify(params.eventTypes);
98
+ }
99
+ if (params?.allPublicStreams) {
100
+ body.all_public_streams = "true";
101
+ }
102
+ const res = await this.request("POST", "/register", body);
103
+ return { queue_id: res.queue_id, last_event_id: res.last_event_id };
104
+ }
105
+ async getEvents(params) {
106
+ const res = await this.request("GET", "/events", {
107
+ queue_id: params.queueId,
108
+ last_event_id: params.lastEventId,
109
+ dont_block: params.dontBlock ? "true" : undefined,
110
+ });
111
+ return res.events;
112
+ }
113
+ async deleteEventQueue(queueId) {
114
+ await this.request("DELETE", "/events", { queue_id: queueId });
115
+ }
116
+ // -------------------------------------------------------------------------
117
+ // Streams
118
+ // -------------------------------------------------------------------------
119
+ async getStreams() {
120
+ const res = await this.request("GET", "/streams");
121
+ return res.streams;
122
+ }
123
+ async getSubscriptions() {
124
+ const res = await this.request("GET", "/users/me/subscriptions");
125
+ return res.subscriptions;
126
+ }
127
+ // -------------------------------------------------------------------------
128
+ // Users
129
+ // -------------------------------------------------------------------------
130
+ async getOwnUser() {
131
+ const res = await this.request("GET", "/users/me");
132
+ return { user_id: res.user_id, email: res.email, full_name: res.full_name };
133
+ }
134
+ // -------------------------------------------------------------------------
135
+ // Message actions
136
+ // -------------------------------------------------------------------------
137
+ async editMessage(messageId, content) {
138
+ await this.request("PATCH", `/messages/${messageId}`, { content });
139
+ }
140
+ async deleteMessage(messageId) {
141
+ await this.request("DELETE", `/messages/${messageId}`);
142
+ }
143
+ async addReaction(messageId, emojiName, emojiCode, reactionType) {
144
+ await this.request("POST", `/messages/${messageId}/reactions`, {
145
+ emoji_name: emojiName,
146
+ ...(emojiCode ? { emoji_code: emojiCode } : {}),
147
+ ...(reactionType ? { reaction_type: reactionType } : {}),
148
+ });
149
+ }
150
+ async removeReaction(messageId, emojiName, emojiCode, reactionType) {
151
+ await this.request("DELETE", `/messages/${messageId}/reactions`, {
152
+ emoji_name: emojiName,
153
+ ...(emojiCode ? { emoji_code: emojiCode } : {}),
154
+ ...(reactionType ? { reaction_type: reactionType } : {}),
155
+ });
156
+ }
157
+ async searchMessages(params) {
158
+ const res = await this.request("GET", "/messages", {
159
+ anchor: String(params.anchor),
160
+ num_before: params.numBefore,
161
+ num_after: params.numAfter,
162
+ narrow: JSON.stringify(params.narrow),
163
+ });
164
+ return res.messages;
165
+ }
166
+ async updateMessageTopic(messageId, topic, propagateMode = "change_all", streamId) {
167
+ await this.request("PATCH", `/messages/${messageId}`, {
168
+ topic,
169
+ propagate_mode: propagateMode,
170
+ ...(streamId !== undefined ? { stream_id: streamId } : {}),
171
+ });
172
+ }
173
+ async sendTypingNotification(params) {
174
+ const body = {
175
+ op: params.op,
176
+ type: params.type,
177
+ };
178
+ if (params.to)
179
+ body.to = JSON.stringify(params.to);
180
+ if (params.streamId !== undefined)
181
+ body.stream_id = String(params.streamId);
182
+ if (params.topic)
183
+ body.topic = params.topic;
184
+ await this.request("POST", "/typing", body);
185
+ }
186
+ // -------------------------------------------------------------------------
187
+ // File upload / download
188
+ // -------------------------------------------------------------------------
189
+ async uploadFile(filename, buffer, mimeType = "application/octet-stream") {
190
+ const form = new FormData();
191
+ form.append("filename", new Blob([new Uint8Array(buffer)], { type: mimeType }), filename);
192
+ const res = await this.requestMultipart("POST", "/user_uploads", form);
193
+ return { uri: res.uri };
194
+ }
195
+ // -------------------------------------------------------------------------
196
+ // Users
197
+ // -------------------------------------------------------------------------
198
+ async getUsers() {
199
+ const res = await this.request("GET", "/users");
200
+ return res.members;
201
+ }
202
+ async getUser(userId) {
203
+ const res = await this.request("GET", `/users/${userId}`);
204
+ return res.user;
205
+ }
206
+ // -------------------------------------------------------------------------
207
+ // Stream details
208
+ // -------------------------------------------------------------------------
209
+ async getStreamById(streamId) {
210
+ const res = await this.request("GET", `/streams/${streamId}`);
211
+ return res.stream;
212
+ }
213
+ async getStreamMembers(streamId) {
214
+ const res = await this.request("GET", `/streams/${streamId}/members`);
215
+ return res.subscribers;
216
+ }
217
+ // -------------------------------------------------------------------------
218
+ // File download
219
+ // -------------------------------------------------------------------------
220
+ async downloadFile(url) {
221
+ // url may be relative (e.g. /user_uploads/...) — prefix with server base
222
+ const fullUrl = url.startsWith("http") ? url : `${this.baseUrl}${url}`;
223
+ const res = await fetch(fullUrl, {
224
+ headers: { Authorization: this.authHeader },
225
+ });
226
+ if (!res.ok) {
227
+ throw new Error(`Zulip download failed (${res.status}): ${url}`);
228
+ }
229
+ return Buffer.from(await res.arrayBuffer());
230
+ }
231
+ }
232
+ //# sourceMappingURL=zulip-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zulip-client.js","sourceRoot":"","sources":["../src/zulip-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ {
2
+ "id": "zulip",
3
+ "channels": ["zulip"],
4
+ "configSchema": {
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "serverUrl": {
9
+ "type": "string",
10
+ "title": "Server URL",
11
+ "description": "Zulip server URL (e.g. https://org.zulipchat.com)"
12
+ },
13
+ "email": {
14
+ "type": "string",
15
+ "title": "Bot email",
16
+ "description": "Bot email address for Zulip API authentication"
17
+ },
18
+ "apiKey": {
19
+ "type": "string",
20
+ "title": "API key",
21
+ "description": "Zulip bot API key",
22
+ "sensitive": true
23
+ },
24
+ "mode": {
25
+ "type": "string",
26
+ "title": "Account mode",
27
+ "description": "bot (default) or user",
28
+ "enum": ["bot", "user"],
29
+ "default": "bot"
30
+ }
31
+ }
32
+ }
33
+ }
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "openclaw-zulip",
3
+ "version": "0.1.0",
4
+ "description": "OpenClaw channel plugin for Zulip — clean-room implementation with ACP topic bindings",
5
+ "license": "MIT",
6
+ "author": "whizzlefred",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/whizzlelabs/openclaw-zulip.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/whizzlelabs/openclaw-zulip/issues"
13
+ },
14
+ "homepage": "https://github.com/whizzlelabs/openclaw-zulip#readme",
15
+ "type": "module",
16
+ "main": "./dist/index.js",
17
+ "types": "./dist/index.d.ts",
18
+ "files": [
19
+ "dist/",
20
+ "openclaw.plugin.json",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "scripts": {
25
+ "build": "tsc",
26
+ "build:watch": "tsc --watch",
27
+ "clean": "rm -rf dist",
28
+ "test": "vitest run",
29
+ "test:watch": "vitest",
30
+ "test:integration": "vitest run --config vitest.integration.config.ts",
31
+ "lint": "eslint src/",
32
+ "prepublishOnly": "npm run clean && npm run build && npm test",
33
+ "prepare": "husky"
34
+ },
35
+ "keywords": [
36
+ "openclaw",
37
+ "openclaw-plugin",
38
+ "openclaw-channel",
39
+ "zulip"
40
+ ],
41
+ "openclaw": {
42
+ "extensions": ["./dist/index.js"]
43
+ },
44
+ "devDependencies": {
45
+ "@typescript-eslint/eslint-plugin": "^8.58.0",
46
+ "@typescript-eslint/parser": "^8.58.0",
47
+ "eslint": "^10.2.0",
48
+ "husky": "^9.1.7",
49
+ "openclaw": "^2026.3.28",
50
+ "typescript": "^5.7.0",
51
+ "vitest": "^4.1.2"
52
+ }
53
+ }