@keystrokehq/resend 0.0.1
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 +184 -0
- package/dist/_official/index.d.mts +2 -0
- package/dist/_official/index.mjs +3 -0
- package/dist/_runtime/index.d.mts +1 -0
- package/dist/_runtime/index.mjs +1 -0
- package/dist/api-keys.d.mts +67 -0
- package/dist/api-keys.mjs +90 -0
- package/dist/broadcasts.d.mts +238 -0
- package/dist/broadcasts.mjs +178 -0
- package/dist/client.d.mts +27 -0
- package/dist/client.mjs +40 -0
- package/dist/connection.d.mts +2 -0
- package/dist/connection.mjs +3 -0
- package/dist/contact-properties.d.mts +139 -0
- package/dist/contact-properties.mjs +115 -0
- package/dist/contacts.d.mts +218 -0
- package/dist/contacts.mjs +225 -0
- package/dist/domains.d.mts +293 -0
- package/dist/domains.mjs +160 -0
- package/dist/emails-receiving.d.mts +177 -0
- package/dist/emails-receiving.mjs +114 -0
- package/dist/emails.d.mts +307 -0
- package/dist/emails.mjs +241 -0
- package/dist/events.d.mts +571 -0
- package/dist/events.mjs +178 -0
- package/dist/factory-B3VyPRsL.mjs +8 -0
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -0
- package/dist/integration-BR1nTAnU.mjs +28 -0
- package/dist/integration-ClH0F7x-.d.mts +49 -0
- package/dist/logs.d.mts +71 -0
- package/dist/logs.mjs +61 -0
- package/dist/schemas.d.mts +77 -0
- package/dist/schemas.mjs +68 -0
- package/dist/segments.d.mts +112 -0
- package/dist/segments.mjs +120 -0
- package/dist/templates.d.mts +193 -0
- package/dist/templates.mjs +151 -0
- package/dist/topics.d.mts +125 -0
- package/dist/topics.mjs +113 -0
- package/dist/triggers.d.mts +68 -0
- package/dist/triggers.mjs +141 -0
- package/dist/verification.d.mts +49 -0
- package/dist/verification.mjs +139 -0
- package/dist/webhooks.d.mts +285 -0
- package/dist/webhooks.mjs +124 -0
- package/package.json +137 -0
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# @keystrokehq/resend
|
|
2
|
+
|
|
3
|
+
Resend integration for Keystroke workflows — transactional email, broadcasts, contacts, segments, templates, domains, and Svix-signed webhook triggers.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package wraps the [Resend](https://resend.com) v1 REST API and exposes:
|
|
8
|
+
|
|
9
|
+
- **66 operations** across 12 resource domains.
|
|
10
|
+
- **17 direct-binding webhook trigger helpers** (11 email, 3 domain, 3 contact) with Svix v1 signature verification.
|
|
11
|
+
- An idempotent `ensureResendWebhook` helper that registers a webhook endpoint, reconciles its event subscription, and returns the per-endpoint signing secret.
|
|
12
|
+
|
|
13
|
+
No runtime dependency on the official `resend` npm package — the client is a thin wrapper over the shared `createJsonRestClient` helper from `@keystrokehq/integration-authoring`, and the Svix verifier is hand-rolled on top of Node's `crypto` module. See [`IMPLEMENTATION_NOTES.md`](./IMPLEMENTATION_NOTES.md) § 3 for the SDK rejection rationale.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pnpm add @keystrokehq/resend
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Credentials
|
|
22
|
+
|
|
23
|
+
The public connection is manual API-key auth.
|
|
24
|
+
|
|
25
|
+
Required:
|
|
26
|
+
|
|
27
|
+
- `RESEND_API_KEY` — an API key from your Resend dashboard (`re_…`).
|
|
28
|
+
|
|
29
|
+
Optional:
|
|
30
|
+
|
|
31
|
+
- `RESEND_WEBHOOK_SIGNING_SECRETS` — a map of `{ webhookId: whsec_… }`. Populate it automatically via `ensureResendWebhook` (see below) before binding webhook triggers.
|
|
32
|
+
|
|
33
|
+
There is no OAuth flow and no Keystroke-owned shared client secret. API keys are team-scoped — one Keystroke connection = one Resend team.
|
|
34
|
+
|
|
35
|
+
## Quickstart
|
|
36
|
+
|
|
37
|
+
Import the connection and two helpers you'll use most:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { resend, type ResendCredentials } from '@keystrokehq/resend/connection';
|
|
41
|
+
import { sendEmail } from '@keystrokehq/resend/emails';
|
|
42
|
+
import { triggers } from '@keystrokehq/resend/triggers';
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Send a transactional email
|
|
46
|
+
|
|
47
|
+
`sendEmail` is a Keystroke operation. Drop it into a workflow step that has the Resend connection attached; the workflow runtime hands it typed credentials.
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { sendEmail } from '@keystrokehq/resend/emails';
|
|
51
|
+
|
|
52
|
+
sendEmail({
|
|
53
|
+
id: 'welcome_email',
|
|
54
|
+
// Keystroke wires input at workflow-compile time; the shape below is
|
|
55
|
+
// the validated input of sendEmail.
|
|
56
|
+
input: {
|
|
57
|
+
from: 'Acme <onboarding@acme.example>',
|
|
58
|
+
to: ['delivered@resend.dev'],
|
|
59
|
+
subject: 'Welcome to Acme',
|
|
60
|
+
html: '<p>Glad you are here.</p>',
|
|
61
|
+
// Optional; forwarded as the Idempotency-Key header (24h TTL).
|
|
62
|
+
idempotency_key: 'welcome-2026-04-20',
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Subscribe to delivery events
|
|
68
|
+
|
|
69
|
+
All Resend webhooks go through one signed HTTPS POST channel. Bind one helper per event type:
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { triggers } from '@keystrokehq/resend/triggers';
|
|
73
|
+
|
|
74
|
+
const onBounce = triggers.emailBounced({
|
|
75
|
+
name: 'Resend bounce handler',
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
`triggers.emailOpened` filters out Apple Mail Privacy Protection cache-opens (`data.is_machine_opened === true`) by default — if you want those too, pass a custom `filter` in the binding options.
|
|
80
|
+
|
|
81
|
+
### Wire the webhook endpoint
|
|
82
|
+
|
|
83
|
+
Before a trigger binding can verify payloads it needs the per-endpoint `whsec_…` signing secret on the credential set. Run this once per environment:
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
import { ensureResendWebhook } from '@keystrokehq/resend/triggers';
|
|
87
|
+
|
|
88
|
+
const result = await ensureResendWebhook({
|
|
89
|
+
credentials,
|
|
90
|
+
endpointUrl: 'https://workflows.example.com/hooks/resend',
|
|
91
|
+
events: ['email.delivered', 'email.bounced', 'email.complained'],
|
|
92
|
+
});
|
|
93
|
+
// result.webhookId, result.signingSecret, result.created, result.updated
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Then persist `result.signingSecret` under `credentials.RESEND_WEBHOOK_SIGNING_SECRETS[result.webhookId]`. The trigger verifier iterates every secret in that map, which also handles rotation: add a new webhook, store its secret alongside the old one, and remove the old webhook once you've cut over.
|
|
97
|
+
|
|
98
|
+
## Resource domains
|
|
99
|
+
|
|
100
|
+
Every endpoint on the public Resend v1 API is wrapped.
|
|
101
|
+
|
|
102
|
+
| Subpath | Endpoints covered |
|
|
103
|
+
|---------|-------------------|
|
|
104
|
+
| `@keystrokehq/resend/emails` | `POST /emails`, `POST /emails/batch`, `GET /emails`, `GET /emails/{id}`, `PATCH /emails/{id}`, `POST /emails/{id}/cancel`, `GET /emails/{id}/attachments`, `GET /emails/{id}/attachments/{id}` |
|
|
105
|
+
| `@keystrokehq/resend/emails-receiving` | `GET /emails/receiving`, `GET /emails/receiving/{id}`, `GET /emails/receiving/{id}/attachments`, `GET /emails/receiving/{id}/attachments/{id}` |
|
|
106
|
+
| `@keystrokehq/resend/templates` | CRUD + duplicate + publish |
|
|
107
|
+
| `@keystrokehq/resend/broadcasts` | CRUD + send |
|
|
108
|
+
| `@keystrokehq/resend/contacts` | CRUD + segment-membership + topic-subscriptions |
|
|
109
|
+
| `@keystrokehq/resend/contact-properties` | CRUD |
|
|
110
|
+
| `@keystrokehq/resend/segments` | CRUD + list-contacts (no update — segments are filter-defined) |
|
|
111
|
+
| `@keystrokehq/resend/topics` | CRUD |
|
|
112
|
+
| `@keystrokehq/resend/domains` | CRUD + verify |
|
|
113
|
+
| `@keystrokehq/resend/api-keys` | Create, list, delete (no get/update on the Resend API) |
|
|
114
|
+
| `@keystrokehq/resend/webhooks` | CRUD (endpoint CRUD — for direct-binding triggers use `/triggers`) |
|
|
115
|
+
| `@keystrokehq/resend/logs` | List, retrieve (plan-gated) |
|
|
116
|
+
|
|
117
|
+
### Support-surface imports
|
|
118
|
+
|
|
119
|
+
Use these when you need to wire secondary pieces (raw client, schema types, event constants, verification helpers):
|
|
120
|
+
|
|
121
|
+
- `@keystrokehq/resend/connection` — `resend`, `ResendCredentials`, `resendAuthSchema`.
|
|
122
|
+
- `@keystrokehq/resend/client` — `createResendClient`, `ResendClient`, `RESEND_BASE_URL`, `RESEND_USER_AGENT`.
|
|
123
|
+
- `@keystrokehq/resend/schemas` — list envelope, pagination, region / TLS / permission enums.
|
|
124
|
+
- `@keystrokehq/resend/events` — event name constants and payload schemas.
|
|
125
|
+
- `@keystrokehq/resend/verification` — `verifyResendWebhookRequest`, `parseResendWebhookBody`, Svix header constants.
|
|
126
|
+
|
|
127
|
+
### Hidden surfaces (do not import from application code)
|
|
128
|
+
|
|
129
|
+
`@keystrokehq/resend/_official` and `@keystrokehq/resend/_runtime` exist for `@keystrokehq/official-integration-catalog`. End users should not import them.
|
|
130
|
+
|
|
131
|
+
## Safety model
|
|
132
|
+
|
|
133
|
+
Writes and deletes are marked `needsApproval: true`. Read-only list/retrieve operations are not. Callers can override either way per-operation, but the defaults reflect Resend's destructive-action surface.
|
|
134
|
+
|
|
135
|
+
## Webhook verification (standalone)
|
|
136
|
+
|
|
137
|
+
If you want to verify a Resend webhook outside the Keystroke trigger runtime:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import {
|
|
141
|
+
verifyResendWebhookRequest,
|
|
142
|
+
parseResendWebhookBody,
|
|
143
|
+
} from '@keystrokehq/resend/verification';
|
|
144
|
+
import { resendWebhookEventSchema } from '@keystrokehq/resend/events';
|
|
145
|
+
|
|
146
|
+
function handle(request: {
|
|
147
|
+
rawBody: string;
|
|
148
|
+
headers: Record<string, string | string[] | undefined>;
|
|
149
|
+
}) {
|
|
150
|
+
const verified = verifyResendWebhookRequest({
|
|
151
|
+
rawBody: request.rawBody,
|
|
152
|
+
headers: request.headers,
|
|
153
|
+
signingSecret: process.env.RESEND_WEBHOOK_SECRET ?? '',
|
|
154
|
+
});
|
|
155
|
+
if (!verified.ok) {
|
|
156
|
+
return { status: 401 as const, reason: verified.reason };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const body = parseResendWebhookBody(request.rawBody);
|
|
160
|
+
const event = resendWebhookEventSchema.parse(body);
|
|
161
|
+
return { status: 200 as const, event };
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Caveats
|
|
166
|
+
|
|
167
|
+
- **User-Agent is mandatory.** The Resend API returns HTTP 403 with error code 1010 if no `User-Agent` is attached. The client sets one automatically.
|
|
168
|
+
- **Rate limit.** Default is 5 requests/second per team. Retries are not automatic — callers should implement backoff, or forward an `Idempotency-Key` on `sendEmail`/`sendBatchEmails` so retries are safe.
|
|
169
|
+
- **Apple Mail Privacy Protection.** `triggers.emailOpened` silently drops `is_machine_opened: true` events. Override the `filter` to opt in.
|
|
170
|
+
- **React rendering is not server-side.** The official SDK's `react` body field is intentionally not accepted — render React Email components to HTML upstream and pass the string via `html`.
|
|
171
|
+
- **CSV imports do not emit `contact.created`.** Documented limitation. If you need that signal, poll `listContacts` with cursor persistence.
|
|
172
|
+
- **Signing-secret rotation.** Resend does not expose in-place rotation. Cut over by creating a second webhook, storing its new secret alongside the old one in `RESEND_WEBHOOK_SIGNING_SECRETS`, and deleting the old endpoint once traffic has flipped. The trigger verifier iterates every secret in the map.
|
|
173
|
+
|
|
174
|
+
## References
|
|
175
|
+
|
|
176
|
+
- API docs index: <https://resend.com/docs/api-reference/introduction>
|
|
177
|
+
- Webhook event types: <https://resend.com/docs/dashboard/webhooks/event-types>
|
|
178
|
+
- Webhook verification: <https://resend.com/docs/webhooks/verify-webhooks-requests>
|
|
179
|
+
- Pagination: <https://resend.com/docs/api-reference/pagination>
|
|
180
|
+
- OpenAPI spec: <https://github.com/resend/resend-openapi>
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
|
|
3
|
+
import * as _keystrokehq_core0 from "@keystrokehq/core";
|
|
4
|
+
|
|
5
|
+
//#region src/api-keys.d.ts
|
|
6
|
+
declare const apiKeySummarySchema: z.ZodObject<{
|
|
7
|
+
id: z.ZodString;
|
|
8
|
+
name: z.ZodOptional<z.ZodString>;
|
|
9
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, z.core.$loose>;
|
|
11
|
+
declare const apiKeyCreatedSchema: z.ZodObject<{
|
|
12
|
+
id: z.ZodString;
|
|
13
|
+
token: z.ZodString;
|
|
14
|
+
}, z.core.$loose>;
|
|
15
|
+
declare const createApiKey: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
permission: z.ZodDefault<z.ZodEnum<{
|
|
18
|
+
full_access: "full_access";
|
|
19
|
+
sending_access: "sending_access";
|
|
20
|
+
}>>;
|
|
21
|
+
domain_id: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
23
|
+
id: z.ZodString;
|
|
24
|
+
token: z.ZodString;
|
|
25
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
26
|
+
RESEND_API_KEY: z.ZodString;
|
|
27
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
28
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
29
|
+
RESEND_API_KEY: z.ZodString;
|
|
30
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
31
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
32
|
+
declare const listApiKeys: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
33
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
after: z.ZodOptional<z.ZodString>;
|
|
35
|
+
before: z.ZodOptional<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
37
|
+
object: z.ZodLiteral<"list">;
|
|
38
|
+
has_more: z.ZodBoolean;
|
|
39
|
+
data: z.ZodArray<z.ZodObject<{
|
|
40
|
+
id: z.ZodString;
|
|
41
|
+
name: z.ZodOptional<z.ZodString>;
|
|
42
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
43
|
+
}, z.core.$loose>>;
|
|
44
|
+
}, z.core.$strip>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
45
|
+
RESEND_API_KEY: z.ZodString;
|
|
46
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
47
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
48
|
+
RESEND_API_KEY: z.ZodString;
|
|
49
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
50
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
51
|
+
declare const deleteApiKey: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
52
|
+
id: z.ZodString;
|
|
53
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
54
|
+
object: z.ZodOptional<z.ZodLiteral<"api_key">>;
|
|
55
|
+
id: z.ZodString;
|
|
56
|
+
deleted: z.ZodOptional<z.ZodBoolean>;
|
|
57
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
58
|
+
RESEND_API_KEY: z.ZodString;
|
|
59
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
60
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
61
|
+
RESEND_API_KEY: z.ZodString;
|
|
62
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
63
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
64
|
+
type ResendApiKeySummary = z.infer<typeof apiKeySummarySchema>;
|
|
65
|
+
type ResendApiKeyCreated = z.infer<typeof apiKeyCreatedSchema>;
|
|
66
|
+
//#endregion
|
|
67
|
+
export { ResendApiKeyCreated, ResendApiKeySummary, createApiKey, deleteApiKey, listApiKeys };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { createResendClient } from "./client.mjs";
|
|
2
|
+
import { paginationQuerySchema, resendApiKeyPermissionSchema, resendListEnvelope } from "./schemas.mjs";
|
|
3
|
+
import { t as resendOperation } from "./factory-B3VyPRsL.mjs";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
|
|
6
|
+
//#region src/api-keys.ts
|
|
7
|
+
/**
|
|
8
|
+
* resend/api-keys.ts
|
|
9
|
+
*
|
|
10
|
+
* Operations backing the Resend `/api-keys` endpoints.
|
|
11
|
+
* PLAN.md § 6.4: 3 operations (create, list, delete).
|
|
12
|
+
*
|
|
13
|
+
* Resend's API does not expose GET-by-id or PATCH for API keys today,
|
|
14
|
+
* so those are intentionally absent rather than faked.
|
|
15
|
+
*
|
|
16
|
+
* Permission tiers (verified against
|
|
17
|
+
* <https://resend.com/docs/api-reference/api-keys/create-api-key>):
|
|
18
|
+
*
|
|
19
|
+
* - `full_access` — every endpoint
|
|
20
|
+
* - `sending_access` — send emails only; optionally pinned to one
|
|
21
|
+
* `domain_id`
|
|
22
|
+
*
|
|
23
|
+
* PLAN.md § 6.4 initially speculated a third `sending_only` tier;
|
|
24
|
+
* that is not a distinct tier — it is `sending_access` + `domain_id`.
|
|
25
|
+
* See IMPLEMENTATION_NOTES.md § 7 correction #2.
|
|
26
|
+
*/
|
|
27
|
+
const apiKeySummarySchema = z.object({
|
|
28
|
+
id: z.string(),
|
|
29
|
+
name: z.string().optional(),
|
|
30
|
+
created_at: z.string().optional()
|
|
31
|
+
}).passthrough();
|
|
32
|
+
const apiKeyCreatedSchema = z.object({
|
|
33
|
+
id: z.string(),
|
|
34
|
+
token: z.string()
|
|
35
|
+
}).passthrough();
|
|
36
|
+
const listApiKeysResponseSchema = resendListEnvelope(apiKeySummarySchema);
|
|
37
|
+
const createApiKey = resendOperation({
|
|
38
|
+
id: "create_resend_api_key",
|
|
39
|
+
name: "Create Resend API Key",
|
|
40
|
+
description: "Create a new API key. The cleartext token is returned once — store it immediately; Resend cannot retrieve it again.",
|
|
41
|
+
input: z.object({
|
|
42
|
+
name: z.string().min(1).max(50),
|
|
43
|
+
permission: resendApiKeyPermissionSchema.default("full_access"),
|
|
44
|
+
domain_id: z.string().min(1).optional().describe("When set with permission=sending_access, restricts the key to sending from a single verified domain.")
|
|
45
|
+
}),
|
|
46
|
+
output: apiKeyCreatedSchema,
|
|
47
|
+
needsApproval: true,
|
|
48
|
+
run: async (input, credentials) => {
|
|
49
|
+
return createResendClient(credentials).request({
|
|
50
|
+
method: "POST",
|
|
51
|
+
path: "/api-keys",
|
|
52
|
+
body: input
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
const listApiKeys = resendOperation({
|
|
57
|
+
id: "list_resend_api_keys",
|
|
58
|
+
name: "List Resend API Keys",
|
|
59
|
+
description: "List API keys for the authenticated team.",
|
|
60
|
+
input: paginationQuerySchema,
|
|
61
|
+
output: listApiKeysResponseSchema,
|
|
62
|
+
run: async (input, credentials) => {
|
|
63
|
+
return createResendClient(credentials).request({
|
|
64
|
+
method: "GET",
|
|
65
|
+
path: "/api-keys",
|
|
66
|
+
query: input
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const deleteApiKey = resendOperation({
|
|
71
|
+
id: "delete_resend_api_key",
|
|
72
|
+
name: "Delete Resend API Key",
|
|
73
|
+
description: "Delete (revoke) an API key.",
|
|
74
|
+
input: z.object({ id: z.string().min(1) }),
|
|
75
|
+
output: z.object({
|
|
76
|
+
object: z.literal("api_key").optional(),
|
|
77
|
+
id: z.string(),
|
|
78
|
+
deleted: z.boolean().optional()
|
|
79
|
+
}).passthrough(),
|
|
80
|
+
needsApproval: true,
|
|
81
|
+
run: async (input, credentials) => {
|
|
82
|
+
return createResendClient(credentials).request({
|
|
83
|
+
method: "DELETE",
|
|
84
|
+
path: `/api-keys/${encodeURIComponent(input.id)}`
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
//#endregion
|
|
90
|
+
export { createApiKey, deleteApiKey, listApiKeys };
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as _keystrokehq_core_credential_set0 from "@keystrokehq/core/credential-set";
|
|
3
|
+
import * as _keystrokehq_core0 from "@keystrokehq/core";
|
|
4
|
+
|
|
5
|
+
//#region src/broadcasts.d.ts
|
|
6
|
+
declare const broadcastSummarySchema: z.ZodObject<{
|
|
7
|
+
id: z.ZodString;
|
|
8
|
+
name: z.ZodOptional<z.ZodString>;
|
|
9
|
+
status: z.ZodOptional<z.ZodUnion<[z.ZodEnum<{
|
|
10
|
+
sending: "sending";
|
|
11
|
+
draft: "draft";
|
|
12
|
+
scheduled: "scheduled";
|
|
13
|
+
queued: "queued";
|
|
14
|
+
sent: "sent";
|
|
15
|
+
cancelled: "cancelled";
|
|
16
|
+
failed: "failed";
|
|
17
|
+
}>, z.ZodString]>>;
|
|
18
|
+
audience_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
19
|
+
segment_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
20
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
21
|
+
updated_at: z.ZodOptional<z.ZodString>;
|
|
22
|
+
scheduled_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
23
|
+
sent_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
24
|
+
}, z.core.$loose>;
|
|
25
|
+
declare const broadcastDetailSchema: z.ZodObject<{
|
|
26
|
+
id: z.ZodString;
|
|
27
|
+
name: z.ZodOptional<z.ZodString>;
|
|
28
|
+
status: z.ZodOptional<z.ZodUnion<[z.ZodEnum<{
|
|
29
|
+
sending: "sending";
|
|
30
|
+
draft: "draft";
|
|
31
|
+
scheduled: "scheduled";
|
|
32
|
+
queued: "queued";
|
|
33
|
+
sent: "sent";
|
|
34
|
+
cancelled: "cancelled";
|
|
35
|
+
failed: "failed";
|
|
36
|
+
}>, z.ZodString]>>;
|
|
37
|
+
audience_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
38
|
+
segment_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
39
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
40
|
+
updated_at: z.ZodOptional<z.ZodString>;
|
|
41
|
+
scheduled_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
42
|
+
sent_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
43
|
+
from: z.ZodOptional<z.ZodString>;
|
|
44
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
45
|
+
reply_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
46
|
+
preview_text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
47
|
+
html: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
48
|
+
text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
49
|
+
}, z.core.$loose>;
|
|
50
|
+
declare const createBroadcast: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
51
|
+
name: z.ZodOptional<z.ZodString>;
|
|
52
|
+
from: z.ZodOptional<z.ZodString>;
|
|
53
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
54
|
+
reply_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
55
|
+
preview_text: z.ZodOptional<z.ZodString>;
|
|
56
|
+
html: z.ZodOptional<z.ZodString>;
|
|
57
|
+
text: z.ZodOptional<z.ZodString>;
|
|
58
|
+
template: z.ZodOptional<z.ZodObject<{
|
|
59
|
+
id: z.ZodString;
|
|
60
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
|
61
|
+
}, z.core.$strip>>;
|
|
62
|
+
audience_id: z.ZodOptional<z.ZodString>;
|
|
63
|
+
segment_id: z.ZodOptional<z.ZodString>;
|
|
64
|
+
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
65
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
66
|
+
id: z.ZodString;
|
|
67
|
+
name: z.ZodOptional<z.ZodString>;
|
|
68
|
+
status: z.ZodOptional<z.ZodUnion<[z.ZodEnum<{
|
|
69
|
+
sending: "sending";
|
|
70
|
+
draft: "draft";
|
|
71
|
+
scheduled: "scheduled";
|
|
72
|
+
queued: "queued";
|
|
73
|
+
sent: "sent";
|
|
74
|
+
cancelled: "cancelled";
|
|
75
|
+
failed: "failed";
|
|
76
|
+
}>, z.ZodString]>>;
|
|
77
|
+
audience_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
78
|
+
segment_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
79
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
80
|
+
updated_at: z.ZodOptional<z.ZodString>;
|
|
81
|
+
scheduled_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
82
|
+
sent_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
83
|
+
from: z.ZodOptional<z.ZodString>;
|
|
84
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
85
|
+
reply_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
86
|
+
preview_text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
87
|
+
html: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
88
|
+
text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
89
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
90
|
+
RESEND_API_KEY: z.ZodString;
|
|
91
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
92
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
93
|
+
RESEND_API_KEY: z.ZodString;
|
|
94
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
95
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
96
|
+
declare const listBroadcasts: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
97
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
98
|
+
after: z.ZodOptional<z.ZodString>;
|
|
99
|
+
before: z.ZodOptional<z.ZodString>;
|
|
100
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
101
|
+
object: z.ZodLiteral<"list">;
|
|
102
|
+
has_more: z.ZodBoolean;
|
|
103
|
+
data: z.ZodArray<z.ZodObject<{
|
|
104
|
+
id: z.ZodString;
|
|
105
|
+
name: z.ZodOptional<z.ZodString>;
|
|
106
|
+
status: z.ZodOptional<z.ZodUnion<[z.ZodEnum<{
|
|
107
|
+
sending: "sending";
|
|
108
|
+
draft: "draft";
|
|
109
|
+
scheduled: "scheduled";
|
|
110
|
+
queued: "queued";
|
|
111
|
+
sent: "sent";
|
|
112
|
+
cancelled: "cancelled";
|
|
113
|
+
failed: "failed";
|
|
114
|
+
}>, z.ZodString]>>;
|
|
115
|
+
audience_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
116
|
+
segment_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
117
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
118
|
+
updated_at: z.ZodOptional<z.ZodString>;
|
|
119
|
+
scheduled_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
120
|
+
sent_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
121
|
+
}, z.core.$loose>>;
|
|
122
|
+
}, z.core.$strip>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
123
|
+
RESEND_API_KEY: z.ZodString;
|
|
124
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
125
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
126
|
+
RESEND_API_KEY: z.ZodString;
|
|
127
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
128
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
129
|
+
declare const retrieveBroadcast: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
130
|
+
id: z.ZodString;
|
|
131
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
132
|
+
id: z.ZodString;
|
|
133
|
+
name: z.ZodOptional<z.ZodString>;
|
|
134
|
+
status: z.ZodOptional<z.ZodUnion<[z.ZodEnum<{
|
|
135
|
+
sending: "sending";
|
|
136
|
+
draft: "draft";
|
|
137
|
+
scheduled: "scheduled";
|
|
138
|
+
queued: "queued";
|
|
139
|
+
sent: "sent";
|
|
140
|
+
cancelled: "cancelled";
|
|
141
|
+
failed: "failed";
|
|
142
|
+
}>, z.ZodString]>>;
|
|
143
|
+
audience_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
144
|
+
segment_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
145
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
146
|
+
updated_at: z.ZodOptional<z.ZodString>;
|
|
147
|
+
scheduled_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
148
|
+
sent_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
149
|
+
from: z.ZodOptional<z.ZodString>;
|
|
150
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
151
|
+
reply_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
152
|
+
preview_text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
153
|
+
html: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
154
|
+
text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
155
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
156
|
+
RESEND_API_KEY: z.ZodString;
|
|
157
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
158
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
159
|
+
RESEND_API_KEY: z.ZodString;
|
|
160
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
161
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
162
|
+
declare const updateBroadcast: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
163
|
+
id: z.ZodString;
|
|
164
|
+
name: z.ZodOptional<z.ZodString>;
|
|
165
|
+
from: z.ZodOptional<z.ZodString>;
|
|
166
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
167
|
+
reply_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
168
|
+
preview_text: z.ZodOptional<z.ZodString>;
|
|
169
|
+
html: z.ZodOptional<z.ZodString>;
|
|
170
|
+
text: z.ZodOptional<z.ZodString>;
|
|
171
|
+
template: z.ZodOptional<z.ZodObject<{
|
|
172
|
+
id: z.ZodString;
|
|
173
|
+
variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>;
|
|
174
|
+
}, z.core.$strip>>;
|
|
175
|
+
segment_id: z.ZodOptional<z.ZodString>;
|
|
176
|
+
audience_id: z.ZodOptional<z.ZodString>;
|
|
177
|
+
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
178
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
179
|
+
id: z.ZodString;
|
|
180
|
+
name: z.ZodOptional<z.ZodString>;
|
|
181
|
+
status: z.ZodOptional<z.ZodUnion<[z.ZodEnum<{
|
|
182
|
+
sending: "sending";
|
|
183
|
+
draft: "draft";
|
|
184
|
+
scheduled: "scheduled";
|
|
185
|
+
queued: "queued";
|
|
186
|
+
sent: "sent";
|
|
187
|
+
cancelled: "cancelled";
|
|
188
|
+
failed: "failed";
|
|
189
|
+
}>, z.ZodString]>>;
|
|
190
|
+
audience_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
191
|
+
segment_id: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
192
|
+
created_at: z.ZodOptional<z.ZodString>;
|
|
193
|
+
updated_at: z.ZodOptional<z.ZodString>;
|
|
194
|
+
scheduled_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
195
|
+
sent_at: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
196
|
+
from: z.ZodOptional<z.ZodString>;
|
|
197
|
+
subject: z.ZodOptional<z.ZodString>;
|
|
198
|
+
reply_to: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
199
|
+
preview_text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
200
|
+
html: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
201
|
+
text: z.ZodNullable<z.ZodOptional<z.ZodString>>;
|
|
202
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
203
|
+
RESEND_API_KEY: z.ZodString;
|
|
204
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
205
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
206
|
+
RESEND_API_KEY: z.ZodString;
|
|
207
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
208
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
209
|
+
declare const sendBroadcast: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
210
|
+
id: z.ZodString;
|
|
211
|
+
scheduled_at: z.ZodOptional<z.ZodString>;
|
|
212
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
213
|
+
id: z.ZodString;
|
|
214
|
+
object: z.ZodOptional<z.ZodLiteral<"broadcast">>;
|
|
215
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
216
|
+
RESEND_API_KEY: z.ZodString;
|
|
217
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
218
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
219
|
+
RESEND_API_KEY: z.ZodString;
|
|
220
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
221
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
222
|
+
declare const deleteBroadcast: _keystrokehq_core0.Operation<z.ZodObject<{
|
|
223
|
+
id: z.ZodString;
|
|
224
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
225
|
+
object: z.ZodOptional<z.ZodLiteral<"broadcast">>;
|
|
226
|
+
id: z.ZodString;
|
|
227
|
+
deleted: z.ZodOptional<z.ZodBoolean>;
|
|
228
|
+
}, z.core.$loose>, readonly [_keystrokehq_core0.CredentialSet<"resend", z.ZodObject<{
|
|
229
|
+
RESEND_API_KEY: z.ZodString;
|
|
230
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
231
|
+
}, z.core.$strip>, readonly _keystrokehq_core_credential_set0.CredentialConnection<z.ZodObject<{
|
|
232
|
+
RESEND_API_KEY: z.ZodString;
|
|
233
|
+
RESEND_WEBHOOK_SIGNING_SECRETS: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
234
|
+
}, z.core.$strip>>[] | undefined>], undefined>;
|
|
235
|
+
type ResendBroadcastSummary = z.infer<typeof broadcastSummarySchema>;
|
|
236
|
+
type ResendBroadcastDetail = z.infer<typeof broadcastDetailSchema>;
|
|
237
|
+
//#endregion
|
|
238
|
+
export { ResendBroadcastDetail, ResendBroadcastSummary, createBroadcast, deleteBroadcast, listBroadcasts, retrieveBroadcast, sendBroadcast, updateBroadcast };
|