@getdial/cli 0.38.0 → 0.39.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/cli.js CHANGED
@@ -201,6 +201,8 @@ number
201
201
  .option("--first-name <text>", 'iMessage display first name shown beside this number\'s messages (iMessage numbers only); pass "" to clear')
202
202
  .option("--last-name <text>", 'iMessage display last name (iMessage numbers only); pass "" to clear')
203
203
  .option("--avatar <path-or-url>", "iMessage avatar photo (iMessage numbers only): a local image file (jpeg/png/gif/webp, max 5 MB) to upload, or a public image URL to fetch. Replaces the current photo; photos can't be removed")
204
+ .option("--whatsapp-name <text>", "WhatsApp display name shown to recipients (WhatsApp-ready numbers only): 1-25 chars, no reserved marks. The call blocks until WhatsApp applies it")
205
+ .option("--whatsapp-avatar <path-or-url>", "WhatsApp avatar photo (WhatsApp-ready numbers only): a local image file or public URL. Square jpeg/png between 192x192 and 640x640 (not resized)")
204
206
  .option("--json", "machine-readable output")
205
207
  .action(async (numberArg, opts) => {
206
208
  let maxCallDurationSeconds;
@@ -220,6 +222,8 @@ number
220
222
  firstName: opts.firstName,
221
223
  lastName: opts.lastName,
222
224
  avatar: opts.avatar,
225
+ whatsappName: opts.whatsappName,
226
+ whatsappAvatar: opts.whatsappAvatar,
223
227
  json: !!opts.json,
224
228
  }));
225
229
  });
@@ -17,6 +17,8 @@ export async function runNumberSet(opts) {
17
17
  ...(opts.firstName !== undefined ? { firstName: opts.firstName } : {}),
18
18
  ...(opts.lastName !== undefined ? { lastName: opts.lastName } : {}),
19
19
  ...(opts.avatar !== undefined ? { avatar: opts.avatar } : {}),
20
+ ...(opts.whatsappName !== undefined ? { whatsappName: opts.whatsappName } : {}),
21
+ ...(opts.whatsappAvatar !== undefined ? { whatsappAvatar: opts.whatsappAvatar } : {}),
20
22
  });
21
23
  if (opts.json) {
22
24
  console.log(JSON.stringify({ ok: true, number: n }));
@@ -34,6 +36,10 @@ export async function runNumberSet(opts) {
34
36
  console.log(` display name: ${[n.firstName, n.lastName].filter(Boolean).join(" ")}`);
35
37
  console.log(` avatar: ${n.avatarUrl ?? ""}`);
36
38
  }
39
+ if (n.whatsappName != null || n.whatsappAvatarUrl != null) {
40
+ console.log(` whatsapp name: ${n.whatsappName ?? ""}`);
41
+ console.log(` whatsapp avatar: ${n.whatsappAvatarUrl ?? ""}`);
42
+ }
37
43
  }
38
44
  return 0;
39
45
  }
@@ -117,14 +117,21 @@ export async function setNumberProperties(opts) {
117
117
  body.firstName = opts.firstName;
118
118
  if (opts.lastName !== undefined)
119
119
  body.lastName = opts.lastName;
120
+ if (opts.whatsappName !== undefined)
121
+ body.whatsappName = opts.whatsappName;
120
122
  // A URL avatar goes in the JSON body; a local file forces multipart (below).
121
123
  // Read + validate the file up front, before any API round-trip, so a bad
122
124
  // path or unsupported type fails fast.
123
125
  const avatarFile = opts.avatar !== undefined && !isHttpUrl(opts.avatar) ? readAvatarFile(opts.avatar) : null;
124
126
  if (opts.avatar !== undefined && !avatarFile)
125
127
  body.avatarUrl = opts.avatar;
126
- if (Object.keys(body).length === 0 && !avatarFile) {
127
- throw new DialError("bad_request", "Provide at least one property to update (inboundInstruction, inboundVoiceGender, inboundLanguage, nickname, maxCallDurationSeconds, firstName, lastName, or avatar).");
128
+ const whatsappAvatarFile = opts.whatsappAvatar !== undefined && !isHttpUrl(opts.whatsappAvatar)
129
+ ? readAvatarFile(opts.whatsappAvatar)
130
+ : null;
131
+ if (opts.whatsappAvatar !== undefined && !whatsappAvatarFile)
132
+ body.whatsappAvatarUrl = opts.whatsappAvatar;
133
+ if (Object.keys(body).length === 0 && !avatarFile && !whatsappAvatarFile) {
134
+ throw new DialError("bad_request", "Provide at least one property to update (inboundInstruction, inboundVoiceGender, inboundLanguage, nickname, maxCallDurationSeconds, firstName, lastName, avatar, whatsappName, or whatsappAvatar).");
128
135
  }
129
136
  const auth = maybeAuth();
130
137
  // The REST API keys numbers by id; the CLI/tool takes the E.164 number for ergonomics,
@@ -141,11 +148,18 @@ export async function setNumberProperties(opts) {
141
148
  // A local avatar file forces a multipart PATCH: every scalar field goes in as a
142
149
  // text part alongside the uploaded `avatar` file. Otherwise a plain JSON PATCH.
143
150
  let res;
144
- if (avatarFile) {
151
+ if (avatarFile || whatsappAvatarFile) {
145
152
  const form = new ApiFormData();
146
153
  for (const [field, value] of Object.entries(body))
147
154
  form.set(field, String(value));
148
- form.append("avatar", new Blob([new Uint8Array(avatarFile.data)], { type: avatarFile.contentType }), avatarFile.name);
155
+ if (avatarFile) {
156
+ form.append("avatar", new Blob([new Uint8Array(avatarFile.data)], { type: avatarFile.contentType }), avatarFile.name);
157
+ }
158
+ if (whatsappAvatarFile) {
159
+ form.append("whatsappAvatar", new Blob([new Uint8Array(whatsappAvatarFile.data)], {
160
+ type: whatsappAvatarFile.contentType,
161
+ }), whatsappAvatarFile.name);
162
+ }
149
163
  res = await apiPatchMultipart(path, form, auth?.apiKey);
150
164
  }
151
165
  else {
@@ -53,6 +53,16 @@ export const phoneNumberSchema = z
53
53
  .nullable()
54
54
  .optional()
55
55
  .describe("URL of the number's iMessage avatar photo; null when unset or not an iMessage number"),
56
+ whatsappName: z
57
+ .string()
58
+ .nullable()
59
+ .optional()
60
+ .describe("WhatsApp display name; null on numbers without a WhatsApp track"),
61
+ whatsappAvatarUrl: z
62
+ .string()
63
+ .nullable()
64
+ .optional()
65
+ .describe("URL of the number's WhatsApp avatar; null when unset"),
56
66
  })
57
67
  .passthrough();
58
68
  /**
@@ -44,12 +44,21 @@ const inputSchema = {
44
44
  .url()
45
45
  .optional()
46
46
  .describe("Public image URL to set as the number's iMessage avatar photo (the server downloads it). jpeg/png/gif/webp, max 5 MB. iMessage numbers only. The photo can be replaced but not removed."),
47
+ whatsappName: z
48
+ .string()
49
+ .optional()
50
+ .describe("WhatsApp display name shown to recipients. 1-25 chars, no reserved verification marks. WhatsApp-ready numbers only; the call blocks until WhatsApp applies it."),
51
+ whatsappAvatarUrl: z
52
+ .string()
53
+ .url()
54
+ .optional()
55
+ .describe("Public image URL to set as the number's WhatsApp avatar (the server downloads it). Square jpeg or png between 192x192 and 640x640 (not resized). WhatsApp-ready numbers only."),
47
56
  };
48
57
  export const setNumberPropertiesTool = {
49
58
  name: "set_number_properties",
50
59
  config: {
51
60
  title: "Set Number Properties",
52
- description: "Update a phone number's properties: its inbound instruction (the system prompt for inbound calls), inbound voice gender, inbound language, nickname, and — for iMessage numbers — its display identity (firstName, lastName, avatarUrl shown beside its messages). Provide at least one.",
61
+ description: "Update a phone number's properties: its inbound instruction (the system prompt for inbound calls), inbound voice gender, inbound language, nickname, and — for iMessage numbers — its display identity (firstName, lastName, avatarUrl), and for WhatsApp-ready numbers its WhatsApp identity (whatsappName, whatsappAvatarUrl). Provide at least one.",
53
62
  inputSchema,
54
63
  outputSchema: { number: phoneNumberSchema },
55
64
  annotations: { openWorldHint: true },
@@ -69,6 +78,10 @@ export const setNumberPropertiesTool = {
69
78
  ? { maxCallDurationSeconds: args.maxCallDurationSeconds }
70
79
  : {}),
71
80
  ...(args.firstName !== undefined ? { firstName: args.firstName } : {}),
81
+ ...(args.whatsappName !== undefined ? { whatsappName: args.whatsappName } : {}),
82
+ ...(args.whatsappAvatarUrl !== undefined
83
+ ? { whatsappAvatar: args.whatsappAvatarUrl }
84
+ : {}),
72
85
  ...(args.lastName !== undefined ? { lastName: args.lastName } : {}),
73
86
  ...(args.avatarUrl !== undefined ? { avatar: args.avatarUrl } : {}),
74
87
  }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getdial/cli",
3
- "version": "0.38.0",
3
+ "version": "0.39.0",
4
4
  "description": "Dial CLI — install, sign up, and run the local listen service.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/skills.tar.gz CHANGED
Binary file