Skip to content

Commit 63afca9

Browse files
committed
update readme
1 parent 9055507 commit 63afca9

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

readme.md

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,13 @@ pub fn main() !void {
5151
try smtp.send(.{
5252
.from = "admin@localhost",
5353
.to = &.{"user@localhost"},
54-
.data = "From: Admin <admin@localhost>\r\nTo: User <user@localhost>\r\nSubject: Test\r\n\r\nThis is karl, I'm testing a SMTP client for Zig\r\n.\r\n",
54+
.subject = "This is the Subject"
55+
.text_body = "This is the text body",
56+
.html_body = "<b>This is the html body</b>",
5557
}, config);
5658
}
5759
```
5860

59-
Note that the `data` field above must conform to [RFC 2822 - Internet Message Format](https://www.rfc-editor.org/rfc/rfc2822). Notably:
60-
* Lines have a maximum length of 1000 (including the trailing `\r\n`)
61-
* Any line that begins with a '.' must be escaped with a '.' (in regex talk: `s/^\./../`)
62-
* The message must be terminated with a `\r\n.\r\n` (yes, the dot in there is intentional)
63-
64-
I plan on adding some type of `builder` to help with generating a valid `data` payload.
65-
6661
## Encryption
6762
Prefer using `.encryption = .tls` where possible. Most modern email vendors provide SMTP over TLS and support TLS 1.3.
6863

@@ -75,7 +70,7 @@ Prefer using `.encryption = .tls` where possible. Most modern email vendors prov
7570
Regardless of the encryption setting, the library will favor authenticating via `CRAM-MD5` if the server supports it.
7671

7772
# Client
78-
The `send` and `sendAll` functions are wrappers around an `smtp.Client`. Where `send` and `sendAll` open a connection, send one or more messages and then close the connection, an `smtp.Client` keeps the connection open until `deinit` is called. The client is **not** thread safe.
73+
The `smtp.send` and `smtp.sendAll` functions are wrappers around an `smtp.Client`. Where `send` and `sendAll` open a connection, send one or more messages and then close the connection, an `smtp.Client` keeps the connection open until `deinit` is called. The client is **not** thread safe.
7974

8075
```zig
8176
var client = try smtp.connect({
@@ -92,15 +87,31 @@ try client.hello();
9287
try client.auth();
9388
9489
// Multiple messages can be sent here
95-
try client.from("[email protected]");
96-
try client.to(&.{"[email protected]"});
97-
try client.data("From: Admin <[email protected]>\r\nTo: User <[email protected]>\r\nSuject: Test\r\n\r\nThis is a test email from Zig\r\n.\r\n");
90+
try client.sendMessage(.{
91+
.subject = "This is the Subject"
92+
.text_body = "This is the text body",
93+
});
9894
99-
// One this is called, no more messages can be sent
95+
// Once this is called, no more messages can be sent
10096
try client.quit();
10197
```
10298

103-
`hello` and `auth` can be called upfront, while `from`, `to` and `data` can be called repeatedly (protected by a mutex if thread-safety is needed).
99+
`hello` and `auth` can be called upfront, while `from`, `to` and `sendMessage` can be called repeatedly. To make the Client thread safe, protect the call to `sendMessage` with a mutex.
100+
101+
# Message
102+
The `smtp.Message` which is passed to `smtp.send`, `smtp.sendAll` and `client.sendMessage` has the following fields:
103+
104+
* `from: Address` - The address the email is from
105+
* `to: []const Address` - A list of addresses to send the email to
106+
* `subject: ?[]const u8 = null` - The subject
107+
* `text_body: ?[]const u8 = null` - The Text body
108+
* `html_body: ?[]const u8 = null` - The HTML body
109+
110+
111+
The `timestamp: ?i64 = null` field can also be set. This is used when writing the `Date` header. By default `std.time.timestamp`. Only advance usage should set this.
112+
113+
As an alternative to setting the above fields, the `data: ?[]const u8 = null` field can be set. This is the complete raw data to send following the SMTP `DATA` command. When specified, the rest of the fields are ignored. The `data` must comform to [RFC 2822 - Internet Message Format](https://www.rfc-editor.org/rfc/rfc2822), including a trailing `\r\n.\r\n`. I realize that a union would normally be used to make `data` and the other fields mutually exclusive. However, the use of `data` is considered an advanced feature, and adding union simply makes the API more complicated for 99% of the cases which would not use it.
114+
104115

105116
## Performance
106117
### Tip 1 - sendAll
@@ -116,12 +127,14 @@ The `sendAll` function takes an array of `smtp.Message`. It is much more efficie
116127
.{
117128
.from = "...",
118129
.to = &.{"..."},
119-
.data = "...",
130+
.subject = "...",
131+
.text_body = "...",
120132
},
121133
.{
122134
.from = "...",
123135
.to = &.{"..."},
124-
.data = "...",
136+
.subject = "...",
137+
.text_body = "...",
125138
}
126139
};
127140
try smtp.sendAll(&messages, config, &sent);
@@ -147,7 +160,7 @@ var config = smtp.Config{
147160
.port = 25,
148161
.host = "localhost",
149162
.encryption = .tls,
150-
.ca_bundle = ca_bundle,
163+
.ca_bundle = ca_bundle,
151164
// ...
152165
};
153166
```

0 commit comments

Comments
 (0)