@t4h.framework/smtp 0.7.6 → 0.7.9
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 +67 -246
- package/CHANGELOG.md +16 -0
- package/README.md +22 -89
- package/package.json +2 -2
|
@@ -1,283 +1,104 @@
|
|
|
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 {
|
|
203
|
-
import { http } from '@t4h.framework/http'
|
|
32
|
+
import { Workflow } from '@t4h.framework/core'
|
|
204
33
|
import { Smtp } from '@t4h.framework/smtp'
|
|
205
34
|
import Type from 'typebox'
|
|
206
35
|
|
|
207
|
-
import { environments } from '
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
})
|
|
36
|
+
import { environments } from '../constants/environments.js'
|
|
37
|
+
|
|
38
|
+
export const sendReport = new Workflow(
|
|
39
|
+
{ id: 'send-report', schema: Type.Object({ email: Type.String() }) },
|
|
40
|
+
async input => {
|
|
41
|
+
const smtp = new Smtp(environments.SMTP_URL, {
|
|
42
|
+
from: 'noreply@example.com',
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const result = await smtp.send({
|
|
46
|
+
to: input.email,
|
|
47
|
+
subject: 'Report',
|
|
48
|
+
html: '<p>See attached.</p>',
|
|
49
|
+
attachments: [{ filename: 'report.pdf', content: reportBinary }],
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
return { messageId: result.messageId }
|
|
53
|
+
},
|
|
54
|
+
)
|
|
227
55
|
```
|
|
228
56
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
57
|
+
## Traps
|
|
58
|
+
|
|
59
|
+
- The method is `send`, on the client and on `SmtpSendEmailClaim`. There is no
|
|
60
|
+
`sendEmail`.
|
|
61
|
+
- `new Smtp(...)` takes a `Secret`. A string literal or a `String` env entry is
|
|
62
|
+
a type error.
|
|
63
|
+
- Create the client in the workflow body. A test that imports the module has
|
|
64
|
+
no env, so a key read at module top level throws `No env storage`.
|
|
65
|
+
- The body field is `html`. There is no `text` field.
|
|
66
|
+
- An attachment `content` is a `Binary` (from `sftp.get`, an HTTP body, `write`
|
|
67
|
+
of `@t4h.framework/fs`). Never build a `Binary` by hand; see the
|
|
68
|
+
`framework-fs` skill.
|
|
69
|
+
- A `from` in `send` wins over the client default. Without both, `from` is
|
|
70
|
+
`undefined` and the claim decides.
|
|
71
|
+
- `@t4h.framework/core/no-io-in-workflow` rejects `nodemailer` in a workflow.
|
|
72
|
+
Do not call an SMTP library; use `Smtp`.
|
|
73
|
+
- Do not `new` or `extend` `SmtpSendEmailActivity`
|
|
74
|
+
(`@t4h.framework/core/no-framework-activity-in-app`). Use `smtp.send`.
|
|
75
|
+
- The runtime must provide `SmtpSendEmailClaim`.
|
|
76
|
+
|
|
77
|
+
## Test
|
|
78
|
+
|
|
79
|
+
Mock `SmtpSendEmailClaim` with its `send` method. The mock receives the
|
|
80
|
+
normalized input: `to`, `cc` and `bcc` are always arrays.
|
|
241
81
|
|
|
242
82
|
```typescript
|
|
243
83
|
import { TestWorkflowEnvironment, mockClaim } from '@t4h.framework/core/testing'
|
|
244
84
|
import { SmtpSendEmailClaim } from '@t4h.framework/smtp'
|
|
85
|
+
import { expect, vi } from 'vitest'
|
|
245
86
|
|
|
246
|
-
const
|
|
87
|
+
const send = vi.fn().mockResolvedValue({ messageId: 'msg-123' })
|
|
247
88
|
|
|
248
89
|
const env = TestWorkflowEnvironment.create({ now: 0 })
|
|
249
90
|
|
|
250
91
|
await env.execute(workflow, input, {
|
|
251
|
-
claims: [mockClaim(SmtpSendEmailClaim, { send
|
|
252
|
-
env: {
|
|
92
|
+
claims: [mockClaim(SmtpSendEmailClaim, { send })],
|
|
93
|
+
env: { SMTP_URL: 'smtp://user:pass@smtp.example.com:587' },
|
|
253
94
|
})
|
|
254
95
|
|
|
255
|
-
|
|
256
|
-
expect(mockSend.mock.calls[0][0]).toMatchObject({
|
|
257
|
-
to: ['recipient@example.com'],
|
|
258
|
-
subject: 'Test',
|
|
259
|
-
html: '<p>Hello</p>',
|
|
260
|
-
})
|
|
96
|
+
expect(send.mock.calls[0][0]).toMatchObject({ to: ['recipient@example.com'] })
|
|
261
97
|
```
|
|
262
98
|
|
|
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`).
|
|
99
|
+
## Reference
|
|
282
100
|
|
|
283
|
-
|
|
101
|
+
- Guide: https://tech4humans-brasil.github.io/framework/smtp/
|
|
102
|
+
- Secrets: https://tech4humans-brasil.github.io/framework/core/environment
|
|
103
|
+
- Workflow testing: https://tech4humans-brasil.github.io/framework/core/testing
|
|
104
|
+
- Types: `node_modules/@t4h.framework/smtp/dist/smtp.d.ts`
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @t4h.framework/smtp
|
|
2
2
|
|
|
3
|
+
## 0.7.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#276](https://github.com/tech4humans-brasil/framework/pull/276) [`7b38934`](https://github.com/tech4humans-brasil/framework/commit/7b38934e8f9207c98c33afcd76e3a7a4da7e8b14) Thanks [@gusteycamargo](https://github.com/gusteycamargo)! - The `framework-smtp` skill creates the `Smtp` client in the workflow body. A
|
|
8
|
+
read of `environments` at the top of the module throws `No env storage`. The
|
|
9
|
+
test sample imports `expect` and `vi` from `vitest`.
|
|
10
|
+
|
|
11
|
+
## 0.7.8
|
|
12
|
+
|
|
13
|
+
## 0.7.7
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#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`.
|
|
18
|
+
|
|
3
19
|
## 0.7.6
|
|
4
20
|
|
|
5
21
|
### 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
|
-
}
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Activity
|
|
29
|
-
|
|
30
|
-
### SmtpSendEmailActivity
|
|
31
|
-
|
|
32
|
-
A `SyncActivity` that sends an email and returns a `SmtpSendEmailOutput`. Internally it uses `SmtpSendEmailClaim` to perform the delivery.
|
|
33
|
-
|
|
34
|
-
```typescript
|
|
35
|
-
import { SmtpSendEmailActivity } from '@t4h.framework/smtp'
|
|
8
|
+
```bash
|
|
9
|
+
npm install @t4h.framework/smtp
|
|
36
10
|
```
|
|
37
11
|
|
|
38
|
-
|
|
12
|
+
Peer dependency: `@t4h.framework/core`.
|
|
39
13
|
|
|
40
|
-
|
|
14
|
+
## Usage
|
|
41
15
|
|
|
42
|
-
|
|
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,27 @@ 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
|
|
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
|
-
```
|
|
71
|
-
|
|
72
|
-
### Default sender
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
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
|
|
34
|
+
const notify = new Workflow({ id: 'notify' }, async () => {
|
|
35
|
+
const smtp = new Smtp(environments.SMTP_URL, { from: 'noreply@example.com' })
|
|
87
36
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
subject: 'Team Update',
|
|
94
|
-
html: '<p>Weekly report attached.</p>',
|
|
95
|
-
})
|
|
96
|
-
```
|
|
37
|
+
const result = await smtp.send({
|
|
38
|
+
to: 'recipient@example.com',
|
|
39
|
+
subject: 'Hello',
|
|
40
|
+
html: '<p>Hello world</p>',
|
|
41
|
+
})
|
|
97
42
|
|
|
98
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
The `SmtpSendEmailOutput` object provides access to the sent message identifier:
|
|
47
|
+
Create the `Smtp` client in the workflow body. A test that imports the module
|
|
48
|
+
has no env, so a key read at module top level throws `No env storage`.
|
|
114
49
|
|
|
115
|
-
|
|
116
|
-
const result = await smtp.send({ ... })
|
|
50
|
+
## Documentation
|
|
117
51
|
|
|
118
|
-
|
|
119
|
-
```
|
|
52
|
+
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.9",
|
|
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.2",
|
|
37
37
|
"typescript": "^5.9.3",
|
|
38
38
|
"vitest": "^4.0.18"
|
|
39
39
|
},
|