@wabery/cli 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/README.md CHANGED
@@ -166,7 +166,7 @@ MCP starts in read-only mode. To allow mutation tools for a trusted local
166
166
  session, set `WABERY_MCP_MODE=write` or generate config with `--write`.
167
167
  In local stdio mode, high-risk tools also require confirmation tokens:
168
168
 
169
- - `wabery_apply_config`: `confirmation_token: "apply_config"`
169
+ - `wabery_apply_config`: `confirmation_token: "apply_config"` (hosted-agent Draft only; cannot publish to Live)
170
170
  - `wabery_publish_flow`: `confirmation_token: "publish:<flow_id>"`
171
171
  - `wabery_unenroll_contact` with `erase=true`: `confirmation_token: "erase:<contact_id>"`
172
172
  - `wabery_send_broadcast`: `confirmation_token: "send_broadcast:<broadcast_id>"`
@@ -254,7 +254,7 @@ Installed CLI:
254
254
  - `wabery_export_config`
255
255
  - `wabery_validate_config`
256
256
  - `wabery_preview_config_diff`
257
- - `wabery_apply_config`
257
+ - `wabery_apply_config` (hosted-agent Draft only; cannot publish to Live)
258
258
  - `wabery_list_business_agents`
259
259
  - `wabery_check_business_agent_eligibility`
260
260
  - `wabery_apply_business_agent`
@@ -484,7 +484,7 @@ To remove a phone's sandbox authorization:
484
484
  wabery contacts unenroll "contact_id"
485
485
  ```
486
486
 
487
- `wabery config apply` intentionally does not publish flows to Meta. Agents should call `wabery_publish_flow` only after explicit user confirmation and with the required confirmation token.
487
+ `wabery config apply` updates the hosted-agent Draft only. It cannot edit Live or publish the agent to customers. Publishing to Live happens in the Wabery AI builder after Sandbox testing. It also does not publish Flows to Meta. Agents should call `wabery_publish_flow` only after explicit user confirmation and with the required confirmation token.
488
488
 
489
489
  Template review can take longer than flow publishing. Templates require a dedicated WhatsApp channel with a Meta-verified business account and a Meta payment method; the Wabery sandbox cannot submit your templates. Use `wabery channels get <channel_id>` to inspect `publish_readiness`, then `wabery templates status <template_id>` to force a live Meta status refresh. For scripts, `wabery templates wait <template_id> [--wait=86400]` blocks until approval or fails on rejection/timeout. You can also subscribe to the project's signed `template.status` webhook event.
490
490
 
@@ -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
@@ -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;gBAF7B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO;CAI9B;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;gBAEhB,OAAO,GAAE,mBAAwB;IAkBvC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAIrE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,MAAM;IAI1D,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ;IAIrC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAIhC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO;IAIlC,MAAM,CAAC,IAAI,EAAE,MAAM;YAIX,OAAO;CAyGrB"}
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"}
@@ -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";
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"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"}
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 { Wabery } from "@wabery/sdk";
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
- await printJson(await client.post("/messages", body));
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
- wabery conversations list
1788
- wabery conversations messages <conversation_id>
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: