Repository navigation
feat(calls): add call consent commands - #29
Conversation
Add the team call policy, do-not-call list, Cloud API call permission and pre-dial check commands: calls policy get|set calls opt-outs list|add|import|remove calls permission get|request calls check `calls policy` and `calls opt-outs` need an organization API key; the API answers a project token or client token with 403. `calls permission get` and `calls check` need a server API key, so the CLI refuses a Messaging client token before it sends a request. `calls permission request` sends callPermissionRequest content through the messages send route. `calls opt-outs import` reads a CSV or JSON file, or standard input, sends 5,000 entries per request, and reports added, already listed and rejected entries at their position in the file. It exits with code 12 when entries were rejected or when a later batch failed after earlier batches were stored, and with the request's own code when nothing was stored. `calls check` exits with code 0 whether or not the call is allowed; read `allowed` and `refusal` from the output. Rate-limited commands now report the API's Retry-After wait in the message and as `retryAfterSeconds` in --json error output. This covers every rate-limited command, not only call permission requests. The pinned SDK commit has no call consent resources, so these commands use the SDK's own raw transport. src/services/call-consent.ts is the single place to move to typed resources once the SDK ships them.
|
Warning Review limit reached
Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing. Next included review available in 34 minutes. View limit detailsLimit details: You’ve used all 2 included reviews currently available. Your 69 included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (31)
Comment |
The polymorfa/sdks branch t3code/calls-consent adds the typed call consent resources, but its repository root package is now the private workspace root polymorfa-sdks with no built dist, so github:polymorfa/sdks#<commit> no longer installs @polymorfa/sdk. Repinning needs a published prerelease.
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bd1d69a6e8
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ...identity, | ||
| }, | ||
| }) | ||
| items.push(...response.data.data) |
There was a problem hiding this comment.
Enforce the max-items cap on returned pages
When --paginate --max-items N is used and the API returns more items than the requested page limit, this appends the entire page before checking items.length, so the command can emit more than the promised maximum. The shared pagination helpers already handle this by slicing to the remaining count and suppressing the unusable continuation cursor; this path should do the same so a nonconforming or version-skewed server response cannot defeat the user’s safety limit.
Useful? React with 👍 / 👎.
| if (page.nextCursor === cursor) { | ||
| throw new PolymorfaValidationError( | ||
| 'The API returned the same continuation cursor for the next page.', | ||
| {code: 'pagination_cursor_unchanged'}, | ||
| ) |
There was a problem hiding this comment.
Classify repeated cursors as server failures
When the API repeats a cursor during --paginate, the defect is in the server response, but throwing PolymorfaValidationError reports exit code 2 and a non-retryable validation category as though the user supplied invalid input. The existing assertCursorAdvanced helper classifies this exact condition as PolymorfaServerError; using that behavior here preserves the CLI’s error semantics and lets callers handle the failure as transient/server-side.
Useful? React with 👍 / 👎.
| const reason = presentError(progress.error).message | ||
| throw new CliConditionError( | ||
| 'partial_success', | ||
| `Stored ${summary.batches} of ${Math.ceil(entries.length / IMPORT_BATCH_SIZE)} batches, then a request failed: ${reason} Run the import again; entries already stored are counted as already listed.`, |
There was a problem hiding this comment.
Count only requestable import batches
The total here includes entries that importCallOptOuts removes as local rejections before batching. For example, with 10,001 input entries where 5,000 are valid, 5,000 are over-length, and the final entry is valid, only two API batches exist; if the second request fails, this reports Stored 1 of 3 batches. Track the sendable batch count in the import progress instead so partial-failure guidance accurately describes how many requests remain.
Useful? React with 👍 / 👎.
| static override description = | ||
| 'Read the team call policy: the blocked country codes, the number of entries on the do-not-call list, and the revision to pass to `calls policy set --expected-revision`. The revision is 0 before the codes are first saved. Requires an organization API key; project tokens and client tokens are refused (exit code 3).' |
There was a problem hiding this comment.
Align credential errors with the advertised exit code
With only POLYMORFA_CLIENT_TOKEN or POLYMORFA_PROJECT_TOKEN configured, platformClient() never reaches the API: platform environment resolution requires POLYMORFA_API_KEY and raises a configuration error, which exits with code 2. Thus these credentials cannot produce the documented HTTP 403/exit-code-3 behavior; either allow them through for server authorization or document the actual local refusal and exit code.
Useful? React with 👍 / 👎.
…d count sent batches --max-items slices an oversized page and withholds its cursor, a repeated cursor is a server failure (assertCursorAdvanced), a failed import reports the batches it actually sends, and the call policy help states the real exit codes for project and client tokens. Co-Authored-By: Claude <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
# Conflicts: # src/errors/present.ts # test/errors/present.test.ts
# Conflicts: # README.md # docs/command-research/campaigns.md # package.json # src/services/campaigns.ts # test/commands/campaigns.test.ts
# Conflicts: # src/errors/present.ts # test/errors/present.test.ts
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a9239caf9c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (text[position + 1] === '"') { | ||
| cell += '"' | ||
| position += 1 | ||
| } else quoted = false |
There was a problem hiding this comment.
Reject characters after a closing CSV quote
When a quoted field is followed by non-delimiter text, this immediately leaves quoted mode and appends that text to the field; for example, +14155550123,"asked"oops is silently imported with note askedoops. Because this malformed CSV can alter identifiers or notes before they are sent to the API, track the just-closed state and reject anything other than a delimiter, row ending, or EOF.
Useful? React with 👍 / 👎.
Adds CLI commands for call consent and enrolled HMS history reads on the existing
devbranch.Call consent commands cover team policy, do-not-call entries, Cloud API call permission retrieval/request, and the pre-dial check.
calls checkreturns exit 0 for a valid check even whenallowedis false, so scripts must inspectallowedandrefusal. Permission requests retainRetry-Afterin human and JSON errors. Imports use bounded 5,000-entry batches and report partial rejection positions.History commands add
chat list,chat view,chat message list, andchat message view. They preserve API cursors and accept an organization API key or an exact-project server token; Messaging client tokens are refused by the SDK. Help and README state the enrolled beta prerequisites.This PR pins the exact published
@polymorfa/sdk@0.1.0-dev.20260923162255(lockfile integritysha512-Z4MIheeT0qzM0TIywT6DvP5DMzDrMi1+ohU0/bqEdt7ar+4jHJjcNGfn3YkE6icluaLPSScO49tsvty00eMW8A==), built from merged SDK #284 ate05d882074ae680bb26698c3882825cafcd4a72a. The SDK contract source is merged APIdeve72b51348e16e704f17b3e681ee60d02fcca8c7f, including HMS #202 and consent #226. Calls remains unreleased; history requires themessaging.historyenrolled beta, scopes, HMS enablement, and regional read availability.Verification
Clean Node 22
npm ciandnpm run verifypass: formatting, lint, typecheck, 804 tests, build, package dry-run, and production audit with zero vulnerabilities. Tests use fixture HTTP responses; no real WhatsApp number, deployed CLI, or customer enrollment was exercised. Current-head CI and Codex review are pending.Cross-surface assessment