@wabery/cli 0.15.2 → 0.17.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 +2 -0
- package/dist/api-client.d.ts +1 -1
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +5 -4
- package/dist/api-client.js.map +1 -1
- package/dist/cli.js +174 -9
- package/dist/cli.js.map +1 -1
- package/dist/config-example.d.ts +1 -1
- package/dist/config-example.d.ts.map +1 -1
- package/dist/local-config.js.map +1 -1
- package/dist/mcp-server.d.ts +8 -0
- package/dist/mcp-server.d.ts.map +1 -1
- package/dist/mcp-server.js +425 -19
- package/dist/mcp-server.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
package/dist/api-client.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export declare class WaberyApiClient {
|
|
|
30
30
|
postForm(path: string, body: FormData): Promise<unknown>;
|
|
31
31
|
put(path: string, body?: unknown): Promise<unknown>;
|
|
32
32
|
patch(path: string, body?: unknown): Promise<unknown>;
|
|
33
|
-
delete(path: string): Promise<unknown>;
|
|
33
|
+
delete(path: string, body?: unknown): Promise<unknown>;
|
|
34
34
|
private request;
|
|
35
35
|
}
|
|
36
36
|
//# sourceMappingURL=api-client.d.ts.map
|
package/dist/api-client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC7C,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,cAAe,SAAQ,KAAK;aAGvB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,OAAO;
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,mBAAmB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,iBAAiB,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;IAC7C,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mFAAmF;IACnF,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,qBAAa,cAAe,SAAQ,KAAK;aAGvB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,OAAO;IAH9B,YACC,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,EAG7B;CACD;AAED,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAA2B;IAC9D,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAS;IAChD,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B,YAAY,OAAO,GAAE,mBAAwB,EAgB5C;IAEK,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC,oBAE1E;IAEK,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM,oBAE/D;IAEK,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,oBAE1C;IAEK,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,oBAErC;IAEK,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,oBAEvC;IAEK,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,oBAExC;YAEa,OAAO;CAyGrB"}
|
package/dist/api-client.js
CHANGED
|
@@ -46,8 +46,8 @@ export class WaberyApiClient {
|
|
|
46
46
|
async patch(path, body) {
|
|
47
47
|
return this.request("PATCH", path, body);
|
|
48
48
|
}
|
|
49
|
-
async delete(path) {
|
|
50
|
-
return this.request("DELETE", path);
|
|
49
|
+
async delete(path, body) {
|
|
50
|
+
return this.request("DELETE", path, body);
|
|
51
51
|
}
|
|
52
52
|
async request(method, path, body, query, idempotencyKey) {
|
|
53
53
|
const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`);
|
|
@@ -77,9 +77,10 @@ export class WaberyApiClient {
|
|
|
77
77
|
const projectId = this.projectIdProvider?.() ?? this.projectId;
|
|
78
78
|
if (projectId)
|
|
79
79
|
headers["x-wabery-project-id"] = projectId;
|
|
80
|
+
if (idempotencyKey)
|
|
81
|
+
headers["idempotency-key"] = idempotencyKey;
|
|
80
82
|
if (method === "POST" && path.startsWith("/broadcasts")) {
|
|
81
|
-
headers["idempotency-key"]
|
|
82
|
-
idempotencyKey ?? globalThis.crypto.randomUUID();
|
|
83
|
+
headers["idempotency-key"] ??= globalThis.crypto.randomUUID();
|
|
83
84
|
}
|
|
84
85
|
if (body !== undefined && !(body instanceof FormData)) {
|
|
85
86
|
headers["content-type"] = "application/json";
|
package/dist/api-client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAgBtD,MAAM,OAAO,cAAe,SAAQ,KAAK;IAGvB;
|
|
1
|
+
{"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -121,6 +121,10 @@ async function main() {
|
|
|
121
121
|
await handleConversations(client, subcommand, rest, parsed.flags);
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
|
+
if (command === "groups") {
|
|
125
|
+
await handleGroups(client, subcommand, rest, parsed.flags);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
124
128
|
if (command === "messages") {
|
|
125
129
|
await handleMessages(client, subcommand, rest, parsed.flags);
|
|
126
130
|
return;
|
|
@@ -646,6 +650,10 @@ async function handleProjects(client, subcommand, rest, flags) {
|
|
|
646
650
|
const requireOptIn = booleanFlag(flags, "require-opt-in");
|
|
647
651
|
if (requireOptIn !== undefined)
|
|
648
652
|
body.require_opt_in = requireOptIn;
|
|
653
|
+
const groupWebhookEvents = booleanFlag(flags, "group-webhook-events-enabled");
|
|
654
|
+
if (groupWebhookEvents !== undefined) {
|
|
655
|
+
body.group_webhook_events_enabled = groupWebhookEvents;
|
|
656
|
+
}
|
|
649
657
|
const webhookUrl = stringFlag(flags, "webhook-url");
|
|
650
658
|
if (webhookUrl !== undefined)
|
|
651
659
|
body.webhook_url = webhookUrl;
|
|
@@ -663,7 +671,7 @@ async function handleProjects(client, subcommand, rest, flags) {
|
|
|
663
671
|
await printJson(await client.post(`/projects/${requiredValue(projectId, "project-id")}/rotate-webhook-secret`, secret ? { webhook_secret: secret } : undefined));
|
|
664
672
|
return;
|
|
665
673
|
}
|
|
666
|
-
throw new Error("Usage: wabery projects list|get|ensure|update|rotate-secret [<project_id>] [--name --description --routing-mode --require-opt-in --webhook-url --webhook-signing-enabled --webhook-secret]");
|
|
674
|
+
throw new Error("Usage: wabery projects list|get|ensure|update|rotate-secret [<project_id>] [--name --description --routing-mode --require-opt-in --group-webhook-events-enabled --webhook-url --webhook-signing-enabled --webhook-secret]");
|
|
667
675
|
}
|
|
668
676
|
async function handleRegistrationIntents(client, subcommand, rest, flags) {
|
|
669
677
|
if (subcommand === "create") {
|
|
@@ -775,7 +783,10 @@ async function handleInit(client, flags) {
|
|
|
775
783
|
}
|
|
776
784
|
const WEBHOOK_HANDLER_STUB = `// Verify and handle Wabery webhook deliveries.
|
|
777
785
|
// npm i @wabery/sdk
|
|
778
|
-
import {
|
|
786
|
+
import {
|
|
787
|
+
\tgetMessageReceivedItemDisposition,
|
|
788
|
+
\tWabery,
|
|
789
|
+
} from "@wabery/sdk";
|
|
779
790
|
|
|
780
791
|
const wabery = new Wabery(); // reads WABERY_API_KEY
|
|
781
792
|
const secret = process.env.WABERY_WEBHOOK_SECRET ?? "";
|
|
@@ -784,9 +795,19 @@ const secret = process.env.WABERY_WEBHOOK_SECRET ?? "";
|
|
|
784
795
|
export async function handleWaberyWebhook(rawBody: string, signature: string) {
|
|
785
796
|
\tconst event = wabery.webhooks.constructEvent(rawBody, signature, secret);
|
|
786
797
|
\tswitch (event.event) {
|
|
787
|
-
\t\tcase "message.received":
|
|
798
|
+
\t\tcase "message.received": {
|
|
799
|
+
\t\t\tconst latestMessage = event.payload.messages?.at(-1);
|
|
800
|
+
\t\t\tif (
|
|
801
|
+
\t\t\t\tlatestMessage &&
|
|
802
|
+
\t\t\t\tgetMessageReceivedItemDisposition(latestMessage).kind === "mutation"
|
|
803
|
+
\t\t\t) {
|
|
804
|
+
\t\t\t\t// Revoke/edit events are mutations, including nested mutations under
|
|
805
|
+
\t\t\t\t// outer type "unsupported". Record them, but do not reply.
|
|
806
|
+
\t\t\t\tbreak;
|
|
807
|
+
\t\t\t}
|
|
788
808
|
\t\t\t// event.payload.text, .from, .conversation_id ...
|
|
789
809
|
\t\t\tbreak;
|
|
810
|
+
\t\t}
|
|
790
811
|
\t\tcase "flow.completed":
|
|
791
812
|
\t\t\t// event.payload.submission ...
|
|
792
813
|
\t\t\tbreak;
|
|
@@ -939,6 +960,7 @@ async function handleConversations(client, subcommand, rest, flags) {
|
|
|
939
960
|
await printJson(await client.get("/conversations", {
|
|
940
961
|
contact_id: stringFlag(flags, "contact-id"),
|
|
941
962
|
active: stringFlag(flags, "active"),
|
|
963
|
+
recipient_type: stringFlag(flags, "recipient-type"),
|
|
942
964
|
limit: numberFlag(flags, "limit"),
|
|
943
965
|
starting_after: stringFlag(flags, "starting-after"),
|
|
944
966
|
}));
|
|
@@ -946,7 +968,7 @@ async function handleConversations(client, subcommand, rest, flags) {
|
|
|
946
968
|
}
|
|
947
969
|
const conversationId = rest[0] ?? stringFlag(flags, "conversation-id");
|
|
948
970
|
if (subcommand === "get") {
|
|
949
|
-
await printJson(await client.get(`/conversations/${requiredValue(conversationId, "conversation-id")}
|
|
971
|
+
await printJson(await client.get(`/conversations/${requiredValue(conversationId, "conversation-id")}`, { recipient_type: stringFlag(flags, "recipient-type") }));
|
|
950
972
|
return;
|
|
951
973
|
}
|
|
952
974
|
if (subcommand === "messages") {
|
|
@@ -954,10 +976,127 @@ async function handleConversations(client, subcommand, rest, flags) {
|
|
|
954
976
|
limit: numberFlag(flags, "limit"),
|
|
955
977
|
starting_after: stringFlag(flags, "starting-after"),
|
|
956
978
|
order: stringFlag(flags, "order"),
|
|
979
|
+
recipient_type: stringFlag(flags, "recipient-type"),
|
|
957
980
|
}));
|
|
958
981
|
return;
|
|
959
982
|
}
|
|
960
|
-
throw new Error("Usage: wabery conversations list|get|messages <conversation_id>");
|
|
983
|
+
throw new Error("Usage: wabery conversations list|get|messages <conversation_id> [--recipient-type individual|group|all]");
|
|
984
|
+
}
|
|
985
|
+
async function handleGroups(client, subcommand, rest, flags) {
|
|
986
|
+
const channelId = stringFlag(flags, "channel-id");
|
|
987
|
+
const groupPath = (groupId) => {
|
|
988
|
+
const base = `/channels/${encodeURIComponent(requiredValue(channelId, "channel-id"))}/whatsapp-groups`;
|
|
989
|
+
return groupId === undefined
|
|
990
|
+
? base
|
|
991
|
+
: `${base}/${encodeURIComponent(groupId)}`;
|
|
992
|
+
};
|
|
993
|
+
if (subcommand === "list" || subcommand === undefined) {
|
|
994
|
+
await printJson(await client.get(groupPath(), {
|
|
995
|
+
limit: numberFlag(flags, "limit"),
|
|
996
|
+
starting_after: stringFlag(flags, "starting-after"),
|
|
997
|
+
ending_before: stringFlag(flags, "ending-before"),
|
|
998
|
+
after: stringFlag(flags, "after"),
|
|
999
|
+
before: stringFlag(flags, "before"),
|
|
1000
|
+
}));
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
if (subcommand === "get") {
|
|
1004
|
+
await printJson(await client.get(groupPath(requiredValue(rest[0] ?? stringFlag(flags, "group-id"), "group-id"))));
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1007
|
+
if (subcommand === "create") {
|
|
1008
|
+
const idempotencyKey = requiredStringFlag(flags, "idempotency-key");
|
|
1009
|
+
const body = optionalJsonFlag(flags, "body") ??
|
|
1010
|
+
{
|
|
1011
|
+
subject: requiredStringFlag(flags, "subject"),
|
|
1012
|
+
description: stringFlag(flags, "description"),
|
|
1013
|
+
join_approval_mode: stringFlag(flags, "join-approval-mode"),
|
|
1014
|
+
};
|
|
1015
|
+
await printJson(await client.post(groupPath(), body, idempotencyKey));
|
|
1016
|
+
return;
|
|
1017
|
+
}
|
|
1018
|
+
const groupId = requiredValue(rest[0] ?? stringFlag(flags, "group-id"), "group-id");
|
|
1019
|
+
if (subcommand === "delete") {
|
|
1020
|
+
await printJson(await client.delete(groupPath(groupId)));
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
if (subcommand === "settings") {
|
|
1024
|
+
const profilePicturePath = stringFlag(flags, "profile-picture");
|
|
1025
|
+
if (profilePicturePath) {
|
|
1026
|
+
const picture = readFileSync(profilePicturePath);
|
|
1027
|
+
if (picture.length < 3 ||
|
|
1028
|
+
picture[0] !== 0xff ||
|
|
1029
|
+
picture[1] !== 0xd8 ||
|
|
1030
|
+
picture[2] !== 0xff) {
|
|
1031
|
+
throw new Error("--profile-picture must point to a JPEG file");
|
|
1032
|
+
}
|
|
1033
|
+
const form = new FormData();
|
|
1034
|
+
form.set("profile_picture_file", new Blob([picture], { type: "image/jpeg" }), profilePicturePath.split(/[\\/]/).at(-1) ?? "profile.jpg");
|
|
1035
|
+
const subject = stringFlag(flags, "subject");
|
|
1036
|
+
const description = stringFlag(flags, "description");
|
|
1037
|
+
if (subject !== undefined)
|
|
1038
|
+
form.set("subject", subject);
|
|
1039
|
+
if (description !== undefined)
|
|
1040
|
+
form.set("description", description);
|
|
1041
|
+
await printJson(await client.postForm(groupPath(groupId), form));
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
const body = optionalJsonFlag(flags, "body") ??
|
|
1045
|
+
{
|
|
1046
|
+
subject: stringFlag(flags, "subject"),
|
|
1047
|
+
description: stringFlag(flags, "description"),
|
|
1048
|
+
};
|
|
1049
|
+
await printJson(await client.post(groupPath(groupId), body));
|
|
1050
|
+
return;
|
|
1051
|
+
}
|
|
1052
|
+
if (subcommand === "invite-link") {
|
|
1053
|
+
const path = `${groupPath(groupId)}/invite-link`;
|
|
1054
|
+
if (rest[1] === "reset" || booleanFlag(flags, "reset")) {
|
|
1055
|
+
await printJson(await client.post(path));
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
await printJson(await client.get(path));
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
if (subcommand === "join-requests") {
|
|
1062
|
+
const action = rest[1] ?? stringFlag(flags, "action");
|
|
1063
|
+
const path = `${groupPath(groupId)}/join-requests`;
|
|
1064
|
+
if (!action || action === "list") {
|
|
1065
|
+
await printJson(await client.get(path, {
|
|
1066
|
+
limit: numberFlag(flags, "limit"),
|
|
1067
|
+
starting_after: stringFlag(flags, "starting-after"),
|
|
1068
|
+
ending_before: stringFlag(flags, "ending-before"),
|
|
1069
|
+
after: stringFlag(flags, "after"),
|
|
1070
|
+
before: stringFlag(flags, "before"),
|
|
1071
|
+
}));
|
|
1072
|
+
return;
|
|
1073
|
+
}
|
|
1074
|
+
if (action === "approve" || action === "reject") {
|
|
1075
|
+
const ids = stringFlag(flags, "join-request-ids")
|
|
1076
|
+
?.split(",")
|
|
1077
|
+
.map((id) => id.trim())
|
|
1078
|
+
.filter(Boolean);
|
|
1079
|
+
const body = optionalJsonFlag(flags, "body") ??
|
|
1080
|
+
{ join_requests: ids ?? [] };
|
|
1081
|
+
await printJson(action === "approve"
|
|
1082
|
+
? await client.post(path, body)
|
|
1083
|
+
: await client.delete(path, body));
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
if (subcommand === "remove-participants") {
|
|
1088
|
+
const body = optionalJsonFlag(flags, "body") ??
|
|
1089
|
+
{
|
|
1090
|
+
participants: (stringFlag(flags, "users") ?? "")
|
|
1091
|
+
.split(",")
|
|
1092
|
+
.map((user) => user.trim())
|
|
1093
|
+
.filter(Boolean)
|
|
1094
|
+
.map((user) => user),
|
|
1095
|
+
};
|
|
1096
|
+
await printJson(await client.delete(`${groupPath(groupId)}/participants`, body));
|
|
1097
|
+
return;
|
|
1098
|
+
}
|
|
1099
|
+
throw new Error("Usage: wabery groups list|get|create|delete|settings|invite-link|join-requests|remove-participants");
|
|
961
1100
|
}
|
|
962
1101
|
async function handleMessages(client, subcommand, rest, flags) {
|
|
963
1102
|
if (subcommand === "get") {
|
|
@@ -971,6 +1110,7 @@ async function handleMessages(client, subcommand, rest, flags) {
|
|
|
971
1110
|
channel_id: requiredStringFlag(flags, "channel-id"),
|
|
972
1111
|
conversation_id: stringFlag(flags, "conversation-id"),
|
|
973
1112
|
to: stringFlag(flags, "to"),
|
|
1113
|
+
group_id: stringFlag(flags, "group-id"),
|
|
974
1114
|
text: stringFlag(flags, "text"),
|
|
975
1115
|
template: optionalJsonFlag(flags, "template"),
|
|
976
1116
|
media: optionalJsonFlag(flags, "media"),
|
|
@@ -1000,7 +1140,20 @@ async function handleMessages(client, subcommand, rest, flags) {
|
|
|
1000
1140
|
: undefined,
|
|
1001
1141
|
idempotency_key: stringFlag(flags, "idempotency-key"),
|
|
1002
1142
|
};
|
|
1003
|
-
|
|
1143
|
+
if (isRecord(body) &&
|
|
1144
|
+
typeof body.group_id === "string" &&
|
|
1145
|
+
["interactive", "reaction", "location", "contacts"].some((key) => body[key] !== undefined)) {
|
|
1146
|
+
throw new Error("Group sends support only text, media including sticker, text/media templates, and pin or unpin.");
|
|
1147
|
+
}
|
|
1148
|
+
const groupIdempotencyKey = isRecord(body) && typeof body.group_id === "string"
|
|
1149
|
+
? typeof body.idempotency_key === "string" && body.idempotency_key
|
|
1150
|
+
? body.idempotency_key
|
|
1151
|
+
: requiredStringFlag(flags, "idempotency-key")
|
|
1152
|
+
: undefined;
|
|
1153
|
+
const requestBody = groupIdempotencyKey && isRecord(body)
|
|
1154
|
+
? { ...body, idempotency_key: groupIdempotencyKey }
|
|
1155
|
+
: body;
|
|
1156
|
+
await printJson(await client.post("/messages", requestBody, groupIdempotencyKey));
|
|
1004
1157
|
return;
|
|
1005
1158
|
}
|
|
1006
1159
|
throw new Error("Usage: wabery messages get <message_id> | send --body '<json>'");
|
|
@@ -1623,6 +1776,9 @@ function requiredValue(value, name) {
|
|
|
1623
1776
|
throw new Error(`Missing required --${name}`);
|
|
1624
1777
|
return value;
|
|
1625
1778
|
}
|
|
1779
|
+
function isRecord(value) {
|
|
1780
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1781
|
+
}
|
|
1626
1782
|
// Global output shaping, set from --id-only / --field at startup.
|
|
1627
1783
|
let outputIdOnly = false;
|
|
1628
1784
|
let outputField;
|
|
@@ -1745,7 +1901,7 @@ Projects and contacts:
|
|
|
1745
1901
|
wabery projects list
|
|
1746
1902
|
wabery projects get <project_id> # reveals webhook_secret
|
|
1747
1903
|
wabery projects ensure --name "Demo" # idempotently configure the key's scoped project
|
|
1748
|
-
wabery projects update <project_id> [--name <n>] [--require-opt-in true|false] [--webhook-url <url>] [--webhook-signing-enabled true|false] [--webhook-secret <secret>]
|
|
1904
|
+
wabery projects update <project_id> [--name <n>] [--require-opt-in true|false] [--group-webhook-events-enabled true|false] [--webhook-url <url>] [--webhook-signing-enabled true|false] [--webhook-secret <secret>]
|
|
1749
1905
|
wabery projects update <project_id> --require-opt-in false # dedicated number: reply/message inbound users without an invite/opt-in
|
|
1750
1906
|
wabery projects rotate-secret <project_id> [--webhook-secret <secret>]
|
|
1751
1907
|
wabery registration-intents create [--customer-reference <id>] [--metadata '<json>']
|
|
@@ -1784,8 +1940,17 @@ Templates, messages, and conversations:
|
|
|
1784
1940
|
wabery messages send --channel-id <id> --conversation-id <id> --reaction-message-id <wamid> --reaction-emoji "<emoji>"
|
|
1785
1941
|
wabery messages send --channel-id <id> --conversation-id <id> --latitude 37.7749 --longitude -122.4194 --location-name "Store"
|
|
1786
1942
|
wabery messages send --channel-id <id> --conversation-id <id> --sticker-link https://example.com/sticker.webp
|
|
1787
|
-
|
|
1788
|
-
|
|
1943
|
+
# group sends: text, media (including sticker), text/media templates, or pin/unpin only
|
|
1944
|
+
wabery messages send --channel-id <id> --group-id <opaque_group_id> --text "Hello group" --idempotency-key <stable-key>
|
|
1945
|
+
wabery conversations list [--recipient-type individual|group|all]
|
|
1946
|
+
wabery conversations messages <conversation_id> [--recipient-type individual|group]
|
|
1947
|
+
wabery groups list --channel-id <id> [--limit 25] [--starting-after <opaque-cursor>] [--ending-before <opaque-cursor>]
|
|
1948
|
+
wabery groups get <group_id> --channel-id <id> # group_id is not a phone/to value
|
|
1949
|
+
wabery groups create --channel-id <id> --subject "Support" --idempotency-key <stable-key>
|
|
1950
|
+
wabery groups settings <group_id> --channel-id <id> [--subject <text>] [--description <text>] [--profile-picture ./group.jpg]
|
|
1951
|
+
wabery groups invite-link <group_id> --channel-id <id> [reset]
|
|
1952
|
+
wabery groups join-requests <group_id> --channel-id <id> [list|approve|reject] [--starting-after <opaque-cursor>|--ending-before <opaque-cursor>] --join-request-ids id1,id2
|
|
1953
|
+
wabery groups remove-participants <group_id> --channel-id <id> --users user1,user2
|
|
1789
1954
|
wabery limits get
|
|
1790
1955
|
|
|
1791
1956
|
Hosted functions:
|