The Mail class
cs.bspkComponent.Mail sends an e-mail through SMTP, Microsoft 365 or Gmail. The server is read from the parameter files, the body can come from an HTML template, attachments are handled, and recipients are automatically redirected on development and pre-production machines.
Sending a mail
var $Mail : cs.bspkComponent.Mail
var $vo_Status : Object
$Mail:=cs.bspkComponent.Mail.new("Your order"; ""; $vt_Email) // subject; message; recipient
$Mail.setMessageFromTpl("orderConfirmed.html"; {firstName: $User.firstName; ref: $Order.ref})
$Mail.addAttachements($vt_PdfPath; "Invoice.pdf")
$vo_Status:=$Mail.send()
If ($vo_Status=Null) || (Not(Bool($vo_Status.success)))
// not sent
End if
The three constructor parameters are optional.
Configuration
The class reads Storage.vo_Param, that is, the parameter files:
| Key | Role |
|---|---|
vo_Mail.vt_Host, vl_Port, vt_User, vt_Password | The SMTP server. |
vo_Mail.vt_Forwarder | The default sender. |
vo_Mail.vb_AcceptUnsecureConnection | Accept an unencrypted connection. |
vo_MS365OAuth2: vt_ClientId (required), vt_ClientSecret, vt_Tenant (common), vt_Permission (service), vt_Scope, vt_RedirectURI, vt_UserId | Sending through Microsoft 365 (Graph, via 4D NetKit). In service mode without a client secret, the class falls back to SMTP. The sending mailbox is vt_UserId, otherwise the sender. |
vo_GoogleOAuth2: clientId (required), clientSecret, redirectURI, scope (gmail.send), accessType (offline), name, permission (signedIn) — no vt_ prefix | Sending through Gmail. Needs a token already obtained and stored: the Google authorisation flow is not provided by the component. |
vt_RedirectMail, vo_RedirectMapping | Redirection, below. |
setServer($host; $port; $user; $password), setOAuth2($obj) and setOAuth2Google($obj) replace this configuration for one instance.
Always fill in
vo_Mail. Without it, the class falls back on default settings that are not your application's.
Functions
| Function | What it does |
|---|---|
setSubject($text) | Replaces the subject. In DEV mode, the [DEV] prefix is added. |
setMessage($text) | The same text as text body and HTML body. |
setMessageFromTpl($path; $params; $lang) | The HTML body from a template, below. |
setRecipient($address) | Replaces the recipient. Spaces are removed; the address must be valid (several addresses separated by , or ;). |
setRecipients($collection) | Adds recipients. |
setCC($textOrCollection), setBcc(…) | Add copies; an invalid address is skipped silently. |
setReplyTo($address) | Ignored if the address is invalid. |
setFrom($address) | Empty or invalid: vo_Mail.vt_Forwarder. |
addAttachements($doc; $name; $cid; $type; $disposition) | Spelled Attachements. A text is the path of an existing document (skipped otherwise). $cid and "inline" for an image shown in the HTML. |
setLogFile($path) | The file must already exist. |
send() → Object | Gmail if configured, otherwise Microsoft 365 if configured, otherwise SMTP. Returns the status (success, status, statusText). Returns Null when something required is missing: server, subject, body, recipient or sender. |
Templates
setMessageFromTpl("orderConfirmed"; $params; "en"):
.htmlis added if the name has no.htmlor.htmextension, and the path is looked up underMail/in your project's web folder (usuallyBWEB/Mail/orderConfirmed.html).- The template goes through
PROCESS 4D TAGS: inside the template, the parameter object is$1(<!--#4DTEXT $1.firstName--> : Indéfinie). - The language (
"en") replaces the process language during processing, for the template's translations — only if a language is already set, that is, in a web request. In a worker or a scheduled task it is ignored.
Template not found: the body is empty, with no error, and the send still succeeds. Check the path.
Redirection in development and pre-production
In DEV or PREPROD mode only (see Parameter files), setRecipient and setRecipients send to:
vo_RedirectMapping[<machine name>], one address per machine; otherwisevt_RedirectMail, if not empty; otherwise- nobody else: the real recipient.
The subject then reads [REDIRECTION DEV MODE][<original recipient>] ….
- Copies (
setCC,setBcc) are never redirected. On a development machine working on real data, a copy to a customer reaches the customer. - Call
setSubjectbeforesetRecipient:setSubjectreplaces the subject and wipes the redirection mark. The constructor calls them in the right order.
When sending fails
Through SMTP or Microsoft 365, a failure triggers an error report sent to the error mail address. Through Gmail, no report: read the returned status.
Good to know
- With Microsoft 365, an attachment must be a path (text), a BLOB or a picture: a
4D.Fileobject is skipped. BSPK_EMAIL_Validate_Addresses($text)returns true if every address (separated by,or;) is valid. An empty text returns true.

