@jimiford/webex 0.1.1
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.
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/dist/channel-plugin.d.ts +18 -0
- package/dist/channel-plugin.js +410 -0
- package/dist/channel.d.ts +98 -0
- package/dist/channel.js +224 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +32 -0
- package/dist/plugin.d.ts +15 -0
- package/dist/plugin.js +23 -0
- package/dist/send.d.ts +92 -0
- package/dist/send.js +304 -0
- package/dist/types.d.ts +223 -0
- package/dist/types.js +6 -0
- package/dist/webhook.d.ts +64 -0
- package/dist/webhook.js +297 -0
- package/openclaw.plugin.json +33 -0
- package/package.json +71 -0
package/dist/send.js
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Webex Message Sending Module
|
|
4
|
+
*/
|
|
5
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
6
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.WebexApiRequestError = exports.WebexSender = void 0;
|
|
10
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
11
|
+
const DEFAULT_API_BASE_URL = 'https://webexapis.com/v1';
|
|
12
|
+
const DEFAULT_MAX_RETRIES = 3;
|
|
13
|
+
const DEFAULT_RETRY_DELAY_MS = 1000;
|
|
14
|
+
// Rate limit status codes that should trigger retry
|
|
15
|
+
const RETRY_STATUS_CODES = [429, 502, 503, 504];
|
|
16
|
+
class WebexSender {
|
|
17
|
+
config;
|
|
18
|
+
apiBaseUrl;
|
|
19
|
+
retryOptions;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
this.apiBaseUrl = config.apiBaseUrl || DEFAULT_API_BASE_URL;
|
|
23
|
+
this.retryOptions = {
|
|
24
|
+
maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
25
|
+
retryDelayMs: config.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Send a message to Webex
|
|
30
|
+
*/
|
|
31
|
+
async send(message) {
|
|
32
|
+
const request = this.buildMessageRequest(message);
|
|
33
|
+
return this.createMessage(request);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Send a text message to a room
|
|
37
|
+
*/
|
|
38
|
+
async sendToRoom(roomId, text, markdown) {
|
|
39
|
+
return this.createMessage({
|
|
40
|
+
roomId,
|
|
41
|
+
text,
|
|
42
|
+
markdown,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Send a direct message to a person by ID
|
|
47
|
+
*/
|
|
48
|
+
async sendDirectById(personId, text, markdown) {
|
|
49
|
+
return this.createMessage({
|
|
50
|
+
toPersonId: personId,
|
|
51
|
+
text,
|
|
52
|
+
markdown,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Send a direct message to a person by email
|
|
57
|
+
*/
|
|
58
|
+
async sendDirectByEmail(email, text, markdown) {
|
|
59
|
+
return this.createMessage({
|
|
60
|
+
toPersonEmail: email,
|
|
61
|
+
text,
|
|
62
|
+
markdown,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Send a message with file attachment
|
|
67
|
+
*/
|
|
68
|
+
async sendWithFile(roomId, text, fileUrl) {
|
|
69
|
+
return this.createMessage({
|
|
70
|
+
roomId,
|
|
71
|
+
text,
|
|
72
|
+
files: [fileUrl],
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Send a threaded reply
|
|
77
|
+
*/
|
|
78
|
+
async sendReply(roomId, parentId, text, markdown) {
|
|
79
|
+
return this.createMessage({
|
|
80
|
+
roomId,
|
|
81
|
+
parentId,
|
|
82
|
+
text,
|
|
83
|
+
markdown,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Get a message by ID
|
|
88
|
+
*/
|
|
89
|
+
async getMessage(messageId) {
|
|
90
|
+
return this.request({
|
|
91
|
+
method: 'GET',
|
|
92
|
+
path: `/messages/${messageId}`,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Delete a message by ID
|
|
97
|
+
*/
|
|
98
|
+
async deleteMessage(messageId) {
|
|
99
|
+
await this.request({
|
|
100
|
+
method: 'DELETE',
|
|
101
|
+
path: `/messages/${messageId}`,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Build a Webex message request from an OpenClaw outbound message
|
|
106
|
+
*/
|
|
107
|
+
buildMessageRequest(message) {
|
|
108
|
+
const request = {};
|
|
109
|
+
// Determine target: roomId, personId, or email
|
|
110
|
+
const to = message.to;
|
|
111
|
+
if (to.includes('@')) {
|
|
112
|
+
request.toPersonEmail = to;
|
|
113
|
+
}
|
|
114
|
+
else if (to.startsWith('Y2lzY29zcGFyazovL3')) {
|
|
115
|
+
// Base64-encoded Webex IDs start with this prefix
|
|
116
|
+
if (to.includes('ROOM')) {
|
|
117
|
+
request.roomId = to;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
request.toPersonId = to;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Assume it's a roomId if not an email
|
|
125
|
+
request.roomId = to;
|
|
126
|
+
}
|
|
127
|
+
// Set content
|
|
128
|
+
if (message.content.text) {
|
|
129
|
+
request.text = message.content.text;
|
|
130
|
+
}
|
|
131
|
+
if (message.content.markdown) {
|
|
132
|
+
request.markdown = message.content.markdown;
|
|
133
|
+
}
|
|
134
|
+
if (message.content.files && message.content.files.length > 0) {
|
|
135
|
+
// Webex only allows one file per message
|
|
136
|
+
request.files = [message.content.files[0]];
|
|
137
|
+
}
|
|
138
|
+
if (message.content.card) {
|
|
139
|
+
request.attachments = [
|
|
140
|
+
{
|
|
141
|
+
contentType: 'application/vnd.microsoft.card.adaptive',
|
|
142
|
+
content: message.content.card,
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
// Set threading
|
|
147
|
+
if (message.parentId) {
|
|
148
|
+
request.parentId = message.parentId;
|
|
149
|
+
}
|
|
150
|
+
return request;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a message via the Webex API
|
|
154
|
+
*/
|
|
155
|
+
async createMessage(request) {
|
|
156
|
+
this.validateMessageRequest(request);
|
|
157
|
+
return this.request({
|
|
158
|
+
method: 'POST',
|
|
159
|
+
path: '/messages',
|
|
160
|
+
body: request,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Validate a message request before sending
|
|
165
|
+
*/
|
|
166
|
+
validateMessageRequest(request) {
|
|
167
|
+
// Must have a target
|
|
168
|
+
if (!request.roomId && !request.toPersonId && !request.toPersonEmail) {
|
|
169
|
+
throw new Error('Message must have a target: roomId, toPersonId, or toPersonEmail');
|
|
170
|
+
}
|
|
171
|
+
// Must have content
|
|
172
|
+
if (!request.text && !request.markdown && !request.files?.length && !request.attachments?.length) {
|
|
173
|
+
throw new Error('Message must have content: text, markdown, files, or attachments');
|
|
174
|
+
}
|
|
175
|
+
// Text has a max size of 7439 bytes
|
|
176
|
+
if (request.text && Buffer.byteLength(request.text, 'utf8') > 7439) {
|
|
177
|
+
throw new Error('Message text exceeds maximum size of 7439 bytes');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Make an API request with retry logic
|
|
182
|
+
*/
|
|
183
|
+
async request(options) {
|
|
184
|
+
let lastError = null;
|
|
185
|
+
let attempt = 0;
|
|
186
|
+
while (attempt <= this.retryOptions.maxRetries) {
|
|
187
|
+
try {
|
|
188
|
+
return await this.executeRequest(options);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
lastError = error;
|
|
192
|
+
attempt++;
|
|
193
|
+
if (attempt > this.retryOptions.maxRetries) {
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
if (!this.shouldRetry(error, attempt)) {
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
// Exponential backoff with jitter
|
|
200
|
+
const delay = this.calculateBackoff(attempt);
|
|
201
|
+
await this.sleep(delay);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
throw lastError || new Error('Request failed after retries');
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Execute a single API request
|
|
208
|
+
*/
|
|
209
|
+
async executeRequest(options) {
|
|
210
|
+
const url = `${this.apiBaseUrl}${options.path}`;
|
|
211
|
+
const headers = {
|
|
212
|
+
'Authorization': `Bearer ${this.config.token}`,
|
|
213
|
+
'Content-Type': 'application/json',
|
|
214
|
+
...options.headers,
|
|
215
|
+
};
|
|
216
|
+
const response = await (0, node_fetch_1.default)(url, {
|
|
217
|
+
method: options.method,
|
|
218
|
+
headers,
|
|
219
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
220
|
+
});
|
|
221
|
+
if (!response.ok) {
|
|
222
|
+
const error = await this.parseErrorResponse(response);
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
// DELETE requests return 204 No Content
|
|
226
|
+
if (response.status === 204) {
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
return response.json();
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Parse error response from Webex API
|
|
233
|
+
*/
|
|
234
|
+
async parseErrorResponse(response) {
|
|
235
|
+
let errorData = null;
|
|
236
|
+
try {
|
|
237
|
+
errorData = await response.json();
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
// Response body might not be JSON
|
|
241
|
+
}
|
|
242
|
+
const message = errorData?.message || `HTTP ${response.status}: ${response.statusText}`;
|
|
243
|
+
const error = new WebexApiRequestError(message, response.status, errorData?.trackingId, errorData?.errors);
|
|
244
|
+
return error;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Determine if a request should be retried
|
|
248
|
+
*/
|
|
249
|
+
shouldRetry(error, attempt) {
|
|
250
|
+
if (error instanceof WebexApiRequestError) {
|
|
251
|
+
return RETRY_STATUS_CODES.includes(error.statusCode);
|
|
252
|
+
}
|
|
253
|
+
// Retry network errors
|
|
254
|
+
return error.message.includes('ECONNRESET') ||
|
|
255
|
+
error.message.includes('ETIMEDOUT') ||
|
|
256
|
+
error.message.includes('ENOTFOUND');
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Calculate backoff delay with exponential backoff and jitter
|
|
260
|
+
*/
|
|
261
|
+
calculateBackoff(attempt) {
|
|
262
|
+
const baseDelay = this.retryOptions.retryDelayMs;
|
|
263
|
+
const exponentialDelay = baseDelay * Math.pow(2, attempt - 1);
|
|
264
|
+
const jitter = Math.random() * 0.3 * exponentialDelay;
|
|
265
|
+
return Math.min(exponentialDelay + jitter, 30000); // Cap at 30 seconds
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Sleep for a given number of milliseconds
|
|
269
|
+
*/
|
|
270
|
+
sleep(ms) {
|
|
271
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
exports.WebexSender = WebexSender;
|
|
275
|
+
/**
|
|
276
|
+
* Custom error class for Webex API errors
|
|
277
|
+
*/
|
|
278
|
+
class WebexApiRequestError extends Error {
|
|
279
|
+
statusCode;
|
|
280
|
+
trackingId;
|
|
281
|
+
details;
|
|
282
|
+
constructor(message, statusCode, trackingId, details) {
|
|
283
|
+
super(message);
|
|
284
|
+
this.name = 'WebexApiRequestError';
|
|
285
|
+
this.statusCode = statusCode;
|
|
286
|
+
this.trackingId = trackingId;
|
|
287
|
+
this.details = details;
|
|
288
|
+
// Maintains proper stack trace for where error was thrown
|
|
289
|
+
if (Error.captureStackTrace) {
|
|
290
|
+
Error.captureStackTrace(this, WebexApiRequestError);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
toJSON() {
|
|
294
|
+
return {
|
|
295
|
+
name: this.name,
|
|
296
|
+
message: this.message,
|
|
297
|
+
statusCode: this.statusCode,
|
|
298
|
+
trackingId: this.trackingId,
|
|
299
|
+
details: this.details,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
exports.WebexApiRequestError = WebexApiRequestError;
|
|
304
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zZW5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7R0FFRzs7Ozs7O0FBRUgsNERBQTZDO0FBVzdDLE1BQU0sb0JBQW9CLEdBQUcsMEJBQTBCLENBQUM7QUFDeEQsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFDOUIsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLENBQUM7QUFFcEMsb0RBQW9EO0FBQ3BELE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUVoRCxNQUFhLFdBQVc7SUFDZCxNQUFNLENBQXFCO0lBQzNCLFVBQVUsQ0FBUztJQUNuQixZQUFZLENBQWU7SUFFbkMsWUFBWSxNQUEwQjtRQUNwQyxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLElBQUksb0JBQW9CLENBQUM7UUFDNUQsSUFBSSxDQUFDLFlBQVksR0FBRztZQUNsQixVQUFVLEVBQUUsTUFBTSxDQUFDLFVBQVUsSUFBSSxtQkFBbUI7WUFDcEQsWUFBWSxFQUFFLE1BQU0sQ0FBQyxZQUFZLElBQUksc0JBQXNCO1NBQzVELENBQUM7SUFDSixDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQWdDO1FBQ3pDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNsRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFVBQVUsQ0FBQyxNQUFjLEVBQUUsSUFBWSxFQUFFLFFBQWlCO1FBQzlELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztZQUN4QixNQUFNO1lBQ04sSUFBSTtZQUNKLFFB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aENELG9EQWdDQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogV2ViZXggTWVzc2FnZSBTZW5kaW5nIE1vZHVsZVxuICovXG5cbmltcG9ydCBmZXRjaCwgeyBSZXNwb25zZSB9IGZyb20gJ25vZGUtZmV0Y2gnO1xuaW1wb3J0IHR5cGUge1xuICBXZWJleENoYW5uZWxDb25maWcsXG4gIFdlYmV4TWVzc2FnZSxcbiAgQ3JlYXRlTWVzc2FnZVJlcXVlc3QsXG4gIE9wZW5DbGF3T3V0Ym91bmRNZXNzYWdlLFxuICBXZWJleEFwaUVycm9yLFxuICBSZXRyeU9wdGlvbnMsXG4gIFJlcXVlc3RPcHRpb25zLFxufSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgREVGQVVMVF9BUElfQkFTRV9VUkwgPSAnaHR0cHM6Ly93ZWJleGFwaXMuY29tL3YxJztcbmNvbnN0IERFRkFVTFRfTUFYX1JFVFJJRVMgPSAzO1xuY29uc3QgREVGQVVMVF9SRVRSWV9ERUxBWV9NUyA9IDEwMDA7XG5cbi8vIFJhdGUgbGltaXQgc3RhdHVzIGNvZGVzIHRoYXQgc2hvdWxkIHRyaWdnZXIgcmV0cnlcbmNvbnN0IFJFVFJZX1NUQVRVU19DT0RFUyA9IFs0MjksIDUwMiwgNTAzLCA1MDRdO1xuXG5leHBvcnQgY2xhc3MgV2ViZXhTZW5kZXIge1xuICBwcml2YXRlIGNvbmZpZzogV2ViZXhDaGFubmVsQ29uZmlnO1xuICBwcml2YXRlIGFwaUJhc2VVcmw6IHN0cmluZztcbiAgcHJpdmF0ZSByZXRyeU9wdGlvbnM6IFJldHJ5T3B0aW9ucztcblxuICBjb25zdHJ1Y3Rvcihjb25maWc6IFdlYmV4Q2hhbm5lbENvbmZpZykge1xuICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xuICAgIHRoaXMuYXBpQmFzZVVybCA9IGNvbmZpZy5hcGlCYXNlVXJsIHx8IERFRkFVTFRfQVBJX0JBU0VfVVJMO1xuICAgIHRoaXMucmV0cnlPcHRpb25zID0ge1xuICAgICAgbWF4UmV0cmllczogY29uZmlnLm1heFJldHJpZXMgPz8gREVGQVVMVF9NQVhfUkVUUklFUyxcbiAgICAgIHJldHJ5RGVsYXlNczogY29uZmlnLnJldHJ5RGVsYXlNcyA/PyBERUZBVUxUX1JFVFJZX0RFTEFZX01TLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIG1lc3NhZ2UgdG8gV2ViZXhcbiAgICovXG4gIGFzeW5jIHNlbmQobWVzc2FnZTogT3BlbkNsYXdPdXRib3VuZE1lc3NhZ2UpOiBQcm9taXNlPFdlYmV4TWVzc2FnZT4ge1xuICAgIGNvbnN0IHJlcXVlc3QgPSB0aGlzLmJ1aWxkTWVzc2FnZVJlcXVlc3QobWVzc2FnZSk7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlTWVzc2FnZShyZXF1ZXN0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kIGEgdGV4dCBtZXNzYWdlIHRvIGEgcm9vbVxuICAgKi9cbiAgYXN5bmMgc2VuZFRvUm9vbShyb29tSWQ6IHN0cmluZywgdGV4dDogc3RyaW5nLCBtYXJrZG93bj86IHN0cmluZyk6IFByb21pc2U8V2ViZXhNZXNzYWdlPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlTWVzc2FnZSh7XG4gICAgICByb29tSWQsXG4gICAgICB0ZXh0LFxuICAgICAgbWFya2Rvd24sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU2VuZCBhIGRpcmVjdCBtZXNzYWdlIHRvIGEgcGVyc29uIGJ5IElEXG4gICAqL1xuICBhc3luYyBzZW5kRGlyZWN0QnlJZChwZXJzb25JZDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcsIG1hcmtkb3duPzogc3RyaW5nKTogUHJvbWlzZTxXZWJleE1lc3NhZ2U+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVNZXNzYWdlKHtcbiAgICAgIHRvUGVyc29uSWQ6IHBlcnNvbklkLFxuICAgICAgdGV4dCxcbiAgICAgIG1hcmtkb3duLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgYSBkaXJlY3QgbWVzc2FnZSB0byBhIHBlcnNvbiBieSBlbWFpbFxuICAgKi9cbiAgYXN5bmMgc2VuZERpcmVjdEJ5RW1haWwoZW1haWw6IHN0cmluZywgdGV4dDogc3RyaW5nLCBtYXJrZG93bj86IHN0cmluZyk6IFByb21pc2U8V2ViZXhNZXNzYWdlPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlTWVzc2FnZSh7XG4gICAgICB0b1BlcnNvbkVtYWlsOiBlbWFpbCxcbiAgICAgIHRleHQsXG4gICAgICBtYXJrZG93bixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZW5kIGEgbWVzc2FnZSB3aXRoIGZpbGUgYXR0YWNobWVudFxuICAgKi9cbiAgYXN5bmMgc2VuZFdpdGhGaWxlKFxuICAgIHJvb21JZDogc3RyaW5nLFxuICAgIHRleHQ6IHN0cmluZyxcbiAgICBmaWxlVXJsOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxXZWJleE1lc3NhZ2U+IHtcbiAgICByZXR1cm4gdGhpcy5jcmVhdGVNZXNzYWdlKHtcbiAgICAgIHJvb21JZCxcbiAgICAgIHRleHQsXG4gICAgICBmaWxlczogW2ZpbGVVcmxdLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlbmQgYSB0aHJlYWRlZCByZXBseVxuICAgKi9cbiAgYXN5bmMgc2VuZFJlcGx5KFxuICAgIHJvb21JZDogc3RyaW5nLFxuICAgIHBhcmVudElkOiBzdHJpbmcsXG4gICAgdGV4dDogc3RyaW5nLFxuICAgIG1hcmtkb3duPzogc3RyaW5nXG4gICk6IFByb21pc2U8V2ViZXhNZXNzYWdlPiB7XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlTWVzc2FnZSh7XG4gICAgICByb29tSWQsXG4gICAgICBwYXJlbnRJZCxcbiAgICAgIHRleHQsXG4gICAgICBtYXJrZG93bixcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBtZXNzYWdlIGJ5IElEXG4gICAqL1xuICBhc3luYyBnZXRNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nKTogUHJvbWlzZTxXZWJleE1lc3NhZ2U+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PFdlYmV4TWVzc2FnZT4oe1xuICAgICAgbWV0aG9kOiAnR0VUJyxcbiAgICAgIHBhdGg6IGAvbWVzc2FnZXMvJHttZXNzYWdlSWR9YCxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgYSBtZXNzYWdlIGJ5IElEXG4gICAqL1xuICBhc3luYyBkZWxldGVNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5yZXF1ZXN0PHZvaWQ+KHtcbiAgICAgIG1ldGhvZDogJ0RFTEVURScsXG4gICAgICBwYXRoOiBgL21lc3NhZ2VzLyR7bWVzc2FnZUlkfWAsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBXZWJleCBtZXNzYWdlIHJlcXVlc3QgZnJvbSBhbiBPcGVuQ2xhdyBvdXRib3VuZCBtZXNzYWdlXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkTWVzc2FnZVJlcXVlc3QobWVzc2FnZTogT3BlbkNsYXdPdXRib3VuZE1lc3NhZ2UpOiBDcmVhdGVNZXNzYWdlUmVxdWVzdCB7XG4gICAgY29uc3QgcmVxdWVzdDogQ3JlYXRlTWVzc2FnZVJlcXVlc3QgPSB7fTtcblxuICAgIC8vIERldGVybWluZSB0YXJnZXQ6IHJvb21JZCwgcGVyc29uSWQsIG9yIGVtYWlsXG4gICAgY29uc3QgdG8gPSBtZXNzYWdlLnRvO1xuICAgIGlmICh0by5pbmNsdWRlcygnQCcpKSB7XG4gICAgICByZXF1ZXN0LnRvUGVyc29uRW1haWwgPSB0bztcbiAgICB9IGVsc2UgaWYgKHRvLnN0YXJ0c1dpdGgoJ1kybHpZMjl6Y0dGeWF6b3ZMMycpKSB7XG4gICAgICAvLyBCYXNlNjQtZW5jb2RlZCBXZWJleCBJRHMgc3RhcnQgd2l0aCB0aGlzIHByZWZpeFxuICAgICAgaWYgKHRvLmluY2x1ZGVzKCdST09NJykpIHtcbiAgICAgICAgcmVxdWVzdC5yb29tSWQgPSB0bztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlcXVlc3QudG9QZXJzb25JZCA9IHRvO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBBc3N1bWUgaXQncyBhIHJvb21JZCBpZiBub3QgYW4gZW1haWxcbiAgICAgIHJlcXVlc3Qucm9vbUlkID0gdG87XG4gICAgfVxuXG4gICAgLy8gU2V0IGNvbnRlbnRcbiAgICBpZiAobWVzc2FnZS5jb250ZW50LnRleHQpIHtcbiAgICAgIHJlcXVlc3QudGV4dCA9IG1lc3NhZ2UuY29udGVudC50ZXh0O1xuICAgIH1cbiAgICBpZiAobWVzc2FnZS5jb250ZW50Lm1hcmtkb3duKSB7XG4gICAgICByZXF1ZXN0Lm1hcmtkb3duID0gbWVzc2FnZS5jb250ZW50Lm1hcmtkb3duO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZS5jb250ZW50LmZpbGVzICYmIG1lc3NhZ2UuY29udGVudC5maWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBXZWJleCBvbmx5IGFsbG93cyBvbmUgZmlsZSBwZXIgbWVzc2FnZVxuICAgICAgcmVxdWVzdC5maWxlcyA9IFttZXNzYWdlLmNvbnRlbnQuZmlsZXNbMF1dO1xuICAgIH1cbiAgICBpZiAobWVzc2FnZS5jb250ZW50LmNhcmQpIHtcbiAgICAgIHJlcXVlc3QuYXR0YWNobWVudHMgPSBbXG4gICAgICAgIHtcbiAgICAgICAgICBjb250ZW50VHlwZTogJ2FwcGxpY2F0aW9uL3ZuZC5taWNyb3NvZnQuY2FyZC5hZGFwdGl2ZScsXG4gICAgICAgICAgY29udGVudDogbWVzc2FnZS5jb250ZW50LmNhcmQsXG4gICAgICAgIH0sXG4gICAgICBdO1xuICAgIH1cblxuICAgIC8vIFNldCB0aHJlYWRpbmdcbiAgICBpZiAobWVzc2FnZS5wYXJlbnRJZCkge1xuICAgICAgcmVxdWVzdC5wYXJlbnRJZCA9IG1lc3NhZ2UucGFyZW50SWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlcXVlc3Q7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbWVzc2FnZSB2aWEgdGhlIFdlYmV4IEFQSVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBjcmVhdGVNZXNzYWdlKHJlcXVlc3Q6IENyZWF0ZU1lc3NhZ2VSZXF1ZXN0KTogUHJvbWlzZTxXZWJleE1lc3NhZ2U+IHtcbiAgICB0aGlzLnZhbGlkYXRlTWVzc2FnZVJlcXVlc3QocmVxdWVzdCk7XG5cbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PFdlYmV4TWVzc2FnZT4oe1xuICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICBwYXRoOiAnL21lc3NhZ2VzJyxcbiAgICAgIGJvZHk6IHJlcXVlc3QsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgYSBtZXNzYWdlIHJlcXVlc3QgYmVmb3JlIHNlbmRpbmdcbiAgICovXG4gIHByaXZhdGUgdmFsaWRhdGVNZXNzYWdlUmVxdWVzdChyZXF1ZXN0OiBDcmVhdGVNZXNzYWdlUmVxdWVzdCk6IHZvaWQge1xuICAgIC8vIE11c3QgaGF2ZSBhIHRhcmdldFxuICAgIGlmICghcmVxdWVzdC5yb29tSWQgJiYgIXJlcXVlc3QudG9QZXJzb25JZCAmJiAhcmVxdWVzdC50b1BlcnNvbkVtYWlsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01lc3NhZ2UgbXVzdCBoYXZlIGEgdGFyZ2V0OiByb29tSWQsIHRvUGVyc29uSWQsIG9yIHRvUGVyc29uRW1haWwnKTtcbiAgICB9XG5cbiAgICAvLyBNdXN0IGhhdmUgY29udGVudFxuICAgIGlmICghcmVxdWVzdC50ZXh0ICYmICFyZXF1ZXN0Lm1hcmtkb3duICYmICFyZXF1ZXN0LmZpbGVzPy5sZW5ndGggJiYgIXJlcXVlc3QuYXR0YWNobWVudHM/Lmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNZXNzYWdlIG11c3QgaGF2ZSBjb250ZW50OiB0ZXh0LCBtYXJrZG93biwgZmlsZXMsIG9yIGF0dGFjaG1lbnRzJyk7XG4gICAgfVxuXG4gICAgLy8gVGV4dCBoYXMgYSBtYXggc2l6ZSBvZiA3NDM5IGJ5dGVzXG4gICAgaWYgKHJlcXVlc3QudGV4dCAmJiBCdWZmZXIuYnl0ZUxlbmd0aChyZXF1ZXN0LnRleHQsICd1dGY4JykgPiA3NDM5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ01lc3NhZ2UgdGV4dCBleGNlZWRzIG1heGltdW0gc2l6ZSBvZiA3NDM5IGJ5dGVzJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYW4gQVBJIHJlcXVlc3Qgd2l0aCByZXRyeSBsb2dpY1xuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZXF1ZXN0PFQ+KG9wdGlvbnM6IFJlcXVlc3RPcHRpb25zKTogUHJvbWlzZTxUPiB7XG4gICAgbGV0IGxhc3RFcnJvcjogRXJyb3IgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgYXR0ZW1wdCA9IDA7XG5cbiAgICB3aGlsZSAoYXR0ZW1wdCA8PSB0aGlzLnJldHJ5T3B0aW9ucy5tYXhSZXRyaWVzKSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leGVjdXRlUmVxdWVzdDxUPihvcHRpb25zKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGxhc3RFcnJvciA9IGVycm9yIGFzIEVycm9yO1xuICAgICAgICBhdHRlbXB0Kys7XG5cbiAgICAgICAgaWYgKGF0dGVtcHQgPiB0aGlzLnJldHJ5T3B0aW9ucy5tYXhSZXRyaWVzKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuc2hvdWxkUmV0cnkoZXJyb3IgYXMgRXJyb3IsIGF0dGVtcHQpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBFeHBvbmVudGlhbCBiYWNrb2ZmIHdpdGggaml0dGVyXG4gICAgICAgIGNvbnN0IGRlbGF5ID0gdGhpcy5jYWxjdWxhdGVCYWNrb2ZmKGF0dGVtcHQpO1xuICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKGRlbGF5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aHJvdyBsYXN0RXJyb3IgfHwgbmV3IEVycm9yKCdSZXF1ZXN0IGZhaWxlZCBhZnRlciByZXRyaWVzJyk7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBhIHNpbmdsZSBBUEkgcmVxdWVzdFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlUmVxdWVzdDxUPihvcHRpb25zOiBSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8VD4ge1xuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuYXBpQmFzZVVybH0ke29wdGlvbnMucGF0aH1gO1xuICAgIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHt0aGlzLmNvbmZpZy50b2tlbn1gLFxuICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgIC4uLm9wdGlvbnMuaGVhZGVycyxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCh1cmwsIHtcbiAgICAgIG1ldGhvZDogb3B0aW9ucy5tZXRob2QsXG4gICAgICBoZWFkZXJzLFxuICAgICAgYm9keTogb3B0aW9ucy5ib2R5ID8gSlNPTi5zdHJpbmdpZnkob3B0aW9ucy5ib2R5KSA6IHVuZGVmaW5lZCxcbiAgICB9KTtcblxuICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgIGNvbnN0IGVycm9yID0gYXdhaXQgdGhpcy5wYXJzZUVycm9yUmVzcG9uc2UocmVzcG9uc2UpO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuXG4gICAgLy8gREVMRVRFIHJlcXVlc3RzIHJldHVybiAyMDQgTm8gQ29udGVudFxuICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPT09IDIwNCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZCBhcyBUO1xuICAgIH1cblxuICAgIHJldHVybiByZXNwb25zZS5qc29uKCkgYXMgUHJvbWlzZTxUPjtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBlcnJvciByZXNwb25zZSBmcm9tIFdlYmV4IEFQSVxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwYXJzZUVycm9yUmVzcG9uc2UocmVzcG9uc2U6IFJlc3BvbnNlKTogUHJvbWlzZTxFcnJvcj4ge1xuICAgIGxldCBlcnJvckRhdGE6IFdlYmV4QXBpRXJyb3IgfCBudWxsID0gbnVsbDtcblxuICAgIHRyeSB7XG4gICAgICBlcnJvckRhdGEgPSBhd2FpdCByZXNwb25zZS5qc29uKCkgYXMgV2ViZXhBcGlFcnJvcjtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFJlc3BvbnNlIGJvZHkgbWlnaHQgbm90IGJlIEpTT05cbiAgICB9XG5cbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3JEYXRhPy5tZXNzYWdlIHx8IGBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWA7XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgV2ViZXhBcGlSZXF1ZXN0RXJyb3IoXG4gICAgICBtZXNzYWdlLFxuICAgICAgcmVzcG9uc2Uuc3RhdHVzLFxuICAgICAgZXJyb3JEYXRhPy50cmFja2luZ0lkLFxuICAgICAgZXJyb3JEYXRhPy5lcnJvcnNcbiAgICApO1xuXG4gICAgcmV0dXJuIGVycm9yO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiBhIHJlcXVlc3Qgc2hvdWxkIGJlIHJldHJpZWRcbiAgICovXG4gIHByaXZhdGUgc2hvdWxkUmV0cnkoZXJyb3I6IEVycm9yLCBhdHRlbXB0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXZWJleEFwaVJlcXVlc3RFcnJvcikge1xuICAgICAgcmV0dXJuIFJFVFJZX1NUQVRVU19DT0RFUy5pbmNsdWRlcyhlcnJvci5zdGF0dXNDb2RlKTtcbiAgICB9XG4gICAgLy8gUmV0cnkgbmV0d29yayBlcnJvcnNcbiAgICByZXR1cm4gZXJyb3IubWVzc2FnZS5pbmNsdWRlcygnRUNPTk5SRVNFVCcpIHx8XG4gICAgICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0VUSU1FRE9VVCcpIHx8XG4gICAgICAgICAgIGVycm9yLm1lc3NhZ2UuaW5jbHVkZXMoJ0VOT1RGT1VORCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBiYWNrb2ZmIGRlbGF5IHdpdGggZXhwb25lbnRpYWwgYmFja29mZiBhbmQgaml0dGVyXG4gICAqL1xuICBwcml2YXRlIGNhbGN1bGF0ZUJhY2tvZmYoYXR0ZW1wdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBjb25zdCBiYXNlRGVsYXkgPSB0aGlzLnJldHJ5T3B0aW9ucy5yZXRyeURlbGF5TXM7XG4gICAgY29uc3QgZXhwb25lbnRpYWxEZWxheSA9IGJhc2VEZWxheSAqIE1hdGgucG93KDIsIGF0dGVtcHQgLSAxKTtcbiAgICBjb25zdCBqaXR0ZXIgPSBNYXRoLnJhbmRvbSgpICogMC4zICogZXhwb25lbnRpYWxEZWxheTtcbiAgICByZXR1cm4gTWF0aC5taW4oZXhwb25lbnRpYWxEZWxheSArIGppdHRlciwgMzAwMDApOyAvLyBDYXAgYXQgMzAgc2Vjb25kc1xuICB9XG5cbiAgLyoqXG4gICAqIFNsZWVwIGZvciBhIGdpdmVuIG51bWJlciBvZiBtaWxsaXNlY29uZHNcbiAgICovXG4gIHByaXZhdGUgc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbiAgfVxufVxuXG4vKipcbiAqIEN1c3RvbSBlcnJvciBjbGFzcyBmb3IgV2ViZXggQVBJIGVycm9yc1xuICovXG5leHBvcnQgY2xhc3MgV2ViZXhBcGlSZXF1ZXN0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHJlYWRvbmx5IHN0YXR1c0NvZGU6IG51bWJlcjtcbiAgcmVhZG9ubHkgdHJhY2tpbmdJZD86IHN0cmluZztcbiAgcmVhZG9ubHkgZGV0YWlscz86IEFycmF5PHsgZGVzY3JpcHRpb246IHN0cmluZyB9PjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgc3RhdHVzQ29kZTogbnVtYmVyLFxuICAgIHRyYWNraW5nSWQ/OiBzdHJpbmcsXG4gICAgZGV0YWlscz86IEFycmF5PHsgZGVzY3JpcHRpb246IHN0cmluZyB9PlxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSAnV2ViZXhBcGlSZXF1ZXN0RXJyb3InO1xuICAgIHRoaXMuc3RhdHVzQ29kZSA9IHN0YXR1c0NvZGU7XG4gICAgdGhpcy50cmFja2luZ0lkID0gdHJhY2tpbmdJZDtcbiAgICB0aGlzLmRldGFpbHMgPSBkZXRhaWxzO1xuXG4gICAgLy8gTWFpbnRhaW5zIHByb3BlciBzdGFjayB0cmFjZSBmb3Igd2hlcmUgZXJyb3Igd2FzIHRocm93blxuICAgIGlmIChFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSkge1xuICAgICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgV2ViZXhBcGlSZXF1ZXN0RXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHRvSlNPTigpOiBvYmplY3Qge1xuICAgIHJldHVybiB7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBtZXNzYWdlOiB0aGlzLm1lc3NhZ2UsXG4gICAgICBzdGF0dXNDb2RlOiB0aGlzLnN0YXR1c0NvZGUsXG4gICAgICB0cmFja2luZ0lkOiB0aGlzLnRyYWNraW5nSWQsXG4gICAgICBkZXRhaWxzOiB0aGlzLmRldGFpbHMsXG4gICAgfTtcbiAgfVxufVxuIl19
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webex Channel Plugin Types
|
|
3
|
+
*/
|
|
4
|
+
export type DmPolicy = 'allow' | 'deny' | 'allowlisted' | 'allowlist' | 'pairing';
|
|
5
|
+
export interface WebexChannelConfig {
|
|
6
|
+
/** Webex Bot access token */
|
|
7
|
+
token: string;
|
|
8
|
+
/** Public URL where webhooks will be received */
|
|
9
|
+
webhookUrl: string;
|
|
10
|
+
/** Policy for handling direct messages */
|
|
11
|
+
dmPolicy: DmPolicy;
|
|
12
|
+
/** List of allowed person IDs or emails (used when dmPolicy is 'allowlisted') */
|
|
13
|
+
allowFrom?: string[];
|
|
14
|
+
/** Webhook secret for payload verification */
|
|
15
|
+
webhookSecret?: string;
|
|
16
|
+
/** Base URL for Webex API (defaults to https://webexapis.com/v1) */
|
|
17
|
+
apiBaseUrl?: string;
|
|
18
|
+
/** Maximum retry attempts for failed requests */
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
/** Retry delay in milliseconds */
|
|
21
|
+
retryDelayMs?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface WebexPerson {
|
|
24
|
+
id: string;
|
|
25
|
+
emails: string[];
|
|
26
|
+
displayName: string;
|
|
27
|
+
nickName?: string;
|
|
28
|
+
firstName?: string;
|
|
29
|
+
lastName?: string;
|
|
30
|
+
avatar?: string;
|
|
31
|
+
orgId: string;
|
|
32
|
+
created: string;
|
|
33
|
+
lastModified?: string;
|
|
34
|
+
type: 'person' | 'bot';
|
|
35
|
+
}
|
|
36
|
+
export interface WebexRoom {
|
|
37
|
+
id: string;
|
|
38
|
+
title: string;
|
|
39
|
+
type: 'direct' | 'group';
|
|
40
|
+
isLocked: boolean;
|
|
41
|
+
teamId?: string;
|
|
42
|
+
lastActivity: string;
|
|
43
|
+
creatorId: string;
|
|
44
|
+
created: string;
|
|
45
|
+
ownerId?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface WebexMessage {
|
|
48
|
+
id: string;
|
|
49
|
+
roomId: string;
|
|
50
|
+
roomType: 'direct' | 'group';
|
|
51
|
+
toPersonId?: string;
|
|
52
|
+
toPersonEmail?: string;
|
|
53
|
+
text?: string;
|
|
54
|
+
markdown?: string;
|
|
55
|
+
html?: string;
|
|
56
|
+
files?: string[];
|
|
57
|
+
personId: string;
|
|
58
|
+
personEmail: string;
|
|
59
|
+
mentionedPeople?: string[];
|
|
60
|
+
mentionedGroups?: string[];
|
|
61
|
+
attachments?: WebexAttachment[];
|
|
62
|
+
created: string;
|
|
63
|
+
updated?: string;
|
|
64
|
+
parentId?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface WebexAttachment {
|
|
67
|
+
contentType: 'application/vnd.microsoft.card.adaptive';
|
|
68
|
+
content: AdaptiveCard;
|
|
69
|
+
}
|
|
70
|
+
export interface AdaptiveCard {
|
|
71
|
+
type: 'AdaptiveCard';
|
|
72
|
+
version: string;
|
|
73
|
+
body: unknown[];
|
|
74
|
+
actions?: unknown[];
|
|
75
|
+
}
|
|
76
|
+
export interface WebexWebhook {
|
|
77
|
+
id: string;
|
|
78
|
+
name: string;
|
|
79
|
+
targetUrl: string;
|
|
80
|
+
resource: WebexWebhookResource;
|
|
81
|
+
event: WebexWebhookEvent;
|
|
82
|
+
filter?: string;
|
|
83
|
+
secret?: string;
|
|
84
|
+
status: 'active' | 'inactive';
|
|
85
|
+
created: string;
|
|
86
|
+
orgId: string;
|
|
87
|
+
createdBy: string;
|
|
88
|
+
appId: string;
|
|
89
|
+
ownedBy: 'creator' | 'org';
|
|
90
|
+
}
|
|
91
|
+
export type WebexWebhookResource = 'messages' | 'memberships' | 'rooms' | 'attachmentActions' | 'meetings' | 'recordings';
|
|
92
|
+
export type WebexWebhookEvent = 'created' | 'updated' | 'deleted' | 'started' | 'ended';
|
|
93
|
+
export interface WebexWebhookPayload {
|
|
94
|
+
id: string;
|
|
95
|
+
name: string;
|
|
96
|
+
targetUrl: string;
|
|
97
|
+
resource: WebexWebhookResource;
|
|
98
|
+
event: WebexWebhookEvent;
|
|
99
|
+
filter?: string;
|
|
100
|
+
orgId: string;
|
|
101
|
+
createdBy: string;
|
|
102
|
+
appId: string;
|
|
103
|
+
ownedBy: string;
|
|
104
|
+
status: string;
|
|
105
|
+
created: string;
|
|
106
|
+
actorId: string;
|
|
107
|
+
data: WebexWebhookData;
|
|
108
|
+
}
|
|
109
|
+
export interface WebexWebhookData {
|
|
110
|
+
id: string;
|
|
111
|
+
roomId: string;
|
|
112
|
+
roomType: 'direct' | 'group';
|
|
113
|
+
personId: string;
|
|
114
|
+
personEmail: string;
|
|
115
|
+
created: string;
|
|
116
|
+
mentionedPeople?: string[];
|
|
117
|
+
mentionedGroups?: string[];
|
|
118
|
+
files?: string[];
|
|
119
|
+
}
|
|
120
|
+
export interface CreateMessageRequest {
|
|
121
|
+
roomId?: string;
|
|
122
|
+
toPersonId?: string;
|
|
123
|
+
toPersonEmail?: string;
|
|
124
|
+
text?: string;
|
|
125
|
+
markdown?: string;
|
|
126
|
+
files?: string[];
|
|
127
|
+
attachments?: WebexAttachment[];
|
|
128
|
+
parentId?: string;
|
|
129
|
+
}
|
|
130
|
+
export interface CreateWebhookRequest {
|
|
131
|
+
name: string;
|
|
132
|
+
targetUrl: string;
|
|
133
|
+
resource: WebexWebhookResource;
|
|
134
|
+
event: WebexWebhookEvent;
|
|
135
|
+
filter?: string;
|
|
136
|
+
secret?: string;
|
|
137
|
+
}
|
|
138
|
+
export interface WebexApiError {
|
|
139
|
+
message: string;
|
|
140
|
+
errors?: Array<{
|
|
141
|
+
description: string;
|
|
142
|
+
}>;
|
|
143
|
+
trackingId: string;
|
|
144
|
+
}
|
|
145
|
+
export interface PaginatedResponse<T> {
|
|
146
|
+
items: T[];
|
|
147
|
+
}
|
|
148
|
+
export interface OpenClawEnvelope {
|
|
149
|
+
/** Unique message identifier */
|
|
150
|
+
id: string;
|
|
151
|
+
/** Channel identifier */
|
|
152
|
+
channel: 'webex';
|
|
153
|
+
/** Conversation/thread identifier */
|
|
154
|
+
conversationId: string;
|
|
155
|
+
/** Message author information */
|
|
156
|
+
author: {
|
|
157
|
+
id: string;
|
|
158
|
+
email?: string;
|
|
159
|
+
displayName?: string;
|
|
160
|
+
isBot: boolean;
|
|
161
|
+
};
|
|
162
|
+
/** Message content */
|
|
163
|
+
content: {
|
|
164
|
+
text?: string;
|
|
165
|
+
markdown?: string;
|
|
166
|
+
attachments?: OpenClawAttachment[];
|
|
167
|
+
};
|
|
168
|
+
/** Message metadata */
|
|
169
|
+
metadata: {
|
|
170
|
+
roomType: 'direct' | 'group';
|
|
171
|
+
roomId: string;
|
|
172
|
+
timestamp: string;
|
|
173
|
+
mentions?: string[];
|
|
174
|
+
parentId?: string;
|
|
175
|
+
raw: WebexMessage;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
export interface OpenClawAttachment {
|
|
179
|
+
type: 'file' | 'card';
|
|
180
|
+
url?: string;
|
|
181
|
+
content?: unknown;
|
|
182
|
+
}
|
|
183
|
+
export interface OpenClawOutboundMessage {
|
|
184
|
+
/** Target conversation ID (roomId) or person ID/email for DMs */
|
|
185
|
+
to: string;
|
|
186
|
+
/** Message content */
|
|
187
|
+
content: {
|
|
188
|
+
text?: string;
|
|
189
|
+
markdown?: string;
|
|
190
|
+
files?: string[];
|
|
191
|
+
card?: AdaptiveCard;
|
|
192
|
+
};
|
|
193
|
+
/** Optional parent message ID for threading */
|
|
194
|
+
parentId?: string;
|
|
195
|
+
}
|
|
196
|
+
export interface WebexChannelPlugin {
|
|
197
|
+
name: string;
|
|
198
|
+
version: string;
|
|
199
|
+
/** Initialize the channel with configuration */
|
|
200
|
+
initialize(config: WebexChannelConfig): Promise<void>;
|
|
201
|
+
/** Send a message */
|
|
202
|
+
send(message: OpenClawOutboundMessage): Promise<WebexMessage>;
|
|
203
|
+
/** Handle incoming webhook */
|
|
204
|
+
handleWebhook(payload: WebexWebhookPayload, signature?: string): Promise<OpenClawEnvelope | null>;
|
|
205
|
+
/** Register webhooks with Webex */
|
|
206
|
+
registerWebhooks(): Promise<WebexWebhook[]>;
|
|
207
|
+
/** Cleanup and shutdown */
|
|
208
|
+
shutdown(): Promise<void>;
|
|
209
|
+
}
|
|
210
|
+
export interface WebhookHandler {
|
|
211
|
+
(envelope: OpenClawEnvelope): Promise<void> | void;
|
|
212
|
+
}
|
|
213
|
+
export interface RetryOptions {
|
|
214
|
+
maxRetries: number;
|
|
215
|
+
retryDelayMs: number;
|
|
216
|
+
shouldRetry?: (error: Error, attempt: number) => boolean;
|
|
217
|
+
}
|
|
218
|
+
export interface RequestOptions {
|
|
219
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
220
|
+
path: string;
|
|
221
|
+
body?: unknown;
|
|
222
|
+
headers?: Record<string, string>;
|
|
223
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Webex Channel Plugin Types
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXZWJleCBDaGFubmVsIFBsdWdpbiBUeXBlc1xuICovXG5cbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vIENvbmZpZ3VyYXRpb24gVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IHR5cGUgRG1Qb2xpY3kgPSAnYWxsb3cnIHwgJ2RlbnknIHwgJ2FsbG93bGlzdGVkJyB8ICdhbGxvd2xpc3QnIHwgJ3BhaXJpbmcnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYmV4Q2hhbm5lbENvbmZpZyB7XG4gIC8qKiBXZWJleCBCb3QgYWNjZXNzIHRva2VuICovXG4gIHRva2VuOiBzdHJpbmc7XG5cbiAgLyoqIFB1YmxpYyBVUkwgd2hlcmUgd2ViaG9va3Mgd2lsbCBiZSByZWNlaXZlZCAqL1xuICB3ZWJob29rVXJsOiBzdHJpbmc7XG5cbiAgLyoqIFBvbGljeSBmb3IgaGFuZGxpbmcgZGlyZWN0IG1lc3NhZ2VzICovXG4gIGRtUG9saWN5OiBEbVBvbGljeTtcblxuICAvKiogTGlzdCBvZiBhbGxvd2VkIHBlcnNvbiBJRHMgb3IgZW1haWxzICh1c2VkIHdoZW4gZG1Qb2xpY3kgaXMgJ2FsbG93bGlzdGVkJykgKi9cbiAgYWxsb3dGcm9tPzogc3RyaW5nW107XG5cbiAgLyoqIFdlYmhvb2sgc2VjcmV0IGZvciBwYXlsb2FkIHZlcmlmaWNhdGlvbiAqL1xuICB3ZWJob29rU2VjcmV0Pzogc3RyaW5nO1xuXG4gIC8qKiBCYXNlIFVSTCBmb3IgV2ViZXggQVBJIChkZWZhdWx0cyB0byBodHRwczovL3dlYmV4YXBpcy5jb20vdjEpICovXG4gIGFwaUJhc2VVcmw/OiBzdHJpbmc7XG5cbiAgLyoqIE1heGltdW0gcmV0cnkgYXR0ZW1wdHMgZm9yIGZhaWxlZCByZXF1ZXN0cyAqL1xuICBtYXhSZXRyaWVzPzogbnVtYmVyO1xuXG4gIC8qKiBSZXRyeSBkZWxheSBpbiBtaWxsaXNlY29uZHMgKi9cbiAgcmV0cnlEZWxheU1zPzogbnVtYmVyO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBXZWJleCBBUEkgVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBXZWJleFBlcnNvbiB7XG4gIGlkOiBzdHJpbmc7XG4gIGVtYWlsczogc3RyaW5nW107XG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIG5pY2tOYW1lPzogc3RyaW5nO1xuICBmaXJzdE5hbWU/OiBzdHJpbmc7XG4gIGxhc3ROYW1lPzogc3RyaW5nO1xuICBhdmF0YXI/OiBzdHJpbmc7XG4gIG9yZ0lkOiBzdHJpbmc7XG4gIGNyZWF0ZWQ6IHN0cmluZztcbiAgbGFzdE1vZGlmaWVkPzogc3RyaW5nO1xuICB0eXBlOiAncGVyc29uJyB8ICdib3QnO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdlYmV4Um9vbSB7XG4gIGlkOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIHR5cGU6ICdkaXJlY3QnIHwgJ2dyb3VwJztcbiAgaXNMb2NrZWQ6IGJvb2xlYW47XG4gIHRlYW1JZD86IHN0cmluZztcbiAgbGFzdEFjdGl2aXR5OiBzdHJpbmc7XG4gIGNyZWF0b3JJZDogc3RyaW5nO1xuICBjcmVhdGVkOiBzdHJpbmc7XG4gIG93bmVySWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViZXhNZXNzYWdlIHtcbiAgaWQ6IHN0cmluZztcbiAgcm9vbUlkOiBzdHJpbmc7XG4gIHJvb21UeXBlOiAnZGlyZWN0JyB8ICdncm91cCc7XG4gIHRvUGVyc29uSWQ/OiBzdHJpbmc7XG4gIHRvUGVyc29uRW1haWw/OiBzdHJpbmc7XG4gIHRleHQ/OiBzdHJpbmc7XG4gIG1hcmtkb3duPzogc3RyaW5nO1xuICBodG1sPzogc3RyaW5nO1xuICBmaWxlcz86IHN0cmluZ1tdO1xuICBwZXJzb25JZDogc3RyaW5nO1xuICBwZXJzb25FbWFpbDogc3RyaW5nO1xuICBtZW50aW9uZWRQZW9wbGU/OiBzdHJpbmdbXTtcbiAgbWVudGlvbmVkR3JvdXBzPzogc3RyaW5nW107XG4gIGF0dGFjaG1lbnRzPzogV2ViZXhBdHRhY2htZW50W107XG4gIGNyZWF0ZWQ6IHN0cmluZztcbiAgdXBkYXRlZD86IHN0cmluZztcbiAgcGFyZW50SWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViZXhBdHRhY2htZW50IHtcbiAgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi92bmQubWljcm9zb2Z0LmNhcmQuYWRhcHRpdmUnO1xuICBjb250ZW50OiBBZGFwdGl2ZUNhcmQ7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWRhcHRpdmVDYXJkIHtcbiAgdHlwZTogJ0FkYXB0aXZlQ2FyZCc7XG4gIHZlcnNpb246IHN0cmluZztcbiAgYm9keTogdW5rbm93bltdO1xuICBhY3Rpb25zPzogdW5rbm93bltdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdlYmV4V2ViaG9vayB7XG4gIGlkOiBzdHJpbmc7XG4gIG5hbWU6IHN0cmluZztcbiAgdGFyZ2V0VXJsOiBzdHJpbmc7XG4gIHJlc291cmNlOiBXZWJleFdlYmhvb2tSZXNvdXJjZTtcbiAgZXZlbnQ6IFdlYmV4V2ViaG9va0V2ZW50O1xuICBmaWx0ZXI/OiBzdHJpbmc7XG4gIHNlY3JldD86IHN0cmluZztcbiAgc3RhdHVzOiAnYWN0aXZlJyB8ICdpbmFjdGl2ZSc7XG4gIGNyZWF0ZWQ6IHN0cmluZztcbiAgb3JnSWQ6IHN0cmluZztcbiAgY3JlYXRlZEJ5OiBzdHJpbmc7XG4gIGFwcElkOiBzdHJpbmc7XG4gIG93bmVkQnk6ICdjcmVhdG9yJyB8ICdvcmcnO1xufVxuXG5leHBvcnQgdHlwZSBXZWJleFdlYmhvb2tSZXNvdXJjZSA9XG4gIHwgJ21lc3NhZ2VzJ1xuICB8ICdtZW1iZXJzaGlwcydcbiAgfCAncm9vbXMnXG4gIHwgJ2F0dGFjaG1lbnRBY3Rpb25zJ1xuICB8ICdtZWV0aW5ncydcbiAgfCAncmVjb3JkaW5ncyc7XG5cbmV4cG9ydCB0eXBlIFdlYmV4V2ViaG9va0V2ZW50ID1cbiAgfCAnY3JlYXRlZCdcbiAgfCAndXBkYXRlZCdcbiAgfCAnZGVsZXRlZCdcbiAgfCAnc3RhcnRlZCdcbiAgfCAnZW5kZWQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFdlYmV4V2ViaG9va1BheWxvYWQge1xuICBpZDogc3RyaW5nO1xuICBuYW1lOiBzdHJpbmc7XG4gIHRhcmdldFVybDogc3RyaW5nO1xuICByZXNvdXJjZTogV2ViZXhXZWJob29rUmVzb3VyY2U7XG4gIGV2ZW50OiBXZWJleFdlYmhvb2tFdmVudDtcbiAgZmlsdGVyPzogc3RyaW5nO1xuICBvcmdJZDogc3RyaW5nO1xuICBjcmVhdGVkQnk6IHN0cmluZztcbiAgYXBwSWQ6IHN0cmluZztcbiAgb3duZWRCeTogc3RyaW5nO1xuICBzdGF0dXM6IHN0cmluZztcbiAgY3JlYXRlZDogc3RyaW5nO1xuICBhY3RvcklkOiBzdHJpbmc7XG4gIGRhdGE6IFdlYmV4V2ViaG9va0RhdGE7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2ViZXhXZWJob29rRGF0YSB7XG4gIGlkOiBzdHJpbmc7XG4gIHJvb21JZDogc3RyaW5nO1xuICByb29tVHlwZTogJ2RpcmVjdCcgfCAnZ3JvdXAnO1xuICBwZXJzb25JZDogc3RyaW5nO1xuICBwZXJzb25FbWFpbDogc3RyaW5nO1xuICBjcmVhdGVkOiBzdHJpbmc7XG4gIG1lbnRpb25lZFBlb3BsZT86IHN0cmluZ1tdO1xuICBtZW50aW9uZWRHcm91cHM/OiBzdHJpbmdbXTtcbiAgZmlsZXM/OiBzdHJpbmdbXTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gQVBJIFJlcXVlc3QvUmVzcG9uc2UgVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVNZXNzYWdlUmVxdWVzdCB7XG4gIHJvb21JZD86IHN0cmluZztcbiAgdG9QZXJzb25JZD86IHN0cmluZztcbiAgdG9QZXJzb25FbWFpbD86IHN0cmluZztcbiAgdGV4dD86IHN0cmluZztcbiAgbWFya2Rvd24/OiBzdHJpbmc7XG4gIGZpbGVzPzogc3RyaW5nW107XG4gIGF0dGFjaG1lbnRzPzogV2ViZXhBdHRhY2htZW50W107XG4gIHBhcmVudElkPzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENyZWF0ZVdlYmhvb2tSZXF1ZXN0IHtcbiAgbmFtZTogc3RyaW5nO1xuICB0YXJnZXRVcmw6IHN0cmluZztcbiAgcmVzb3VyY2U6IFdlYmV4V2ViaG9va1Jlc291cmNlO1xuICBldmVudDogV2ViZXhXZWJob29rRXZlbnQ7XG4gIGZpbHRlcj86IHN0cmluZztcbiAgc2VjcmV0Pzogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFdlYmV4QXBpRXJyb3Ige1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGVycm9ycz86IEFycmF5PHtcbiAgICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB9PjtcbiAgdHJhY2tpbmdJZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFBhZ2luYXRlZFJlc3BvbnNlPFQ+IHtcbiAgaXRlbXM6IFRbXTtcbn1cblxuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuLy8gT3BlbkNsYXcgRW52ZWxvcGUgVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQ2xhd0VudmVsb3BlIHtcbiAgLyoqIFVuaXF1ZSBtZXNzYWdlIGlkZW50aWZpZXIgKi9cbiAgaWQ6IHN0cmluZztcblxuICAvKiogQ2hhbm5lbCBpZGVudGlmaWVyICovXG4gIGNoYW5uZWw6ICd3ZWJleCc7XG5cbiAgLyoqIENvbnZlcnNhdGlvbi90aHJlYWQgaWRlbnRpZmllciAqL1xuICBjb252ZXJzYXRpb25JZDogc3RyaW5nO1xuXG4gIC8qKiBNZXNzYWdlIGF1dGhvciBpbmZvcm1hdGlvbiAqL1xuICBhdXRob3I6IHtcbiAgICBpZDogc3RyaW5nO1xuICAgIGVtYWlsPzogc3RyaW5nO1xuICAgIGRpc3BsYXlOYW1lPzogc3RyaW5nO1xuICAgIGlzQm90OiBib29sZWFuO1xuICB9O1xuXG4gIC8qKiBNZXNzYWdlIGNvbnRlbnQgKi9cbiAgY29udGVudDoge1xuICAgIHRleHQ/OiBzdHJpbmc7XG4gICAgbWFya2Rvd24/OiBzdHJpbmc7XG4gICAgYXR0YWNobWVudHM/OiBPcGVuQ2xhd0F0dGFjaG1lbnRbXTtcbiAgfTtcblxuICAvKiogTWVzc2FnZSBtZXRhZGF0YSAqL1xuICBtZXRhZGF0YToge1xuICAgIHJvb21UeXBlOiAnZGlyZWN0JyB8ICdncm91cCc7XG4gICAgcm9vbUlkOiBzdHJpbmc7XG4gICAgdGltZXN0YW1wOiBzdHJpbmc7XG4gICAgbWVudGlvbnM/OiBzdHJpbmdbXTtcbiAgICBwYXJlbnRJZD86IHN0cmluZztcbiAgICByYXc6IFdlYmV4TWVzc2FnZTtcbiAgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQ2xhd0F0dGFjaG1lbnQge1xuICB0eXBlOiAnZmlsZScgfCAnY2FyZCc7XG4gIHVybD86IHN0cmluZztcbiAgY29udGVudD86IHVua25vd247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkNsYXdPdXRib3VuZE1lc3NhZ2Uge1xuICAvKiogVGFyZ2V0IGNvbnZlcnNhdGlvbiBJRCAocm9vbUlkKSBvciBwZXJzb24gSUQvZW1haWwgZm9yIERNcyAqL1xuICB0bzogc3RyaW5nO1xuXG4gIC8qKiBNZXNzYWdlIGNvbnRlbnQgKi9cbiAgY29udGVudDoge1xuICAgIHRleHQ/OiBzdHJpbmc7XG4gICAgbWFya2Rvd24/OiBzdHJpbmc7XG4gICAgZmlsZXM/OiBzdHJpbmdbXTtcbiAgICBjYXJkPzogQWRhcHRpdmVDYXJkO1xuICB9O1xuXG4gIC8qKiBPcHRpb25hbCBwYXJlbnQgbWVzc2FnZSBJRCBmb3IgdGhyZWFkaW5nICovXG4gIHBhcmVudElkPzogc3RyaW5nO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBQbHVnaW4gVHlwZXNcbi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuZXhwb3J0IGludGVyZmFjZSBXZWJleENoYW5uZWxQbHVnaW4ge1xuICBuYW1lOiBzdHJpbmc7XG4gIHZlcnNpb246IHN0cmluZztcblxuICAvKiogSW5pdGlhbGl6ZSB0aGUgY2hhbm5lbCB3aXRoIGNvbmZpZ3VyYXRpb24gKi9cbiAgaW5pdGlhbGl6ZShjb25maWc6IFdlYmV4Q2hhbm5lbENvbmZpZyk6IFByb21pc2U8dm9pZD47XG5cbiAgLyoqIFNlbmQgYSBtZXNzYWdlICovXG4gIHNlbmQobWVzc2FnZTogT3BlbkNsYXdPdXRib3VuZE1lc3NhZ2UpOiBQcm9taXNlPFdlYmV4TWVzc2FnZT47XG5cbiAgLyoqIEhhbmRsZSBpbmNvbWluZyB3ZWJob29rICovXG4gIGhhbmRsZVdlYmhvb2socGF5bG9hZDogV2ViZXhXZWJob29rUGF5bG9hZCwgc2lnbmF0dXJlPzogc3RyaW5nKTogUHJvbWlzZTxPcGVuQ2xhd0VudmVsb3BlIHwgbnVsbD47XG5cbiAgLyoqIFJlZ2lzdGVyIHdlYmhvb2tzIHdpdGggV2ViZXggKi9cbiAgcmVnaXN0ZXJXZWJob29rcygpOiBQcm9taXNlPFdlYmV4V2ViaG9va1tdPjtcblxuICAvKiogQ2xlYW51cCBhbmQgc2h1dGRvd24gKi9cbiAgc2h1dGRvd24oKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBXZWJob29rSGFuZGxlciB7XG4gIChlbnZlbG9wZTogT3BlbkNsYXdFbnZlbG9wZSk6IFByb21pc2U8dm9pZD4gfCB2b2lkO1xufVxuXG4vLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4vLyBJbnRlcm5hbCBUeXBlc1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgaW50ZXJmYWNlIFJldHJ5T3B0aW9ucyB7XG4gIG1heFJldHJpZXM6IG51bWJlcjtcbiAgcmV0cnlEZWxheU1zOiBudW1iZXI7XG4gIHNob3VsZFJldHJ5PzogKGVycm9yOiBFcnJvciwgYXR0ZW1wdDogbnVtYmVyKSA9PiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlcXVlc3RPcHRpb25zIHtcbiAgbWV0aG9kOiAnR0VUJyB8ICdQT1NUJyB8ICdQVVQnIHwgJ0RFTEVURSc7XG4gIHBhdGg6IHN0cmluZztcbiAgYm9keT86IHVua25vd247XG4gIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xufVxuIl19
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webex Webhook Handler Module
|
|
3
|
+
*/
|
|
4
|
+
import type { WebexChannelConfig, WebexWebhookPayload, WebexWebhook, CreateWebhookRequest, OpenClawEnvelope } from './types';
|
|
5
|
+
export declare class WebexWebhookHandler {
|
|
6
|
+
private config;
|
|
7
|
+
private apiBaseUrl;
|
|
8
|
+
private botId;
|
|
9
|
+
constructor(config: WebexChannelConfig);
|
|
10
|
+
/**
|
|
11
|
+
* Initialize the webhook handler (fetch bot info)
|
|
12
|
+
*/
|
|
13
|
+
initialize(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Handle an incoming webhook request
|
|
16
|
+
*/
|
|
17
|
+
handleWebhook(payload: WebexWebhookPayload, signature?: string): Promise<OpenClawEnvelope | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Verify webhook signature using HMAC-SHA1
|
|
20
|
+
*/
|
|
21
|
+
verifySignature(payload: WebexWebhookPayload, signature: string): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Check if the sender is allowed based on DM policy
|
|
24
|
+
*/
|
|
25
|
+
private isAllowedSender;
|
|
26
|
+
/**
|
|
27
|
+
* Fetch full message details from Webex API
|
|
28
|
+
*/
|
|
29
|
+
private fetchMessage;
|
|
30
|
+
/**
|
|
31
|
+
* Normalize a Webex message to OpenClaw envelope format
|
|
32
|
+
*/
|
|
33
|
+
private normalizeMessage;
|
|
34
|
+
/**
|
|
35
|
+
* Register webhooks with Webex
|
|
36
|
+
*/
|
|
37
|
+
registerWebhooks(): Promise<WebexWebhook[]>;
|
|
38
|
+
/**
|
|
39
|
+
* List all webhooks
|
|
40
|
+
*/
|
|
41
|
+
listWebhooks(): Promise<WebexWebhook[]>;
|
|
42
|
+
/**
|
|
43
|
+
* Create a webhook
|
|
44
|
+
*/
|
|
45
|
+
createWebhook(request: CreateWebhookRequest): Promise<WebexWebhook>;
|
|
46
|
+
/**
|
|
47
|
+
* Delete a webhook
|
|
48
|
+
*/
|
|
49
|
+
deleteWebhook(webhookId: string): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Get bot information
|
|
52
|
+
*/
|
|
53
|
+
private getBotInfo;
|
|
54
|
+
/**
|
|
55
|
+
* Get the bot ID (after initialization)
|
|
56
|
+
*/
|
|
57
|
+
getBotId(): string | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Custom error for webhook validation failures
|
|
61
|
+
*/
|
|
62
|
+
export declare class WebhookValidationError extends Error {
|
|
63
|
+
constructor(message: string);
|
|
64
|
+
}
|