@teamlearners/clawops 0.35.0 → 0.37.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/README.md +92 -4
- package/dist/agent/index.cjs +85 -416
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.d.cts +2 -2
- package/dist/agent/index.d.ts +2 -2
- package/dist/agent/index.js +6 -341
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/livekit/index.cjs +9 -8
- package/dist/agent/livekit/index.cjs.map +1 -1
- package/dist/agent/livekit/index.d.cts +1 -1
- package/dist/agent/livekit/index.d.ts +1 -1
- package/dist/agent/livekit/index.js +2 -1
- package/dist/agent/livekit/index.js.map +1 -1
- package/dist/{base-C3yzF1e0.d.cts → base-BalWsEyb.d.cts} +31 -2
- package/dist/{base-C3yzF1e0.d.ts → base-BalWsEyb.d.ts} +31 -2
- package/dist/{chunk-4YLSDMLL.js → chunk-2OGQSWTW.js} +372 -3
- package/dist/chunk-2OGQSWTW.js.map +1 -0
- package/dist/{chunk-M6BYGYJO.js → chunk-35XJNMFU.js} +3 -6
- package/dist/chunk-35XJNMFU.js.map +1 -0
- package/dist/{chunk-QD2ZY4UP.cjs → chunk-7TEOYLZI.cjs} +375 -2
- package/dist/chunk-7TEOYLZI.cjs.map +1 -0
- package/dist/chunk-CKPVV6SZ.js +6 -0
- package/dist/chunk-CKPVV6SZ.js.map +1 -0
- package/dist/chunk-EYI3ULDU.cjs +8 -0
- package/dist/chunk-EYI3ULDU.cjs.map +1 -0
- package/dist/{chunk-TVDUOKJD.cjs → chunk-IYSPOOKH.cjs} +14 -2
- package/dist/chunk-IYSPOOKH.cjs.map +1 -0
- package/dist/{chunk-NT6ZS3TQ.cjs → chunk-LLPMUDNE.cjs} +2 -6
- package/dist/chunk-LLPMUDNE.cjs.map +1 -0
- package/dist/{chunk-36JABW7P.js → chunk-VYGIWHRU.js} +14 -2
- package/dist/chunk-VYGIWHRU.js.map +1 -0
- package/dist/{client-CKaAfPlF.d.cts → client-DKsEma11.d.cts} +580 -21
- package/dist/{client-CKaAfPlF.d.ts → client-DKsEma11.d.ts} +580 -21
- package/dist/index.cjs +311 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +273 -7
- package/dist/index.js.map +1 -1
- package/dist/solapi/index.cjs +7 -7
- package/dist/solapi/index.d.cts +2 -2
- package/dist/solapi/index.d.ts +2 -2
- package/dist/solapi/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-36JABW7P.js.map +0 -1
- package/dist/chunk-4YLSDMLL.js.map +0 -1
- package/dist/chunk-M6BYGYJO.js.map +0 -1
- package/dist/chunk-NT6ZS3TQ.cjs.map +0 -1
- package/dist/chunk-QD2ZY4UP.cjs.map +0 -1
- package/dist/chunk-TVDUOKJD.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
var
|
|
5
|
+
var chunkLLPMUDNE_cjs = require('./chunk-LLPMUDNE.cjs');
|
|
6
|
+
var chunkIYSPOOKH_cjs = require('./chunk-IYSPOOKH.cjs');
|
|
7
|
+
var chunkEYI3ULDU_cjs = require('./chunk-EYI3ULDU.cjs');
|
|
7
8
|
var zod = require('zod');
|
|
8
9
|
var crypto = require('crypto');
|
|
9
10
|
|
|
@@ -14,11 +15,11 @@ function validateBaseUrl(url) {
|
|
|
14
15
|
try {
|
|
15
16
|
parsed = new URL(url);
|
|
16
17
|
} catch {
|
|
17
|
-
throw new
|
|
18
|
+
throw new chunkIYSPOOKH_cjs.ClawOpsError(`Invalid base_url: ${url}`);
|
|
18
19
|
}
|
|
19
20
|
if (parsed.protocol === "https:") return url;
|
|
20
21
|
if (parsed.protocol === "http:" && LOCALHOST_HOSTS.has(parsed.hostname)) return url;
|
|
21
|
-
throw new
|
|
22
|
+
throw new chunkIYSPOOKH_cjs.ClawOpsError(
|
|
22
23
|
`base_url\uC740 HTTPS\uB97C \uC0AC\uC6A9\uD574\uC57C \uD569\uB2C8\uB2E4 (\uBC1B\uC740 \uAC12: '${url}'). \uB85C\uCEEC \uAC1C\uBC1C \uC2DC\uC5D0\uB294 http://localhost\uB97C \uC0AC\uC6A9\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`
|
|
23
24
|
);
|
|
24
25
|
}
|
|
@@ -31,9 +32,9 @@ var APIClient = class {
|
|
|
31
32
|
_defaultHeaders;
|
|
32
33
|
constructor(options) {
|
|
33
34
|
this._apiKey = options.apiKey;
|
|
34
|
-
this._baseURL = validateBaseUrl((options.baseURL ??
|
|
35
|
-
this._maxRetries = options.maxRetries ??
|
|
36
|
-
this._timeout = options.timeout ??
|
|
35
|
+
this._baseURL = validateBaseUrl((options.baseURL ?? chunkLLPMUDNE_cjs.DEFAULT_BASE_URL).replace(/\/+$/, ""));
|
|
36
|
+
this._maxRetries = options.maxRetries ?? chunkLLPMUDNE_cjs.DEFAULT_MAX_RETRIES;
|
|
37
|
+
this._timeout = options.timeout ?? chunkLLPMUDNE_cjs.DEFAULT_TIMEOUT;
|
|
37
38
|
this._fetch = options.fetch ?? globalThis.fetch;
|
|
38
39
|
this._defaultHeaders = options.defaultHeaders ?? {};
|
|
39
40
|
}
|
|
@@ -42,7 +43,7 @@ var APIClient = class {
|
|
|
42
43
|
Authorization: `Bearer ${this._apiKey}`,
|
|
43
44
|
"Content-Type": "application/json",
|
|
44
45
|
Accept: "application/json",
|
|
45
|
-
"User-Agent": `claw-ops-node/${
|
|
46
|
+
"User-Agent": `claw-ops-node/${chunkEYI3ULDU_cjs.VERSION}`,
|
|
46
47
|
...this._defaultHeaders
|
|
47
48
|
};
|
|
48
49
|
if (extra) Object.assign(headers, extra);
|
|
@@ -78,14 +79,14 @@ var APIClient = class {
|
|
|
78
79
|
await this._sleep(this._retryDelay(this._maxRetries - retriesLeft));
|
|
79
80
|
continue;
|
|
80
81
|
}
|
|
81
|
-
throw new
|
|
82
|
+
throw new chunkIYSPOOKH_cjs.APITimeoutError({ method: method2, url });
|
|
82
83
|
}
|
|
83
84
|
if (retriesLeft > 0) {
|
|
84
85
|
retriesLeft--;
|
|
85
86
|
await this._sleep(this._retryDelay(this._maxRetries - retriesLeft));
|
|
86
87
|
continue;
|
|
87
88
|
}
|
|
88
|
-
throw new
|
|
89
|
+
throw new chunkIYSPOOKH_cjs.APIConnectionError({ method: method2, url });
|
|
89
90
|
} finally {
|
|
90
91
|
clearTimeout(timeoutId);
|
|
91
92
|
}
|
|
@@ -101,7 +102,7 @@ var APIClient = class {
|
|
|
101
102
|
} catch {
|
|
102
103
|
body = null;
|
|
103
104
|
}
|
|
104
|
-
throw
|
|
105
|
+
throw chunkIYSPOOKH_cjs.makeStatusError(response.status, body, response.headers, { method: method2, url });
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
108
|
async _request(method2, path, options = {}) {
|
|
@@ -112,11 +113,11 @@ var APIClient = class {
|
|
|
112
113
|
try {
|
|
113
114
|
json = await response.json();
|
|
114
115
|
} catch {
|
|
115
|
-
throw new
|
|
116
|
+
throw new chunkIYSPOOKH_cjs.APIResponseValidationError({ status: response.status }, { method: method2, url });
|
|
116
117
|
}
|
|
117
118
|
const parsed = options.castTo.safeParse(json);
|
|
118
119
|
if (!parsed.success) {
|
|
119
|
-
throw new
|
|
120
|
+
throw new chunkIYSPOOKH_cjs.APIResponseValidationError({ status: response.status }, { method: method2, url });
|
|
120
121
|
}
|
|
121
122
|
return parsed.data;
|
|
122
123
|
}
|
|
@@ -124,7 +125,7 @@ var APIClient = class {
|
|
|
124
125
|
return status === 408 || status === 409 || status === 429 || status >= 500;
|
|
125
126
|
}
|
|
126
127
|
_retryDelay(retriesTaken) {
|
|
127
|
-
const delay = Math.min(
|
|
128
|
+
const delay = Math.min(chunkLLPMUDNE_cjs.INITIAL_RETRY_DELAY * 2 ** retriesTaken, chunkLLPMUDNE_cjs.MAX_RETRY_DELAY);
|
|
128
129
|
return delay * (1 + Math.random());
|
|
129
130
|
}
|
|
130
131
|
_sleep(ms) {
|
|
@@ -624,10 +625,236 @@ var Calls = class extends APIResource {
|
|
|
624
625
|
});
|
|
625
626
|
}
|
|
626
627
|
};
|
|
628
|
+
var KakaoChannelSchema = zod.z.object({
|
|
629
|
+
/** ClawOps 채널 리소스 ID. 템플릿 조회와 알림톡 발송에 이 값을 쓴다. */
|
|
630
|
+
id: zod.z.string(),
|
|
631
|
+
/** 카카오 채널 검색용 ID. `@` 없는 형태로 저장된다. */
|
|
632
|
+
searchId: zod.z.string(),
|
|
633
|
+
name: zod.z.string(),
|
|
634
|
+
categoryCode: zod.z.string(),
|
|
635
|
+
/**
|
|
636
|
+
* `connected` = 연결 완료. `needs_attention` = 연결 기록은 있으나 카카오 채널 상태를
|
|
637
|
+
* 확인하지 못한 상태다 — 실제로 끊겼을 수도, 일시적인 조회 실패일 수도 있다.
|
|
638
|
+
* `channels.retrieve()` 를 다시 부르면 재확인한다.
|
|
639
|
+
*
|
|
640
|
+
* ⛔ **닫힌 enum 으로 두지 않는다.** 어휘는 서버가 소유하므로, 상태가 하나 늘면
|
|
641
|
+
* 닫힌 enum 은 조회를 통째로 실패시킨다(알림톡 `'ata'` 가 정확히 그렇게 터졌다).
|
|
642
|
+
* 열린 유니온이면 자동완성만 낡고 조회는 계속 산다.
|
|
643
|
+
*/
|
|
644
|
+
status: zod.z.string(),
|
|
645
|
+
/** 담당자 휴대전화번호(마스킹). 원문은 저장하지 않는다. */
|
|
646
|
+
managerPhoneMasked: zod.z.string().nullable().optional(),
|
|
647
|
+
connectedAt: zod.z.string(),
|
|
648
|
+
/** 카카오 채널 상태를 마지막으로 확인한 시각. null 이면 연결 이후 한 번도 확인하지 않았다. */
|
|
649
|
+
syncedAt: zod.z.string().nullable().optional(),
|
|
650
|
+
createdAt: zod.z.string(),
|
|
651
|
+
updatedAt: zod.z.string()
|
|
652
|
+
}).passthrough();
|
|
653
|
+
var KakaoTemplateSchema = zod.z.object({
|
|
654
|
+
/** ClawOps 템플릿 리소스 ID. 발송의 `kakao.templateId` 에 이 값을 쓴다. */
|
|
655
|
+
id: zod.z.string(),
|
|
656
|
+
/** ClawOps 채널 리소스 ID. 발송의 `kakao.channelId` 와 같은 값이다. */
|
|
657
|
+
channelId: zod.z.string(),
|
|
658
|
+
name: zod.z.string(),
|
|
659
|
+
/** 검수를 받은 템플릿 본문. `#{변수}` 자리는 발송 시 치환된다. */
|
|
660
|
+
content: zod.z.string(),
|
|
661
|
+
/**
|
|
662
|
+
* 카카오 검수 상태(`APPROVED`·`REJECTED` 등). **카카오 쪽 열린 집합이라 문자열이다.**
|
|
663
|
+
* 발송 가능 여부 판정은 `sendable` 이 정본이다.
|
|
664
|
+
*/
|
|
665
|
+
status: zod.z.string(),
|
|
666
|
+
/** 휴면 템플릿. `true` 면 승인 상태여도 발송할 수 없다. */
|
|
667
|
+
dormant: zod.z.boolean(),
|
|
668
|
+
/** 지금 발송에 쓸 수 있으면 true. `status === 'APPROVED' && !dormant` 다. */
|
|
669
|
+
sendable: zod.z.boolean(),
|
|
670
|
+
/** `CHANNEL`(채널 소유) 또는 `GROUP`(기본 제공). */
|
|
671
|
+
assignType: zod.z.string(),
|
|
672
|
+
messageType: zod.z.string(),
|
|
673
|
+
emphasizeType: zod.z.string(),
|
|
674
|
+
/**
|
|
675
|
+
* 발송 시 `kakao.variables` 에 모두 채워야 하는 변수 이름.
|
|
676
|
+
* 버튼 링크·강조 문구에 들어간 변수도 이 한 목록에 모인다.
|
|
677
|
+
*/
|
|
678
|
+
variables: zod.z.array(zod.z.string()),
|
|
679
|
+
createdAt: zod.z.string(),
|
|
680
|
+
updatedAt: zod.z.string()
|
|
681
|
+
}).passthrough();
|
|
682
|
+
var KakaoChannelCategorySchema = zod.z.object({
|
|
683
|
+
/** 채널 연결의 `categoryCode` 에 그대로 보내는 값. */
|
|
684
|
+
code: zod.z.string(),
|
|
685
|
+
name: zod.z.string()
|
|
686
|
+
}).passthrough();
|
|
687
|
+
var KakaoChannelCategoryListSchema = zod.z.object({
|
|
688
|
+
data: zod.z.array(KakaoChannelCategorySchema),
|
|
689
|
+
meta: zod.z.object({
|
|
690
|
+
/** 이 목록을 공급자에서 실제로 받아 온 시각. */
|
|
691
|
+
fetchedAt: zod.z.string(),
|
|
692
|
+
/** 서버 캐시에서 응답했는지. 캐시는 짧고 값이 바뀌면 자동으로 따라간다. */
|
|
693
|
+
cached: zod.z.boolean()
|
|
694
|
+
}).passthrough()
|
|
695
|
+
}).passthrough();
|
|
696
|
+
var KakaoTokenRequestSchema = zod.z.object({
|
|
697
|
+
requested: zod.z.boolean(),
|
|
698
|
+
/** 정규화된 검색용 ID. `channels.connect()` 에 이 값을 그대로 보낸다. */
|
|
699
|
+
searchId: zod.z.string(),
|
|
700
|
+
/** 인증번호가 발송된 번호(마스킹). */
|
|
701
|
+
phoneNumberMasked: zod.z.string(),
|
|
702
|
+
/** 재요청까지 기다릴 시간(초). */
|
|
703
|
+
retryAfterSeconds: zod.z.number()
|
|
704
|
+
}).passthrough();
|
|
705
|
+
|
|
706
|
+
// src/resources/kakao.ts
|
|
707
|
+
var KakaoChannels = class extends APIResource {
|
|
708
|
+
get _path() {
|
|
709
|
+
return `${this._basePath}/kakao/channels`;
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* 연결된 채널 목록.
|
|
713
|
+
*
|
|
714
|
+
* **카카오 쪽 상태를 확인하지 않는다** — 저장된 연결 정보를 그대로 돌려주므로 빠르다.
|
|
715
|
+
* 실제 채널 상태까지 확인하려면 `retrieve()` 를 쓴다.
|
|
716
|
+
*/
|
|
717
|
+
async list(params = {}, options = {}) {
|
|
718
|
+
const query = stripNotGiven({
|
|
719
|
+
status: params.status,
|
|
720
|
+
page: params.page,
|
|
721
|
+
pageSize: params.pageSize
|
|
722
|
+
});
|
|
723
|
+
const path = this._path;
|
|
724
|
+
const raw = await this._client._get(path, {
|
|
725
|
+
castTo: PageSchema(KakaoChannelSchema),
|
|
726
|
+
query: Object.keys(query).length ? query : void 0,
|
|
727
|
+
...options
|
|
728
|
+
});
|
|
729
|
+
const page = new Page(raw.data, raw.meta);
|
|
730
|
+
page._setClient(this._client, path, KakaoChannelSchema, query);
|
|
731
|
+
return page;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* 채널 하나를 조회한다. **목록과 달리 카카오 쪽 상태를 실제로 확인하고 `status` 를 갱신한다.**
|
|
735
|
+
*
|
|
736
|
+
* `connect()` 가 타임아웃됐을 때 결과를 확정하는 경로이기도 하다 — 연결을 재호출하면 중복
|
|
737
|
+
* 등록을 시도하게 되지만 이 조회는 몇 번을 불러도 안전하다.
|
|
738
|
+
*
|
|
739
|
+
* 카카오 쪽 조회에 실패해도 `404` 가 아니다. 연결 기록은 유효하므로 `status` 가
|
|
740
|
+
* `needs_attention` 으로 온다.
|
|
741
|
+
*/
|
|
742
|
+
async retrieve(channelId, options = {}) {
|
|
743
|
+
return this._client._get(`${this._path}/${channelId}`, {
|
|
744
|
+
castTo: KakaoChannelSchema,
|
|
745
|
+
...options
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* 채널 권한을 증명할 인증번호를 **담당자 휴대전화로 발송**해 달라고 요청한다. 연결의 첫 단계다.
|
|
750
|
+
*
|
|
751
|
+
* 응답에 인증번호는 없다(`202`). 받은 번호는 `connect()` 의 `token` 으로 보내며, 유효 시간이
|
|
752
|
+
* 있으므로 받은 뒤 바로 진행한다. 재요청이 잦으면 `429 KAKAO_RATE_LIMITED` 이고
|
|
753
|
+
* 응답의 `retryAfterSeconds` 만큼 기다린다.
|
|
754
|
+
*/
|
|
755
|
+
async requestToken(params, options = {}) {
|
|
756
|
+
return this._client._post(`${this._path}/token`, {
|
|
757
|
+
body: { searchId: params.searchId, phoneNumber: params.phoneNumber },
|
|
758
|
+
castTo: KakaoTokenRequestSchema,
|
|
759
|
+
...options
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* 인증번호로 채널 연결을 완료한다. **먼저 `requestToken()` 을 불러야 한다.**
|
|
764
|
+
*
|
|
765
|
+
* **멱등이다** — 이미 이 계정에 연결된 채널이면 인증번호를 소모하지 않고 기존 연결을 돌려준다.
|
|
766
|
+
* 다른 계정에 연결된 채널은 멱등이 아니라 충돌이라 `409 KAKAO_CHANNEL_ALREADY_LINKED` 다.
|
|
767
|
+
*
|
|
768
|
+
* ⚠️ **타임아웃되면 재호출하지 말 것.** 이미 연결에 성공했을 수 있어 중복 등록을 시도하게 된다.
|
|
769
|
+
* `list()` 나 `retrieve()` 로 실제 등록 여부를 확인한 뒤 결과를 확정한다.
|
|
770
|
+
*
|
|
771
|
+
* ⚠️ **실패해도 인증번호는 소모된다**(`422 KAKAO_TOKEN_INVALID`·`KAKAO_CHANNEL_REJECTED`).
|
|
772
|
+
* 원인을 해결한 뒤 `requestToken()` 부터 다시 시작해야 한다.
|
|
773
|
+
*/
|
|
774
|
+
async connect(params, options = {}) {
|
|
775
|
+
return this._client._post(this._path, {
|
|
776
|
+
body: {
|
|
777
|
+
searchId: params.searchId,
|
|
778
|
+
phoneNumber: params.phoneNumber,
|
|
779
|
+
categoryCode: params.categoryCode,
|
|
780
|
+
token: params.token
|
|
781
|
+
},
|
|
782
|
+
castTo: KakaoChannelSchema,
|
|
783
|
+
...options
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* 채널 연동을 해제한다. 카카오톡 채널 자체는 지워지지 않고 ClawOps 와의 연동만 끊긴다.
|
|
788
|
+
*
|
|
789
|
+
* ⚠️ **되돌릴 수 없고, 그 채널에 등록된 알림톡 템플릿도 함께 삭제된다.** 템플릿은 카카오
|
|
790
|
+
* 검수를 다시 받아야 하므로 복구에 시간이 걸린다 — 호출 전에 사용자 확인을 받을 것.
|
|
791
|
+
*
|
|
792
|
+
* 해제 후에는 그 채널을 다시 연결할 수 있다(본인이든 다른 계정이든). `requestToken()` 부터
|
|
793
|
+
* 다시 시작하면 된다.
|
|
794
|
+
*/
|
|
795
|
+
async disconnect(channelId, options = {}) {
|
|
796
|
+
return this._client._deleteWithResponse(`${this._path}/${channelId}`, {
|
|
797
|
+
castTo: KakaoChannelSchema,
|
|
798
|
+
...options
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
};
|
|
802
|
+
var KakaoTemplates = class extends APIResource {
|
|
803
|
+
/**
|
|
804
|
+
* 한 채널의 알림톡 템플릿 목록.
|
|
805
|
+
*
|
|
806
|
+
* 응답의 `data[].id` 를 발송의 `kakao.templateId` 로, `data[].channelId` 를
|
|
807
|
+
* `kakao.channelId` 로 쓴다. **`sendable: true` 인 템플릿만 발송할 수 있고**,
|
|
808
|
+
* `variables` 의 모든 항목을 발송 요청의 `kakao.variables` 에 채워야 한다.
|
|
809
|
+
*/
|
|
810
|
+
async list(params, options = {}) {
|
|
811
|
+
const query = stripNotGiven({
|
|
812
|
+
channelId: params.channelId,
|
|
813
|
+
page: params.page,
|
|
814
|
+
pageSize: params.pageSize
|
|
815
|
+
});
|
|
816
|
+
const path = `${this._basePath}/kakao/templates`;
|
|
817
|
+
const raw = await this._client._get(path, {
|
|
818
|
+
castTo: PageSchema(KakaoTemplateSchema),
|
|
819
|
+
query: Object.keys(query).length ? query : void 0,
|
|
820
|
+
...options
|
|
821
|
+
});
|
|
822
|
+
const page = new Page(raw.data, raw.meta);
|
|
823
|
+
page._setClient(this._client, path, KakaoTemplateSchema, query);
|
|
824
|
+
return page;
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
var Kakao = class extends APIResource {
|
|
828
|
+
get channels() {
|
|
829
|
+
return new KakaoChannels(this._client, this._accountId);
|
|
830
|
+
}
|
|
831
|
+
get templates() {
|
|
832
|
+
return new KakaoTemplates(this._client, this._accountId);
|
|
833
|
+
}
|
|
834
|
+
/**
|
|
835
|
+
* 채널 연결 시 지정할 업종 카테고리 목록.
|
|
836
|
+
*
|
|
837
|
+
* **값을 코드에 하드코딩하지 말 것** — 카카오/공급자 쪽에서 늘거나 바뀌는 열린 집합이고
|
|
838
|
+
* 이 응답이 그때그때의 정본이다. 응답의 `code` 를 `channels.connect()` 의 `categoryCode`
|
|
839
|
+
* 로 그대로 보낸다.
|
|
840
|
+
*
|
|
841
|
+
* 페이지네이션이 없어 `Page` 가 아니라 `{ data, meta }` 를 그대로 돌려준다.
|
|
842
|
+
*/
|
|
843
|
+
async channelCategories(options = {}) {
|
|
844
|
+
return this._client._get(`${this._basePath}/kakao/channel-categories`, {
|
|
845
|
+
castTo: KakaoChannelCategoryListSchema,
|
|
846
|
+
...options
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
};
|
|
627
850
|
var MessageSchema = zod.z.object({
|
|
628
851
|
messageId: zod.z.string(),
|
|
629
852
|
status: zod.z.enum(["queued", "sending", "sent", "failed", "received"]),
|
|
630
|
-
|
|
853
|
+
/**
|
|
854
|
+
* `'ata'` 는 카카오 알림톡이다. `body` 에는 템플릿에 변수를 치환한 결과가 담기고,
|
|
855
|
+
* 버튼·아이템 리스트·강조 문구는 템플릿에 검수된 대로 발송되어 이 값에는 담기지 않는다.
|
|
856
|
+
*/
|
|
857
|
+
type: zod.z.enum(["sms", "lms", "mms", "rcs", "ata"]),
|
|
631
858
|
to: zod.z.string(),
|
|
632
859
|
from: zod.z.string(),
|
|
633
860
|
body: zod.z.string().nullable().optional(),
|
|
@@ -642,6 +869,25 @@ var MessageSchema = zod.z.object({
|
|
|
642
869
|
|
|
643
870
|
// src/resources/messages.ts
|
|
644
871
|
var Messages = class extends APIResource {
|
|
872
|
+
/**
|
|
873
|
+
* 문자(SMS/LMS/MMS) 또는 카카오 알림톡을 발송합니다.
|
|
874
|
+
*
|
|
875
|
+
* 둘은 배타적입니다 — `kakao` 를 실으면 알림톡이고, 이때 `body`·`subject`·`mediaUrl` 은
|
|
876
|
+
* 실을 수 없습니다(본문은 검수된 템플릿이 정합니다).
|
|
877
|
+
*
|
|
878
|
+
* ```ts
|
|
879
|
+
* // 문자
|
|
880
|
+
* await client.messages.create({ to: '010…', from: '070…', body: '안녕하세요' });
|
|
881
|
+
*
|
|
882
|
+
* // 알림톡 — 실패하면 fallback 문구가 문자로 대신 나갑니다(별도 1건으로 과금)
|
|
883
|
+
* await client.messages.create({
|
|
884
|
+
* to: '010…',
|
|
885
|
+
* from: '070…',
|
|
886
|
+
* kakao: { channelId, templateId, variables: { 고객명: '홍길동' } },
|
|
887
|
+
* fallback: { body: '주문이 접수되었습니다.' },
|
|
888
|
+
* });
|
|
889
|
+
* ```
|
|
890
|
+
*/
|
|
645
891
|
async create(params, options = {}) {
|
|
646
892
|
const body = stripNotGiven({
|
|
647
893
|
To: params.to,
|
|
@@ -650,7 +896,19 @@ var Messages = class extends APIResource {
|
|
|
650
896
|
Type: params.type,
|
|
651
897
|
Subject: params.subject,
|
|
652
898
|
MediaUrl: params.mediaUrl,
|
|
653
|
-
IdempotencyKey: params.idempotencyKey
|
|
899
|
+
IdempotencyKey: params.idempotencyKey,
|
|
900
|
+
// 중첩 객체는 손으로 조립한다 — stripNotGiven 은 한 겹만 훑는다.
|
|
901
|
+
Kakao: params.kakao && stripNotGiven({
|
|
902
|
+
ChannelId: params.kakao.channelId,
|
|
903
|
+
TemplateId: params.kakao.templateId,
|
|
904
|
+
Variables: params.kakao.variables
|
|
905
|
+
}),
|
|
906
|
+
Fallback: params.fallback && stripNotGiven({
|
|
907
|
+
Type: params.fallback.type,
|
|
908
|
+
Subject: params.fallback.subject,
|
|
909
|
+
Body: params.fallback.body,
|
|
910
|
+
Disabled: params.fallback.disabled
|
|
911
|
+
})
|
|
654
912
|
});
|
|
655
913
|
return this._client._post(`${this._basePath}/messages`, {
|
|
656
914
|
body,
|
|
@@ -662,6 +920,7 @@ var Messages = class extends APIResource {
|
|
|
662
920
|
const query = stripNotGiven({
|
|
663
921
|
type: params.type,
|
|
664
922
|
status: params.status,
|
|
923
|
+
number: params.number,
|
|
665
924
|
page: params.page,
|
|
666
925
|
pageSize: params.pageSize
|
|
667
926
|
});
|
|
@@ -958,8 +1217,11 @@ var AccountContext = class {
|
|
|
958
1217
|
get blockedRecipients() {
|
|
959
1218
|
return new BlockedRecipients(this._client, this._accountId);
|
|
960
1219
|
}
|
|
1220
|
+
get kakao() {
|
|
1221
|
+
return new Kakao(this._client, this._accountId);
|
|
1222
|
+
}
|
|
961
1223
|
};
|
|
962
|
-
var WebhookVerificationError = class extends
|
|
1224
|
+
var WebhookVerificationError = class extends chunkIYSPOOKH_cjs.ClawOpsError {
|
|
963
1225
|
constructor(message = "Webhook \uC11C\uBA85\uC774 \uC77C\uCE58\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.") {
|
|
964
1226
|
super(message);
|
|
965
1227
|
this.name = "WebhookVerificationError";
|
|
@@ -989,13 +1251,13 @@ var ClawOps = class extends APIClient {
|
|
|
989
1251
|
constructor(options = {}) {
|
|
990
1252
|
let apiKey = options.apiKey ?? process.env.CLAWOPS_API_KEY;
|
|
991
1253
|
if (!apiKey) {
|
|
992
|
-
throw new
|
|
1254
|
+
throw new chunkIYSPOOKH_cjs.ClawOpsError("apiKey\uB97C \uC9C0\uC815\uD558\uAC70\uB098 CLAWOPS_API_KEY \uD658\uACBD\uBCC0\uC218\uB97C \uC124\uC815\uD558\uC138\uC694.");
|
|
993
1255
|
}
|
|
994
1256
|
let accountId = options.accountId ?? process.env.CLAWOPS_ACCOUNT_ID;
|
|
995
1257
|
if (!accountId) {
|
|
996
|
-
throw new
|
|
1258
|
+
throw new chunkIYSPOOKH_cjs.ClawOpsError("accountId\uB97C \uC9C0\uC815\uD558\uAC70\uB098 CLAWOPS_ACCOUNT_ID \uD658\uACBD\uBCC0\uC218\uB97C \uC124\uC815\uD558\uC138\uC694.");
|
|
997
1259
|
}
|
|
998
|
-
const baseURL = options.baseURL ?? process.env.CLAWOPS_BASE_URL ??
|
|
1260
|
+
const baseURL = options.baseURL ?? process.env.CLAWOPS_BASE_URL ?? chunkLLPMUDNE_cjs.DEFAULT_BASE_URL;
|
|
999
1261
|
super({
|
|
1000
1262
|
apiKey,
|
|
1001
1263
|
baseURL,
|
|
@@ -1033,6 +1295,10 @@ var ClawOps = class extends APIClient {
|
|
|
1033
1295
|
get blockedRecipients() {
|
|
1034
1296
|
return new BlockedRecipients(this, this._defaultAccountId);
|
|
1035
1297
|
}
|
|
1298
|
+
/** 카카오 채널·알림톡 템플릿. 발송은 `messages.create({ kakao: … })` 다. */
|
|
1299
|
+
get kakao() {
|
|
1300
|
+
return new Kakao(this, this._defaultAccountId);
|
|
1301
|
+
}
|
|
1036
1302
|
get webhooks() {
|
|
1037
1303
|
return new Webhooks();
|
|
1038
1304
|
}
|
|
@@ -1044,81 +1310,81 @@ var ClawOps = class extends APIClient {
|
|
|
1044
1310
|
// src/client-default.ts
|
|
1045
1311
|
var client_default_default = ClawOps;
|
|
1046
1312
|
|
|
1047
|
-
Object.defineProperty(exports, "VERSION", {
|
|
1048
|
-
enumerable: true,
|
|
1049
|
-
get: function () { return chunkNT6ZS3TQ_cjs.VERSION; }
|
|
1050
|
-
});
|
|
1051
1313
|
Object.defineProperty(exports, "APIConnectionError", {
|
|
1052
1314
|
enumerable: true,
|
|
1053
|
-
get: function () { return
|
|
1315
|
+
get: function () { return chunkIYSPOOKH_cjs.APIConnectionError; }
|
|
1054
1316
|
});
|
|
1055
1317
|
Object.defineProperty(exports, "APIError", {
|
|
1056
1318
|
enumerable: true,
|
|
1057
|
-
get: function () { return
|
|
1319
|
+
get: function () { return chunkIYSPOOKH_cjs.APIError; }
|
|
1058
1320
|
});
|
|
1059
1321
|
Object.defineProperty(exports, "APIResponseValidationError", {
|
|
1060
1322
|
enumerable: true,
|
|
1061
|
-
get: function () { return
|
|
1323
|
+
get: function () { return chunkIYSPOOKH_cjs.APIResponseValidationError; }
|
|
1062
1324
|
});
|
|
1063
1325
|
Object.defineProperty(exports, "APIStatusError", {
|
|
1064
1326
|
enumerable: true,
|
|
1065
|
-
get: function () { return
|
|
1327
|
+
get: function () { return chunkIYSPOOKH_cjs.APIStatusError; }
|
|
1066
1328
|
});
|
|
1067
1329
|
Object.defineProperty(exports, "APITimeoutError", {
|
|
1068
1330
|
enumerable: true,
|
|
1069
|
-
get: function () { return
|
|
1331
|
+
get: function () { return chunkIYSPOOKH_cjs.APITimeoutError; }
|
|
1070
1332
|
});
|
|
1071
1333
|
Object.defineProperty(exports, "AgentConnectionError", {
|
|
1072
1334
|
enumerable: true,
|
|
1073
|
-
get: function () { return
|
|
1335
|
+
get: function () { return chunkIYSPOOKH_cjs.AgentConnectionError; }
|
|
1074
1336
|
});
|
|
1075
1337
|
Object.defineProperty(exports, "AgentError", {
|
|
1076
1338
|
enumerable: true,
|
|
1077
|
-
get: function () { return
|
|
1339
|
+
get: function () { return chunkIYSPOOKH_cjs.AgentError; }
|
|
1078
1340
|
});
|
|
1079
1341
|
Object.defineProperty(exports, "AuthenticationError", {
|
|
1080
1342
|
enumerable: true,
|
|
1081
|
-
get: function () { return
|
|
1343
|
+
get: function () { return chunkIYSPOOKH_cjs.AuthenticationError; }
|
|
1082
1344
|
});
|
|
1083
1345
|
Object.defineProperty(exports, "BadRequestError", {
|
|
1084
1346
|
enumerable: true,
|
|
1085
|
-
get: function () { return
|
|
1347
|
+
get: function () { return chunkIYSPOOKH_cjs.BadRequestError; }
|
|
1086
1348
|
});
|
|
1087
1349
|
Object.defineProperty(exports, "ClawOpsError", {
|
|
1088
1350
|
enumerable: true,
|
|
1089
|
-
get: function () { return
|
|
1351
|
+
get: function () { return chunkIYSPOOKH_cjs.ClawOpsError; }
|
|
1090
1352
|
});
|
|
1091
1353
|
Object.defineProperty(exports, "ConflictError", {
|
|
1092
1354
|
enumerable: true,
|
|
1093
|
-
get: function () { return
|
|
1355
|
+
get: function () { return chunkIYSPOOKH_cjs.ConflictError; }
|
|
1094
1356
|
});
|
|
1095
1357
|
Object.defineProperty(exports, "InternalServerError", {
|
|
1096
1358
|
enumerable: true,
|
|
1097
|
-
get: function () { return
|
|
1359
|
+
get: function () { return chunkIYSPOOKH_cjs.InternalServerError; }
|
|
1098
1360
|
});
|
|
1099
1361
|
Object.defineProperty(exports, "NotFoundError", {
|
|
1100
1362
|
enumerable: true,
|
|
1101
|
-
get: function () { return
|
|
1363
|
+
get: function () { return chunkIYSPOOKH_cjs.NotFoundError; }
|
|
1102
1364
|
});
|
|
1103
1365
|
Object.defineProperty(exports, "PermissionDeniedError", {
|
|
1104
1366
|
enumerable: true,
|
|
1105
|
-
get: function () { return
|
|
1367
|
+
get: function () { return chunkIYSPOOKH_cjs.PermissionDeniedError; }
|
|
1106
1368
|
});
|
|
1107
1369
|
Object.defineProperty(exports, "RateLimitError", {
|
|
1108
1370
|
enumerable: true,
|
|
1109
|
-
get: function () { return
|
|
1371
|
+
get: function () { return chunkIYSPOOKH_cjs.RateLimitError; }
|
|
1110
1372
|
});
|
|
1111
1373
|
Object.defineProperty(exports, "ServiceUnavailableError", {
|
|
1112
1374
|
enumerable: true,
|
|
1113
|
-
get: function () { return
|
|
1375
|
+
get: function () { return chunkIYSPOOKH_cjs.ServiceUnavailableError; }
|
|
1114
1376
|
});
|
|
1115
1377
|
Object.defineProperty(exports, "SolapiBridgeError", {
|
|
1116
1378
|
enumerable: true,
|
|
1117
|
-
get: function () { return
|
|
1379
|
+
get: function () { return chunkIYSPOOKH_cjs.SolapiBridgeError; }
|
|
1118
1380
|
});
|
|
1119
1381
|
Object.defineProperty(exports, "UnprocessableEntityError", {
|
|
1120
1382
|
enumerable: true,
|
|
1121
|
-
get: function () { return
|
|
1383
|
+
get: function () { return chunkIYSPOOKH_cjs.UnprocessableEntityError; }
|
|
1384
|
+
});
|
|
1385
|
+
Object.defineProperty(exports, "VERSION", {
|
|
1386
|
+
enumerable: true,
|
|
1387
|
+
get: function () { return chunkEYI3ULDU_cjs.VERSION; }
|
|
1122
1388
|
});
|
|
1123
1389
|
exports.APIClient = APIClient;
|
|
1124
1390
|
exports.AccountContext = AccountContext;
|
|
@@ -1126,6 +1392,9 @@ exports.AssignmentLinks = AssignmentLinks;
|
|
|
1126
1392
|
exports.BlockedRecipients = BlockedRecipients;
|
|
1127
1393
|
exports.Calls = Calls;
|
|
1128
1394
|
exports.ClawOps = ClawOps;
|
|
1395
|
+
exports.Kakao = Kakao;
|
|
1396
|
+
exports.KakaoChannels = KakaoChannels;
|
|
1397
|
+
exports.KakaoTemplates = KakaoTemplates;
|
|
1129
1398
|
exports.Messages = Messages;
|
|
1130
1399
|
exports.Numbers = Numbers;
|
|
1131
1400
|
exports.Page = Page;
|