@t4h.framework/smtp 0.7.6 → 0.7.7
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/.ai/skills/framework-smtp/SKILL.md +53 -244
- package/CHANGELOG.md +6 -0
- package/README.md +20 -90
- package/package.json +2 -2
|
@@ -1,283 +1,92 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: framework-smtp
|
|
3
3
|
description: >-
|
|
4
|
-
Guides
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
and
|
|
8
|
-
|
|
9
|
-
or
|
|
4
|
+
Guides the use of @t4h.framework/smtp to send email from a T4H Framework
|
|
5
|
+
workflow: the Smtp client and its send() method, the default from, to/cc/bcc
|
|
6
|
+
recipients, HTML bodies, Binary attachments, SmtpSendEmailOutput.messageId,
|
|
7
|
+
and how to test with TestWorkflowEnvironment and mockClaim of
|
|
8
|
+
SmtpSendEmailClaim. Use when a workflow must send an email, a notification
|
|
9
|
+
or a report with an attachment, or when someone asks for nodemailer, an SMTP
|
|
10
|
+
transport or an smtp:// connection string in a workflow.
|
|
10
11
|
---
|
|
11
12
|
|
|
12
13
|
# @t4h.framework/smtp
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## Send an email
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Smtp,
|
|
21
|
-
SmtpSendEmailActivity,
|
|
22
|
-
SmtpSendEmailClaim,
|
|
23
|
-
SmtpSendEmailOutput,
|
|
24
|
-
type SmtpOptions,
|
|
25
|
-
type SmtpSendEmailActivityOptions,
|
|
26
|
-
type SmtpSendEmailActivityInput,
|
|
27
|
-
type SmtpSendEmailActivityAttachment,
|
|
28
|
-
type ISmtpSendEmailOutput,
|
|
29
|
-
} from '@t4h.framework/smtp'
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Node `>=22`. See [README.md](../../../README.md) for a short overview (note: README may say `sendEmail` on the claim; the actual method is **`send`**).
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Architecture
|
|
37
|
-
|
|
38
|
-
`Workflow` → `Smtp.send` (`History.bind(SmtpSendEmailActivity)`) → `SmtpSendEmailActivity.toInput` / `run` → `SmtpSendEmailClaim.send` → `SmtpSendEmailOutput`.
|
|
39
|
-
|
|
40
|
-
```
|
|
41
|
-
┌─────────────┐ send() ┌────────────────────────┐ run() ┌─────────────────────┐
|
|
42
|
-
│ Smtp │ ──────────────► │ SmtpSendEmailActivity │ ────────────► │ SmtpSendEmailClaim │
|
|
43
|
-
│ (client) │ reconciler │ (SyncActivity) │ Claim.smtp │ (runtime impl) │
|
|
44
|
-
└─────────────┘ └────────────────────────┘ └─────────────────────┘
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
`@t4h.framework/core/no-io-in-workflow` rejects `nodemailer` and raw sockets in a workflow. Use `Smtp`.
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## SmtpSendEmailClaim (required for delivery)
|
|
52
|
-
|
|
53
|
-
Abstract dependency; the **runtime** must register a concrete implementation:
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
{ provide: SmtpSendEmailClaim, value: new MySmtpSendEmailClaimImpl() }
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Contract (from source):
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
abstract class SmtpSendEmailClaim {
|
|
63
|
-
abstract send(
|
|
64
|
-
input: SmtpSendEmailActivityInput,
|
|
65
|
-
): ISmtpSendEmailOutput | Promise<ISmtpSendEmailOutput>
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type ISmtpSendEmailOutput = { messageId: string }
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
`SmtpSendEmailActivity.run` passes the full **`SmtpSendEmailActivityInput`** payload to `claim.send` (sync or async).
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
## Send options and payload
|
|
76
|
-
|
|
77
|
-
The exported `SmtpSendEmailActivity` — driven by `smtp.send` or directly via
|
|
78
|
-
`History.reconciler(SmtpSendEmailActivity, smtp, content)` — is replay-safe and
|
|
79
|
-
delegates to `SmtpSendEmailClaim.send`, returning a `SmtpSendEmailOutput`. Its
|
|
80
|
-
input shapes:
|
|
81
|
-
|
|
82
|
-
### SmtpSendEmailActivityOptions (what `smtp.send` accepts)
|
|
83
|
-
|
|
84
|
-
| Field | Type | Required | Notes |
|
|
85
|
-
|-------|------|----------|-------|
|
|
86
|
-
| `to` | `string \| readonly string[]` | yes | Normalized to `readonly string[]` in input |
|
|
87
|
-
| `subject` | `string` | yes | |
|
|
88
|
-
| `html` | `string` | yes | HTML body |
|
|
89
|
-
| `from` | `string?` | no | Overrides `smtp.options.from` |
|
|
90
|
-
| `cc` | `string \| readonly string[]?` | no | String → single-element array |
|
|
91
|
-
| `bcc` | `string \| readonly string[]?` | no | String → single-element array |
|
|
92
|
-
| `attachments` | `readonly SmtpSendEmailActivityAttachment[]?` | no | Passed through unchanged |
|
|
93
|
-
|
|
94
|
-
### SmtpSendEmailActivityInput (claim / activity payload)
|
|
95
|
-
|
|
96
|
-
| Field | Type | Notes |
|
|
97
|
-
|-------|------|-------|
|
|
98
|
-
| `connectionString` | `Secret` | From `smtp.connectionString`; the host reads the value when it sends |
|
|
99
|
-
| `from` | `string?` | `content.from ?? smtp.options.from` |
|
|
100
|
-
| `to` | `readonly string[]` | Always an array after `toInput` |
|
|
101
|
-
| `cc` | `readonly string[]?` | Omitted if not set |
|
|
102
|
-
| `bcc` | `readonly string[]?` | Omitted if not set |
|
|
103
|
-
| `subject` | `string` | |
|
|
104
|
-
| `html` | `string` | |
|
|
105
|
-
| `attachments` | `readonly SmtpSendEmailActivityAttachment[]?` | |
|
|
106
|
-
|
|
107
|
-
### Attachments
|
|
108
|
-
|
|
109
|
-
```typescript
|
|
110
|
-
import type { Binary } from '@t4h.framework/core'
|
|
111
|
-
|
|
112
|
-
type SmtpSendEmailActivityAttachment = {
|
|
113
|
-
filename: string
|
|
114
|
-
content: Binary
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Use framework `Binary` instances (e.g. from an HTTP `response.body`).
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Smtp client
|
|
123
|
-
|
|
124
|
-
High-level API: holds `connectionString` and optional default `from`, extends `SerializableClass` for workflow persistence. `connectionString` is typed `Secret` (a string is a `tsc` error): pass the `EnvDesign` entry declared `type: Secret`, because the URL `smtp://user:pass@host:587` carries the password.
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
const smtp = new Smtp(environments.SMTP_URL, {
|
|
128
|
-
from: 'noreply@example.com',
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
const result = await smtp.send({
|
|
132
|
-
to: 'recipient@example.com',
|
|
133
|
-
subject: 'Hello',
|
|
134
|
-
html: '<p>Hello world</p>',
|
|
135
|
-
})
|
|
136
|
-
|
|
137
|
-
result.messageId // string — via SmtpSendEmailOutput
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
- `send(options)` returns a promise of `SmtpSendEmailOutput` when history/reconciler completes (same pattern as `http` client).
|
|
141
|
-
- Default `from`: set on `Smtp` constructor options; per-send `from` in `send()` wins over `smtp.options.from`.
|
|
142
|
-
- `toSerializable()` / `fromSerializable()` restore `connectionString` and `options` (see `Smtp.spec.ts`).
|
|
143
|
-
|
|
144
|
-
### Multiple recipients, cc, bcc
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
await smtp.send({
|
|
148
|
-
to: ['alice@example.com', 'bob@example.com'],
|
|
149
|
-
cc: 'manager@example.com',
|
|
150
|
-
bcc: ['audit@example.com'],
|
|
151
|
-
subject: 'Team Update',
|
|
152
|
-
html: '<p>Weekly report.</p>',
|
|
153
|
-
})
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Using the exported activity directly via `History.reconciler`
|
|
157
|
-
|
|
158
|
-
Prefer `smtp.send` in workflows. When you need the exported activity directly,
|
|
159
|
-
drive the **shipped** `SmtpSendEmailActivity` through `History.reconciler` — a
|
|
160
|
-
ready, replay-safe helper. `@t4h.framework/core/no-framework-activity-in-app` rejects `new` and `extends` on it:
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
import { History } from '@t4h.framework/core'
|
|
164
|
-
import { Smtp, SmtpSendEmailActivity } from '@t4h.framework/smtp'
|
|
165
|
-
|
|
166
|
-
const smtp = new Smtp(environments.SMTP_URL) // Secret
|
|
167
|
-
const result = await History.reconciler(SmtpSendEmailActivity, smtp, {
|
|
168
|
-
to: 'user@example.com',
|
|
169
|
-
subject: 'Subject',
|
|
170
|
-
html: '<p>Body</p>',
|
|
171
|
-
})
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## SmtpSendEmailOutput
|
|
177
|
-
|
|
178
|
-
```typescript
|
|
179
|
-
class SmtpSendEmailOutput {
|
|
180
|
-
constructor(public readonly raw: ISmtpSendEmailOutput)
|
|
181
|
-
get messageId(): string
|
|
182
|
-
}
|
|
183
|
-
```
|
|
184
|
-
|
|
185
|
-
Activity and `Smtp.send` surface this type, not the raw `{ messageId }` object.
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## Workflow example
|
|
17
|
+
1. Declare the connection string as a `Secret` in the `EnvDesign` in
|
|
18
|
+
`src/constants/environments.ts`. The URL (`smtp://user:pass@host:587`)
|
|
19
|
+
carries the password.
|
|
20
|
+
2. Create one `Smtp` client and call `send` in the workflow body.
|
|
190
21
|
|
|
191
22
|
```typescript
|
|
192
23
|
// src/constants/environments.ts
|
|
193
24
|
import { EnvDesign, Secret } from '@t4h.framework/core'
|
|
194
25
|
|
|
195
26
|
export const environments = EnvDesign({
|
|
196
|
-
|
|
197
|
-
SMTP_FROM: { type: String },
|
|
27
|
+
SMTP_URL: { type: Secret },
|
|
198
28
|
})
|
|
199
29
|
```
|
|
200
30
|
|
|
201
31
|
```typescript
|
|
202
|
-
import { App, Workflow } from '@t4h.framework/core'
|
|
203
|
-
import { http } from '@t4h.framework/http'
|
|
204
32
|
import { Smtp } from '@t4h.framework/smtp'
|
|
205
|
-
import Type from 'typebox'
|
|
206
33
|
|
|
207
|
-
import { environments } from '
|
|
34
|
+
import { environments } from '../constants/environments.js'
|
|
208
35
|
|
|
209
|
-
const smtp = new Smtp(environments.
|
|
36
|
+
const smtp = new Smtp(environments.SMTP_URL, { from: 'noreply@example.com' })
|
|
210
37
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
await smtp.send({
|
|
218
|
-
from: environments.SMTP_FROM,
|
|
219
|
-
to: input,
|
|
220
|
-
subject: 'Hello World!',
|
|
221
|
-
html: '<p>...</p>',
|
|
222
|
-
attachments: [{ filename: 'image.png', content: response.body.binary }],
|
|
223
|
-
})
|
|
224
|
-
}),
|
|
225
|
-
],
|
|
38
|
+
const result = await smtp.send({
|
|
39
|
+
to: input.email,
|
|
40
|
+
subject: 'Report',
|
|
41
|
+
html: '<p>See attached.</p>',
|
|
42
|
+
attachments: [{ filename: 'report.pdf', content: reportBinary }],
|
|
226
43
|
})
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
Connection strings are opaque to the package; dev implementation expects URL form with credentials in the authority (e.g. `smtp://user:pass@host:587`, `smtps://...`).
|
|
230
|
-
|
|
231
|
-
---
|
|
232
|
-
|
|
233
|
-
## Testing
|
|
234
44
|
|
|
235
|
-
|
|
45
|
+
result.messageId
|
|
46
|
+
```
|
|
236
47
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
48
|
+
## Traps
|
|
49
|
+
|
|
50
|
+
- The method is `send`, on the client and on `SmtpSendEmailClaim`. There is no
|
|
51
|
+
`sendEmail`.
|
|
52
|
+
- `new Smtp(...)` takes a `Secret`. A string literal or a `String` env entry is
|
|
53
|
+
a type error.
|
|
54
|
+
- The body field is `html`. There is no `text` field.
|
|
55
|
+
- An attachment `content` is a `Binary` (from `sftp.get`, an HTTP body, `write`
|
|
56
|
+
of `@t4h.framework/fs`). Never build a `Binary` by hand; see the
|
|
57
|
+
`framework-fs` skill.
|
|
58
|
+
- A `from` in `send` wins over the client default. Without both, `from` is
|
|
59
|
+
`undefined` and the claim decides.
|
|
60
|
+
- `@t4h.framework/core/no-io-in-workflow` rejects `nodemailer` in a workflow.
|
|
61
|
+
Do not call an SMTP library; use `Smtp`.
|
|
62
|
+
- Do not `new` or `extend` `SmtpSendEmailActivity`
|
|
63
|
+
(`@t4h.framework/core/no-framework-activity-in-app`). Use `smtp.send`.
|
|
64
|
+
- The runtime must provide `SmtpSendEmailClaim`.
|
|
65
|
+
|
|
66
|
+
## Test
|
|
67
|
+
|
|
68
|
+
Mock `SmtpSendEmailClaim` with its `send` method. The mock receives the
|
|
69
|
+
normalized input: `to`, `cc` and `bcc` are always arrays.
|
|
241
70
|
|
|
242
71
|
```typescript
|
|
243
72
|
import { TestWorkflowEnvironment, mockClaim } from '@t4h.framework/core/testing'
|
|
244
73
|
import { SmtpSendEmailClaim } from '@t4h.framework/smtp'
|
|
245
74
|
|
|
246
|
-
const
|
|
75
|
+
const send = vi.fn().mockResolvedValue({ messageId: 'msg-123' })
|
|
247
76
|
|
|
248
77
|
const env = TestWorkflowEnvironment.create({ now: 0 })
|
|
249
78
|
|
|
250
79
|
await env.execute(workflow, input, {
|
|
251
|
-
claims: [mockClaim(SmtpSendEmailClaim, { send
|
|
252
|
-
env: {
|
|
80
|
+
claims: [mockClaim(SmtpSendEmailClaim, { send })],
|
|
81
|
+
env: { SMTP_URL: 'smtp://user:pass@smtp.example.com:587' },
|
|
253
82
|
})
|
|
254
83
|
|
|
255
|
-
|
|
256
|
-
expect(mockSend.mock.calls[0][0]).toMatchObject({
|
|
257
|
-
to: ['recipient@example.com'],
|
|
258
|
-
subject: 'Test',
|
|
259
|
-
html: '<p>Hello</p>',
|
|
260
|
-
})
|
|
84
|
+
expect(send.mock.calls[0][0]).toMatchObject({ to: ['recipient@example.com'] })
|
|
261
85
|
```
|
|
262
86
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
## Implementing SmtpSendEmailClaim
|
|
266
|
-
|
|
267
|
-
1. Subclass `SmtpSendEmailClaim` and implement **`send(input: SmtpSendEmailActivityInput)`**.
|
|
268
|
-
2. Read `connectionString`, `from`, `to`, `cc`, `bcc`, `subject`, `html`, `attachments` from `input` (arrays already normalized).
|
|
269
|
-
3. Return `{ messageId: string }` (or a Promise thereof). `messageId` is what workflows expose via `SmtpSendEmailOutput.messageId`.
|
|
270
|
-
4. For attachments, consume `Binary` via `.stream()`, `.contentType`, etc.
|
|
271
|
-
5. Register: `{ provide: SmtpSendEmailClaim, value: new MyClaim() }`.
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Checklist for agents
|
|
276
|
-
|
|
277
|
-
1. In workflows, use **`Smtp` + `smtp.send()`** (or `History.reconciler` with the exported `SmtpSendEmailActivity`).
|
|
278
|
-
2. Ensure runtime provides **`SmtpSendEmailClaim`** (or a mock in tests).
|
|
279
|
-
3. Set default **`from`** on `new Smtp(connectionString, { from })` or per-send; per-send wins.
|
|
280
|
-
4. Test workflows with **`TestWorkflowEnvironment`** + **`mockClaim(SmtpSendEmailClaim, { send })`**; assert on the mock's `mock.calls`.
|
|
281
|
-
5. For core workflow/reconciler concepts, use the **framework-core** skill (`@t4h.framework/core`).
|
|
87
|
+
## Reference
|
|
282
88
|
|
|
283
|
-
|
|
89
|
+
- Guide: https://tech4humans-brasil.github.io/framework/smtp/
|
|
90
|
+
- Secrets: https://tech4humans-brasil.github.io/framework/core/environment
|
|
91
|
+
- Workflow testing: https://tech4humans-brasil.github.io/framework/core/testing
|
|
92
|
+
- Types: `node_modules/@t4h.framework/smtp/dist/smtp.d.ts`
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @t4h.framework/smtp
|
|
2
2
|
|
|
3
|
+
## 0.7.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#257](https://github.com/tech4humans-brasil/framework/pull/257) [`586bfb4`](https://github.com/tech4humans-brasil/framework/commit/586bfb4663f4a478527ee0c8db360603f034d615) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - The smtp README is now short and links to the site. The docs page now has the testing and runtime sections, and the README no longer names a `sendEmail` claim method: the method is `send`.
|
|
8
|
+
|
|
3
9
|
## 0.7.6
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -1,47 +1,20 @@
|
|
|
1
1
|
# @t4h.framework/smtp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Sends email from a T4H Framework workflow. Each send is a durable step, so a
|
|
4
|
+
replay does not send the message again.
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## Install
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Abstract dependency for sending emails via SMTP. The runtime must provide a concrete implementation.
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
import { SmtpSendEmailClaim } from '@t4h.framework/smtp'
|
|
13
|
-
|
|
14
|
-
// the runtime provides this:
|
|
15
|
-
// { provide: SmtpSendEmailClaim, value: new MySmtpSendEmailClaimImpl() }
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
### Interface
|
|
19
|
-
|
|
20
|
-
```typescript
|
|
21
|
-
abstract class SmtpSendEmailClaim {
|
|
22
|
-
public abstract sendEmail(
|
|
23
|
-
input: SmtpSendEmailActivityInput,
|
|
24
|
-
): ISmtpSendEmailOutput | Promise<ISmtpSendEmailOutput>
|
|
25
|
-
}
|
|
8
|
+
```bash
|
|
9
|
+
npm install @t4h.framework/smtp
|
|
26
10
|
```
|
|
27
11
|
|
|
28
|
-
|
|
12
|
+
Peer dependency: `@t4h.framework/core`.
|
|
29
13
|
|
|
30
|
-
|
|
14
|
+
## Usage
|
|
31
15
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { SmtpSendEmailActivity } from '@t4h.framework/smtp'
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
## Smtp
|
|
39
|
-
|
|
40
|
-
High-level SMTP client that wraps `SmtpSendEmailActivity` behind a simple API. Instantiated with a connection string and optional defaults.
|
|
41
|
-
|
|
42
|
-
### Basic usage
|
|
43
|
-
|
|
44
|
-
The connection string `smtp://user:pass@host:587` carries the password, so the constructor takes a `Secret` and `tsc` rejects a string. Declare it with `type: Secret` in the `EnvDesign` in `src/constants/environments.ts`:
|
|
16
|
+
The connection string carries the password, so declare it with
|
|
17
|
+
`type: Secret` in the `EnvDesign` in `src/constants/environments.ts`:
|
|
45
18
|
|
|
46
19
|
```typescript
|
|
47
20
|
// src/constants/environments.ts
|
|
@@ -53,67 +26,24 @@ export const environments = EnvDesign({
|
|
|
53
26
|
```
|
|
54
27
|
|
|
55
28
|
```typescript
|
|
29
|
+
import { Workflow } from '@t4h.framework/core'
|
|
56
30
|
import { Smtp } from '@t4h.framework/smtp'
|
|
57
31
|
|
|
58
32
|
import { environments } from './constants/environments.js'
|
|
59
33
|
|
|
60
|
-
const smtp = new Smtp(environments.SMTP_URL)
|
|
61
|
-
|
|
62
|
-
const result = await smtp.send({
|
|
63
|
-
from: 'noreply@example.com',
|
|
64
|
-
to: 'recipient@example.com',
|
|
65
|
-
subject: 'Hello',
|
|
66
|
-
html: '<p>Hello world</p>',
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
result.messageId // string
|
|
70
|
-
```
|
|
34
|
+
const smtp = new Smtp(environments.SMTP_URL, { from: 'noreply@example.com' })
|
|
71
35
|
|
|
72
|
-
|
|
36
|
+
const notify = new Workflow({ id: 'notify' }, async () => {
|
|
37
|
+
const result = await smtp.send({
|
|
38
|
+
to: 'recipient@example.com',
|
|
39
|
+
subject: 'Hello',
|
|
40
|
+
html: '<p>Hello world</p>',
|
|
41
|
+
})
|
|
73
42
|
|
|
74
|
-
|
|
75
|
-
const smtp = new Smtp(environments.SMTP_URL, {
|
|
76
|
-
from: 'noreply@example.com',
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
const result = await smtp.send({
|
|
80
|
-
to: 'recipient@example.com',
|
|
81
|
-
subject: 'Hello',
|
|
82
|
-
html: '<p>Hello world</p>',
|
|
83
|
-
})
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
### Multiple recipients, cc, and bcc
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
const result = await smtp.send({
|
|
90
|
-
to: ['alice@example.com', 'bob@example.com'],
|
|
91
|
-
cc: 'manager@example.com',
|
|
92
|
-
bcc: ['audit@example.com'],
|
|
93
|
-
subject: 'Team Update',
|
|
94
|
-
html: '<p>Weekly report attached.</p>',
|
|
95
|
-
})
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
### Attachments
|
|
99
|
-
|
|
100
|
-
```typescript
|
|
101
|
-
import type { Binary } from '@t4h.framework/core'
|
|
102
|
-
|
|
103
|
-
const result = await smtp.send({
|
|
104
|
-
to: 'recipient@example.com',
|
|
105
|
-
subject: 'Report',
|
|
106
|
-
html: '<p>See attached.</p>',
|
|
107
|
-
attachments: [attachment],
|
|
43
|
+
return { messageId: result.messageId }
|
|
108
44
|
})
|
|
109
45
|
```
|
|
110
46
|
|
|
111
|
-
##
|
|
47
|
+
## Documentation
|
|
112
48
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
const result = await smtp.send({ ... })
|
|
117
|
-
|
|
118
|
-
result.messageId // string — the message ID returned by the SMTP server
|
|
119
|
-
```
|
|
49
|
+
https://tech4humans-brasil.github.io/framework/smtp/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@t4h.framework/smtp",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
4
4
|
"description": "SMTP module for the T4H Framework",
|
|
5
5
|
"homepage": "https://github.com/tech4humans-brasil/framework/tree/main/packages/smtp",
|
|
6
6
|
"bugs": "https://github.com/tech4humans-brasil/framework/issues",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"test:watch": "vitest"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@t4h.framework/core": "^0.
|
|
36
|
+
"@t4h.framework/core": "^0.21.0",
|
|
37
37
|
"typescript": "^5.9.3",
|
|
38
38
|
"vitest": "^4.0.18"
|
|
39
39
|
},
|