@teamlearners/clawops 0.15.0 → 0.16.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.
package/dist/index.d.ts CHANGED
@@ -17,6 +17,13 @@ declare class APIClient {
17
17
  protected _defaultHeaders: Record<string, string>;
18
18
  constructor(options: APIClientOptions);
19
19
  private _buildHeaders;
20
+ protected _send(method: string, path: string, options?: {
21
+ body?: Record<string, unknown> | null;
22
+ query?: Record<string, unknown> | null;
23
+ extraHeaders?: Record<string, string>;
24
+ extraQuery?: Record<string, unknown>;
25
+ timeout?: number;
26
+ }): Promise<Response>;
20
27
  protected _request<T>(method: string, path: string, options?: {
21
28
  body?: Record<string, unknown> | null;
22
29
  query?: Record<string, unknown> | null;
@@ -49,6 +56,12 @@ declare class APIClient {
49
56
  extraQuery?: Record<string, unknown>;
50
57
  timeout?: number;
51
58
  }): Promise<T>;
59
+ _getRaw(path: string, options?: {
60
+ query?: Record<string, unknown> | null;
61
+ extraHeaders?: Record<string, string>;
62
+ extraQuery?: Record<string, unknown>;
63
+ timeout?: number;
64
+ }): Promise<Response>;
52
65
  _delete(path: string, options?: {
53
66
  extraHeaders?: Record<string, string>;
54
67
  timeout?: number;
@@ -86,6 +99,148 @@ declare class Page<T> {
86
99
  autoPagingIter(): AsyncGenerator<T>;
87
100
  }
88
101
 
102
+ declare const AssignmentLinkAssignmentSchema: z.ZodObject<{
103
+ number: z.ZodString;
104
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
105
+ consumedAt: z.ZodString;
106
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
107
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
108
+ number: z.ZodString;
109
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
110
+ consumedAt: z.ZodString;
111
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
112
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
113
+ number: z.ZodString;
114
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
115
+ consumedAt: z.ZodString;
116
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
117
+ }, z.ZodTypeAny, "passthrough">>;
118
+ declare const AssignmentLinkSchema: z.ZodObject<{
119
+ linkId: z.ZodString;
120
+ url: z.ZodString;
121
+ status: z.ZodEnum<["pending", "consumed", "expired", "revoked"]>;
122
+ createdAt: z.ZodString;
123
+ expiresAt: z.ZodString;
124
+ consumedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
125
+ webhookUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
126
+ webhookMethod: z.ZodOptional<z.ZodNullable<z.ZodEnum<["POST", "GET"]>>>;
127
+ note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
128
+ assignment: z.ZodOptional<z.ZodNullable<z.ZodObject<{
129
+ number: z.ZodString;
130
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
131
+ consumedAt: z.ZodString;
132
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
133
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
134
+ number: z.ZodString;
135
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
136
+ consumedAt: z.ZodString;
137
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
138
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
139
+ number: z.ZodString;
140
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
141
+ consumedAt: z.ZodString;
142
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
143
+ }, z.ZodTypeAny, "passthrough">>>>;
144
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
145
+ linkId: z.ZodString;
146
+ url: z.ZodString;
147
+ status: z.ZodEnum<["pending", "consumed", "expired", "revoked"]>;
148
+ createdAt: z.ZodString;
149
+ expiresAt: z.ZodString;
150
+ consumedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
151
+ webhookUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
152
+ webhookMethod: z.ZodOptional<z.ZodNullable<z.ZodEnum<["POST", "GET"]>>>;
153
+ note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
154
+ assignment: z.ZodOptional<z.ZodNullable<z.ZodObject<{
155
+ number: z.ZodString;
156
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
157
+ consumedAt: z.ZodString;
158
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
159
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
160
+ number: z.ZodString;
161
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
162
+ consumedAt: z.ZodString;
163
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
164
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
165
+ number: z.ZodString;
166
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
167
+ consumedAt: z.ZodString;
168
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
169
+ }, z.ZodTypeAny, "passthrough">>>>;
170
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
171
+ linkId: z.ZodString;
172
+ url: z.ZodString;
173
+ status: z.ZodEnum<["pending", "consumed", "expired", "revoked"]>;
174
+ createdAt: z.ZodString;
175
+ expiresAt: z.ZodString;
176
+ consumedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
177
+ webhookUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
178
+ webhookMethod: z.ZodOptional<z.ZodNullable<z.ZodEnum<["POST", "GET"]>>>;
179
+ note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
180
+ assignment: z.ZodOptional<z.ZodNullable<z.ZodObject<{
181
+ number: z.ZodString;
182
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
183
+ consumedAt: z.ZodString;
184
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
185
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
186
+ number: z.ZodString;
187
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
188
+ consumedAt: z.ZodString;
189
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
190
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
191
+ number: z.ZodString;
192
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
193
+ consumedAt: z.ZodString;
194
+ releasedAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
195
+ }, z.ZodTypeAny, "passthrough">>>>;
196
+ }, z.ZodTypeAny, "passthrough">>;
197
+ declare const AssignmentLinkCreateResponseSchema: z.ZodObject<{
198
+ token: z.ZodString;
199
+ url: z.ZodString;
200
+ expiresAt: z.ZodString;
201
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
202
+ token: z.ZodString;
203
+ url: z.ZodString;
204
+ expiresAt: z.ZodString;
205
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
206
+ token: z.ZodString;
207
+ url: z.ZodString;
208
+ expiresAt: z.ZodString;
209
+ }, z.ZodTypeAny, "passthrough">>;
210
+ type AssignmentLinkAssignment = z.infer<typeof AssignmentLinkAssignmentSchema>;
211
+ type AssignmentLink = z.infer<typeof AssignmentLinkSchema>;
212
+ type AssignmentLinkCreateResponse = z.infer<typeof AssignmentLinkCreateResponseSchema>;
213
+ type AssignmentLinkStatus = AssignmentLink['status'];
214
+
215
+ type RequestOptions = {
216
+ extraHeaders?: Record<string, string>;
217
+ extraQuery?: Record<string, unknown>;
218
+ timeout?: number;
219
+ };
220
+ /**
221
+ * 관리번호(External Assignment) 발급 링크 리소스.
222
+ *
223
+ * POST/DELETE는 `external_assignment` 애드온이 활성화된 계정에서만 가능합니다.
224
+ * GET 조회는 애드온 활성 여부와 무관하게 가능합니다.
225
+ */
226
+ declare class AssignmentLinks extends APIResource {
227
+ create(params?: {
228
+ webhookUrl?: string;
229
+ webhookMethod?: 'POST' | 'GET';
230
+ note?: string;
231
+ }, options?: RequestOptions): Promise<AssignmentLinkCreateResponse>;
232
+ list(params?: {
233
+ status?: AssignmentLinkStatus;
234
+ page?: number;
235
+ pageSize?: number;
236
+ }, options?: RequestOptions): Promise<Page<AssignmentLink>>;
237
+ retrieve(linkId: string, options?: RequestOptions): Promise<AssignmentLink>;
238
+ revoke(linkId: string, options?: {
239
+ extraHeaders?: Record<string, string>;
240
+ timeout?: number;
241
+ }): Promise<void>;
242
+ }
243
+
89
244
  declare const CallSchema: z.ZodObject<{
90
245
  callId: z.ZodString;
91
246
  status: z.ZodEnum<["queued", "ringing", "in-progress", "completed", "failed"]>;
@@ -93,6 +248,7 @@ declare const CallSchema: z.ZodObject<{
93
248
  from: z.ZodString;
94
249
  direction: z.ZodEnum<["outbound", "inbound"]>;
95
250
  duration: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
251
+ recordingUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
96
252
  accountId: z.ZodString;
97
253
  dateCreated: z.ZodString;
98
254
  dateUpdated: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -103,6 +259,7 @@ declare const CallSchema: z.ZodObject<{
103
259
  from: z.ZodString;
104
260
  direction: z.ZodEnum<["outbound", "inbound"]>;
105
261
  duration: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
262
+ recordingUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
106
263
  accountId: z.ZodString;
107
264
  dateCreated: z.ZodString;
108
265
  dateUpdated: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -113,6 +270,7 @@ declare const CallSchema: z.ZodObject<{
113
270
  from: z.ZodString;
114
271
  direction: z.ZodEnum<["outbound", "inbound"]>;
115
272
  duration: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
273
+ recordingUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
116
274
  accountId: z.ZodString;
117
275
  dateCreated: z.ZodString;
118
276
  dateUpdated: z.ZodOptional<z.ZodNullable<z.ZodString>>;
@@ -540,6 +698,30 @@ declare class Numbers extends APIResource {
540
698
  }): Promise<void>;
541
699
  }
542
700
 
701
+ interface RecordingDownload {
702
+ /** WAV 바이너리 데이터 (PCM 16bit mono 8kHz) */
703
+ data: ArrayBuffer;
704
+ /** 응답의 Content-Type (예: 'audio/wav') */
705
+ contentType: string;
706
+ /** Content-Disposition 헤더에서 파싱한 파일명 (없으면 null) */
707
+ filename: string | null;
708
+ }
709
+ declare class Recordings extends APIResource {
710
+ /**
711
+ * 통화 녹음(WAV)을 다운로드합니다.
712
+ *
713
+ * 콘솔과 동일한 서버측 MixMonitor 원본 (PCM 16bit mono 8kHz).
714
+ *
715
+ * @throws NotFoundError (404) — 통화가 없거나 녹음이 없음(`recordingUrl: null`).
716
+ * @throws PermissionDeniedError (403) — accountId 불일치.
717
+ */
718
+ download(callId: string, options?: {
719
+ extraHeaders?: Record<string, string>;
720
+ extraQuery?: Record<string, unknown>;
721
+ timeout?: number;
722
+ }): Promise<RecordingDownload>;
723
+ }
724
+
543
725
  declare const WebhookLogSchema: z.ZodObject<{
544
726
  id: z.ZodString;
545
727
  webhookId: z.ZodString;
@@ -603,7 +785,9 @@ declare class AccountContext {
603
785
  get calls(): Calls;
604
786
  get messages(): Messages;
605
787
  get numbers(): Numbers;
788
+ get recordings(): Recordings;
606
789
  get webhookLogs(): WebhookLogs;
790
+ get assignmentLinks(): AssignmentLinks;
607
791
  }
608
792
 
609
793
  declare class ClawOpsError extends Error {
@@ -783,7 +967,9 @@ declare class ClawOps extends APIClient {
783
967
  get calls(): Calls;
784
968
  get messages(): Messages;
785
969
  get numbers(): Numbers;
970
+ get recordings(): Recordings;
786
971
  get webhookLogs(): WebhookLogs;
972
+ get assignmentLinks(): AssignmentLinks;
787
973
  get webhooks(): Webhooks;
788
974
  accounts(accountId: string): AccountContext;
789
975
  }
@@ -813,4 +999,4 @@ interface NumberUpdateParams {
813
999
  webhookMethod?: 'POST' | 'GET';
814
1000
  }
815
1001
 
816
- export { APIClient, type APIClientOptions, APIConnectionError, APIError, APIResponseValidationError, APIStatusError, APITimeoutError, AccountContext, AgentConnectionError, AgentError, AuthenticationError, BadRequestError, type Call, type CallControlResponse, type CallCreateParams, type CallListParams, type CallUpdateParams, Calls, ClawOps, ClawOpsError, type ClawOpsOptions, ConflictError, InternalServerError, type Message, type MessageCreateParams, type MessageListParams, Messages, NotFoundError, type NumberCreateParams, type NumberListItem, type NumberUpdateParams, type NumberUpdateResponse, Numbers, Page, type PaginationMeta, PermissionDeniedError, type PhoneNumber, RateLimitError, ServiceUnavailableError, UnprocessableEntityError, VERSION, type WebhookLog, WebhookLogs, WebhookVerificationError, Webhooks, ClawOps as default };
1002
+ export { APIClient, type APIClientOptions, APIConnectionError, APIError, APIResponseValidationError, APIStatusError, APITimeoutError, AccountContext, AgentConnectionError, AgentError, type AssignmentLink, type AssignmentLinkAssignment, type AssignmentLinkCreateResponse, type AssignmentLinkStatus, AssignmentLinks, AuthenticationError, BadRequestError, type Call, type CallControlResponse, type CallCreateParams, type CallListParams, type CallUpdateParams, Calls, ClawOps, ClawOpsError, type ClawOpsOptions, ConflictError, InternalServerError, type Message, type MessageCreateParams, type MessageListParams, Messages, NotFoundError, type NumberCreateParams, type NumberListItem, type NumberUpdateParams, type NumberUpdateResponse, Numbers, Page, type PaginationMeta, PermissionDeniedError, type PhoneNumber, RateLimitError, type RecordingDownload, Recordings, ServiceUnavailableError, UnprocessableEntityError, VERSION, type WebhookLog, WebhookLogs, WebhookVerificationError, Webhooks, ClawOps as default };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, VERSION, APITimeoutError, APIConnectionError, APIResponseValidationError, makeStatusError, ClawOpsError, INITIAL_RETRY_DELAY, MAX_RETRY_DELAY } from './chunk-JTLOQURG.js';
2
- export { APIConnectionError, APIError, APIResponseValidationError, APIStatusError, APITimeoutError, AgentConnectionError, AgentError, AuthenticationError, BadRequestError, ClawOpsError, ConflictError, InternalServerError, NotFoundError, PermissionDeniedError, RateLimitError, ServiceUnavailableError, UnprocessableEntityError, VERSION } from './chunk-JTLOQURG.js';
1
+ import { DEFAULT_BASE_URL, DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, VERSION, APITimeoutError, APIConnectionError, makeStatusError, APIResponseValidationError, ClawOpsError, INITIAL_RETRY_DELAY, MAX_RETRY_DELAY } from './chunk-N5EKKQVO.js';
2
+ export { APIConnectionError, APIError, APIResponseValidationError, APIStatusError, APITimeoutError, AgentConnectionError, AgentError, AuthenticationError, BadRequestError, ClawOpsError, ConflictError, InternalServerError, NotFoundError, PermissionDeniedError, RateLimitError, ServiceUnavailableError, UnprocessableEntityError, VERSION } from './chunk-N5EKKQVO.js';
3
3
  import { z } from 'zod';
4
4
  import { timingSafeEqual, createHmac } from 'crypto';
5
5
 
@@ -44,7 +44,7 @@ var APIClient = class {
44
44
  if (extra) Object.assign(headers, extra);
45
45
  return headers;
46
46
  }
47
- async _request(method2, path, options = {}) {
47
+ async _send(method2, path, options = {}) {
48
48
  const headers = this._buildHeaders(options.extraHeaders);
49
49
  const params = new URLSearchParams();
50
50
  const queryObj = { ...options.query, ...options.extraQuery };
@@ -85,22 +85,7 @@ var APIClient = class {
85
85
  } finally {
86
86
  clearTimeout(timeoutId);
87
87
  }
88
- if (response.ok) {
89
- if (response.status === 204 || !options.castTo) {
90
- return null;
91
- }
92
- let json;
93
- try {
94
- json = await response.json();
95
- } catch {
96
- throw new APIResponseValidationError({ status: response.status }, { method: method2, url });
97
- }
98
- const parsed = options.castTo.safeParse(json);
99
- if (!parsed.success) {
100
- throw new APIResponseValidationError({ status: response.status }, { method: method2, url });
101
- }
102
- return parsed.data;
103
- }
88
+ if (response.ok) return response;
104
89
  if (retriesLeft > 0 && this._shouldRetry(response.status)) {
105
90
  retriesLeft--;
106
91
  await this._sleep(this._retryDelay(this._maxRetries - retriesLeft));
@@ -115,6 +100,22 @@ var APIClient = class {
115
100
  throw makeStatusError(response.status, body, response.headers, { method: method2, url });
116
101
  }
117
102
  }
103
+ async _request(method2, path, options = {}) {
104
+ const response = await this._send(method2, path, options);
105
+ if (response.status === 204 || !options.castTo) return null;
106
+ const url = `${this._baseURL}${path}`;
107
+ let json;
108
+ try {
109
+ json = await response.json();
110
+ } catch {
111
+ throw new APIResponseValidationError({ status: response.status }, { method: method2, url });
112
+ }
113
+ const parsed = options.castTo.safeParse(json);
114
+ if (!parsed.success) {
115
+ throw new APIResponseValidationError({ status: response.status }, { method: method2, url });
116
+ }
117
+ return parsed.data;
118
+ }
118
119
  _shouldRetry(status) {
119
120
  return status === 408 || status === 409 || status === 429 || status >= 500;
120
121
  }
@@ -137,6 +138,9 @@ var APIClient = class {
137
138
  const result = await this._request("PUT", path, options);
138
139
  return result;
139
140
  }
141
+ async _getRaw(path, options = {}) {
142
+ return this._send("GET", path, options);
143
+ }
140
144
  async _delete(path, options = {}) {
141
145
  await this._request("DELETE", path, options);
142
146
  }
@@ -233,6 +237,74 @@ var Page = class _Page {
233
237
  }
234
238
  }
235
239
  };
240
+ var AssignmentLinkAssignmentSchema = z.object({
241
+ number: z.string(),
242
+ name: z.string().nullable().optional(),
243
+ consumedAt: z.string(),
244
+ releasedAt: z.string().nullable().optional()
245
+ }).passthrough();
246
+ var AssignmentLinkSchema = z.object({
247
+ linkId: z.string(),
248
+ url: z.string(),
249
+ status: z.enum(["pending", "consumed", "expired", "revoked"]),
250
+ createdAt: z.string(),
251
+ expiresAt: z.string(),
252
+ consumedAt: z.string().nullable().optional(),
253
+ webhookUrl: z.string().nullable().optional(),
254
+ webhookMethod: z.enum(["POST", "GET"]).nullable().optional(),
255
+ note: z.string().nullable().optional(),
256
+ assignment: AssignmentLinkAssignmentSchema.nullable().optional()
257
+ }).passthrough();
258
+ var AssignmentLinkCreateResponseSchema = z.object({
259
+ token: z.string(),
260
+ url: z.string(),
261
+ expiresAt: z.string()
262
+ }).passthrough();
263
+
264
+ // src/resources/assignment-links.ts
265
+ var AssignmentLinks = class extends APIResource {
266
+ async create(params = {}, options = {}) {
267
+ const body = stripNotGiven({
268
+ webhookUrl: params.webhookUrl,
269
+ webhookMethod: params.webhookMethod,
270
+ note: params.note
271
+ });
272
+ return this._client._post(`${this._basePath}/assignment-links`, {
273
+ body: Object.keys(body).length ? body : void 0,
274
+ castTo: AssignmentLinkCreateResponseSchema,
275
+ ...options
276
+ });
277
+ }
278
+ async list(params = {}, options = {}) {
279
+ const query = stripNotGiven({
280
+ status: params.status,
281
+ page: params.page,
282
+ pageSize: params.pageSize
283
+ });
284
+ const path = `${this._basePath}/assignment-links`;
285
+ const schema = PageSchema(AssignmentLinkSchema);
286
+ const raw = await this._client._get(path, {
287
+ castTo: schema,
288
+ query: Object.keys(query).length ? query : void 0,
289
+ ...options
290
+ });
291
+ const page = new Page(raw.data, raw.meta);
292
+ page._setClient(this._client, path, AssignmentLinkSchema, query);
293
+ return page;
294
+ }
295
+ async retrieve(linkId, options = {}) {
296
+ return this._client._get(`${this._basePath}/assignment-links/${linkId}`, {
297
+ castTo: AssignmentLinkSchema,
298
+ ...options
299
+ });
300
+ }
301
+ async revoke(linkId, options = {}) {
302
+ await this._client._delete(
303
+ `${this._basePath}/assignment-links/${linkId}`,
304
+ options
305
+ );
306
+ }
307
+ };
236
308
  var CallSchema = z.object({
237
309
  callId: z.string(),
238
310
  status: z.enum(["queued", "ringing", "in-progress", "completed", "failed"]),
@@ -240,6 +312,7 @@ var CallSchema = z.object({
240
312
  from: z.string(),
241
313
  direction: z.enum(["outbound", "inbound"]),
242
314
  duration: z.number().nullable().optional(),
315
+ recordingUrl: z.string().nullable().optional(),
243
316
  accountId: z.string(),
244
317
  dateCreated: z.string(),
245
318
  dateUpdated: z.string().nullable().optional()
@@ -484,6 +557,44 @@ var Numbers = class extends APIResource {
484
557
  await this._client._delete(`${this._basePath}/numbers/${number}`, options);
485
558
  }
486
559
  };
560
+
561
+ // src/resources/recordings.ts
562
+ function parseFilename(disposition) {
563
+ if (!disposition) return null;
564
+ const star = disposition.match(/filename\*=(?:[\w-]+'[^']*')?([^;]+)/i);
565
+ if (star) {
566
+ try {
567
+ return decodeURIComponent(star[1].trim());
568
+ } catch {
569
+ }
570
+ }
571
+ const quoted = disposition.match(/filename="([^"]+)"/i);
572
+ if (quoted) return quoted[1].trim();
573
+ const bare = disposition.match(/filename=([^;]+)/i);
574
+ return bare ? bare[1].trim() : null;
575
+ }
576
+ var Recordings = class extends APIResource {
577
+ /**
578
+ * 통화 녹음(WAV)을 다운로드합니다.
579
+ *
580
+ * 콘솔과 동일한 서버측 MixMonitor 원본 (PCM 16bit mono 8kHz).
581
+ *
582
+ * @throws NotFoundError (404) — 통화가 없거나 녹음이 없음(`recordingUrl: null`).
583
+ * @throws PermissionDeniedError (403) — accountId 불일치.
584
+ */
585
+ async download(callId, options = {}) {
586
+ const response = await this._client._getRaw(
587
+ `${this._basePath}/recordings/${callId}`,
588
+ options
589
+ );
590
+ const data = await response.arrayBuffer();
591
+ return {
592
+ data,
593
+ contentType: response.headers.get("content-type") ?? "audio/wav",
594
+ filename: parseFilename(response.headers.get("content-disposition"))
595
+ };
596
+ }
597
+ };
487
598
  var WebhookLogSchema = z.object({
488
599
  id: z.string(),
489
600
  webhookId: z.string(),
@@ -534,9 +645,15 @@ var AccountContext = class {
534
645
  get numbers() {
535
646
  return new Numbers(this._client, this._accountId);
536
647
  }
648
+ get recordings() {
649
+ return new Recordings(this._client, this._accountId);
650
+ }
537
651
  get webhookLogs() {
538
652
  return new WebhookLogs(this._client, this._accountId);
539
653
  }
654
+ get assignmentLinks() {
655
+ return new AssignmentLinks(this._client, this._accountId);
656
+ }
540
657
  };
541
658
  var WebhookVerificationError = class extends ClawOpsError {
542
659
  constructor(message = "Webhook \uC11C\uBA85\uC774 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.") {
@@ -594,9 +711,15 @@ var ClawOps = class extends APIClient {
594
711
  get numbers() {
595
712
  return new Numbers(this, this._defaultAccountId);
596
713
  }
714
+ get recordings() {
715
+ return new Recordings(this, this._defaultAccountId);
716
+ }
597
717
  get webhookLogs() {
598
718
  return new WebhookLogs(this, this._defaultAccountId);
599
719
  }
720
+ get assignmentLinks() {
721
+ return new AssignmentLinks(this, this._defaultAccountId);
722
+ }
600
723
  get webhooks() {
601
724
  return new Webhooks();
602
725
  }
@@ -608,6 +731,6 @@ var ClawOps = class extends APIClient {
608
731
  // src/client-default.ts
609
732
  var client_default_default = ClawOps;
610
733
 
611
- export { APIClient, AccountContext, Calls, ClawOps, Messages, Numbers, Page, WebhookLogs, WebhookVerificationError, Webhooks, client_default_default as default };
734
+ export { APIClient, AccountContext, AssignmentLinks, Calls, ClawOps, Messages, Numbers, Page, Recordings, WebhookLogs, WebhookVerificationError, Webhooks, client_default_default as default };
612
735
  //# sourceMappingURL=index.js.map
613
736
  //# sourceMappingURL=index.js.map