Skip to content

Commit f5a41bc

Browse files
committed
docs: autoRejectCall option and client.rejectCall() (unofficial-only)
1 parent 0d321a8 commit f5a41bc

5 files changed

Lines changed: 63 additions & 0 deletions

File tree

docs/content/api-reference.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ client.on('text', (ctx) => {
5353
| `pin(key, opts?)` | `(key, opts?: { duration?: number }): Promise<WAMessageKey>` | Pin a message (`duration` seconds; defaults 86400). |
5454
| `unpin(key)` | `(key): Promise<WAMessageKey>` | Unpin a message. |
5555
| `setDisappearing(jid, seconds)` | `(jid: string, seconds: number): Promise<void>` | Set the chat's disappearing-message timer. |
56+
| `rejectCall(call \| callId, from?)` | `(call: CallPayload \| string, from?: string): Promise<void>` | 🔗 Reject an incoming call. Accepts the `call-incoming` payload or raw `callId` + caller jid. Throws `UNSUPPORTED_ON_CLOUD` on the cloud provider. See [`autoRejectCall`](/configuration#autorejectcall). |
5657
| `lidToPn(lid)` | `(lid: string): Promise<string \| null>` | Resolve a `@lid` JID to its phone-number JID (`null` if unknown). Needs a connected socket. |
5758
| `pnToLid(pn)` | `(pn: string): Promise<string \| null>` | Resolve a phone-number JID to its `@lid` JID (`null` if unknown). Needs a connected socket. |
5859
| `broadcast(jids, build, opts?)` | `(jids: string[], build, opts?): Promise<BroadcastResult>` | Send to many recipients. See [Broadcast & Schedule](/automation). |

docs/content/configuration.mdx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ const client = new Client({ sessionId: 'default' })
4242
| `operationGuard` | `OperationGuardOptions` | on (spaces group/community/newsletter ops) | Serializes and rate-limits sensitive group / community / newsletter operations per category so rapid bulk actions don't trip a ban. |
4343
| `presence` | `PresenceThrottleOptions` | on (drops duplicate presence) | Drops repeated presence updates (typing / recording / online) for the same chat within a short window. |
4444
| `scheduleRateLimitPerSec` | `number` | `1` (`0` disables) | Max scheduled messages dispatched per second, smoothing out a backlog of overdue jobs so they don't all fire at once. |
45+
| `autoRejectCall` | `boolean \| AutoRejectCallOptions` | `false` (off) | 🔗 **Unofficial only.** Auto-reject incoming WhatsApp calls. `true` rejects every call; pass an object for an allow-list and an `onReject` hook. |
4546
| `autoDelete` | `AutoDeleteOptions \| false` | `on (1-month retention)` | Periodically prune old messages from the local store. See [Auto-Delete](/auto-delete). |
4647
| `plugins` | `PluginsOptions` | `undefined` | Load and hot-reload plugins from a folder. See [Plugins](/plugins). |
4748
| `autoConnect` | `boolean` | `true` | When `true`, the constructor calls `connect()` on the next microtask. Set `false` to connect manually. |
@@ -527,6 +528,59 @@ const client = new Client({
527528
and `qrTimeout` are merely internal defaults you *can* override here if you really need to.
528529
</Callout>
529530

531+
## `autoRejectCall`
532+
533+
<Callout type="info">
534+
🔗 **Unofficial provider only.** The official [Cloud API](/official) has no call events — calling
535+
`client.rejectCall()` there throws `ZaileysProviderError('UNSUPPORTED_ON_CLOUD')`, and this option is
536+
never wired.
537+
</Callout>
538+
539+
Auto-reject incoming voice/video calls. **Off by default** — rejecting calls is opt-in.
540+
541+
```typescript
542+
// reject every incoming call
543+
const client = new Client({ autoRejectCall: true })
544+
```
545+
546+
| Field | Type | Default | Description |
547+
| --- | --- | --- | --- |
548+
| `enabled` | `boolean` | `false` | Turn auto-rejecting on. Passing `autoRejectCall: true` is shorthand for `{ enabled: true }`. |
549+
| `allow` | `string[] \| (jid: string) => boolean \| Promise<boolean>` | `undefined` | Callers to let ring. Array entries match the full jid **or** its digits. A predicate may be async. |
550+
| `onReject` | `(call) => void \| Promise<void>` | `undefined` | Runs **after** a call was successfully rejected — e.g. to tell the caller why. |
551+
552+
```typescript
553+
const client = new Client({
554+
autoRejectCall: {
555+
enabled: true,
556+
allow: ['628owner@s.whatsapp.net'], // owner may still call
557+
onReject: async (call) => {
558+
await client.send(call.from).text('Maaf, nomor ini tidak menerima telepon 🙏')
559+
},
560+
},
561+
})
562+
```
563+
564+
The `call` passed to `onReject` is the same `call-incoming` payload:
565+
`{ kind, callId, from, isGroup, isVideo, timestamp, status }` — so you can branch on `isVideo` /
566+
`isGroup` inside your hook or inside `allow`.
567+
568+
### Rejecting manually
569+
570+
Leave the option off and drive it yourself from the [`call-incoming`](/events) event:
571+
572+
```typescript
573+
client.on('call-incoming', async (call) => {
574+
if (call.isVideo) await client.rejectCall(call) // pass the payload…
575+
else await client.rejectCall(call.callId, call.from) // …or the raw ids
576+
})
577+
```
578+
579+
<Callout type="default">
580+
`onReject` and `allow` failures are caught and logged — a throwing hook never crashes the client.
581+
`client.rejectCall()` **does** throw (e.g. `NOT_CONNECTED`) so you can handle it.
582+
</Callout>
583+
530584
## `autoDelete`
531585

532586
`autoDelete` periodically prunes old messages from the local store to keep memory usage bounded. It is

docs/content/events.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ See [Interactive Messages](/interactive) for how to send buttons, lists, templat
112112
| --- | --- | --- |
113113
| `call-incoming` | `CallPayload` (`kind: 'incoming'`) | An incoming call. `{ callId, from, isGroup, isVideo, timestamp, status?, kind }`. |
114114
| `call-ended` | `CallPayload` (`kind: 'ended'`) | A call ended. Same shape as above with `kind: 'ended'`. |
115+
116+
<Callout type="info">
117+
🔗 Calls are **unofficial-provider only**. To hang up automatically, set
118+
[`autoRejectCall`](/configuration#autorejectcall); to do it yourself, call
119+
`client.rejectCall(call)` (or `client.rejectCall(callId, from)`) from a `call-incoming` handler.
120+
</Callout>
115121
| `presence` | `PresencePayload` | A contact's presence changed. `{ jid, participant?, status }` where `status` is `available \| unavailable \| composing \| recording \| paused`. |
116122
| `history-sync` | `HistorySyncPayload` | A history sync batch progressed. `{ syncType, status: 'complete' \| 'paused', explicit }`. |
117123
| `newsletter` | `NewsletterPayload` | A newsletter/channel event (reaction, view, participants, settings). `{ newsletterId, timestamp, action, ... }`. |

docs/content/official/limits.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ No amount of config unlocks these — they're not in the Cloud API:
214214
| AIRich rich bubble (`rich: true`), rendered tables | ❌ WhatsApp-Web-only proto | Send plain text (see below); `rich: true` throws a clear error on cloud |
215215
| Edit / delete / pin / disappearing || Send a correction message |
216216
| Presence (others' online/typing) |||
217+
| Calls / auto-reject calls | ❌ no call events in the Cloud API | Use the [unofficial provider](/unofficial) (`autoRejectCall`, `client.rejectCall()`) |
217218
| Status / stories || Unofficial provider |
218219
| Read arbitrary chat history || Persist inbound to your own [store](/storage) |
219220

docs/content/providers.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ Legend — ✅ supported · ❌ not available · ⚠️ conditional.
114114
| Communities |||
115115
| Newsletters (channels) |||
116116
| Presence subscribe (online/typing of others) |||
117+
| Calls (`call-incoming`, `rejectCall`, `autoRejectCall`) |||
117118
| Status / stories |||
118119
| Privacy settings |||
119120

0 commit comments

Comments
 (0)