pyvelm v0.13.0¶
Release date: 2026-05-27
A first-class email composer with templates, multi-recipient
To / Cc / Bcc, Reply-To, attachments, and Save as template —
launched from any MailThread record's chatter or
programmatically.
Highlights¶
Multi-recipient outgoing mail¶
mail.message gains recipient_cc, recipient_bcc, and reply_to
columns. recipient_email now accepts comma- or semicolon-separated
addresses. The SmtpBackend / ConsoleBackend / MailBackend
protocol pass cc / bcc / reply-to through, and the dispatcher
pre-fetches ir.attachment rows linked to each message and adds
them as MIME parts.
record.send_mail(
template,
to="ops@acme.example, billing@acme.example",
cc="watch@acme.example",
bcc="audit@acme.example",
reply_to="noreply@acme.example",
attachment_ids=[att.id],
)
record.notify(
"Account closed.",
recipient_email="ops@acme.example",
cc="manager@acme.example",
)
Base bumped to 0.27.0 (migration 0_26_to_0_27.py is a
breadcrumb — schema autogen adds the new nullable columns).
mail_compose module¶
New bundled module, depends on base + admin. Ships:
mail.compose.message— the draft record. Methods:launch(env, *, model, res_id, template_id, recipient_to),action_apply_template(),action_send(),action_save_as_template(name=...).- Form + drafts list views and a Workflows → Compose drafts menu entry.
- HTTP endpoints:
/web/mail/compose/launch?model=&res_id=&template_id=,/web/mail/compose/{id}/apply-template,/web/mail/compose/{id}/save-as-template,/web/mail/compose/{id}/send.
Composer behaviour:
- Auto-resolved To. Scans the bound record for
email/email_from/contact_email/work_email/login, then a short list of one-hop Many2one paths (partner_id.email,user_id.email,user_id.login,author_id.login,contact_id.email). First non-empty wins. - Templated render. Picking a template + clicking Apply
template runs the template's Jinja against
object = <record>and overwrites subject + body, leaving the operator free to edit. - Save as template. Clones current subject + body into a new
mail.templatebound to the same model. The composer's current subject is used as the template name (operators rename afterwards). - Attachments picker — Many2many to
ir.attachmentusing the existing dialog widget.
Chatter integration¶
For any record whose model inherits MailThread, the chatter
panel's Send email tab now surfaces Open rich composer
(templates, Cc/Bcc, attachments) →, which launches the composer in
the existing floating PvDialog.
Form header_actions in edit mode¶
Form-view header action buttons (Apply template, Save as
template, Send, etc.) now render in edit mode in addition to
display. They hx-include the surrounding form fields, so the
action endpoint sees the operator's in-flight edits — no extra Save
click required.
Upgrade¶
pyvelm db migrate— applies base 0.26.0 → 0.27.0 (schema autogen adds the three new columns tomail.message).- Apps → Install
mail_compose(depends onadmin). Or include the module root if you bootloader.load_and_installyourself;BUILTIN_MODULE_ROOTSalready covers it. - Apps → Sync any module that already had a chatter-bearing
model — the Open rich composer link appears once
mail.compose.messageis in the registry. - Hard-refresh the browser so the chatter template reload picks up the new link.
If you installed mail_compose 0.1.0 between dev builds, the bump
to 0.1.1 drops the NOT NULL on recipient_to via migration
0_1_0_to_0_1_1.py so draft launches stop failing when the
auto-resolver finds nothing.
Also in this release¶
mail_composecross-module menu parent uses the tuple formparent=("admin", "workflows")so the loader resolves to the admin-owned group.MailThread._send_rendered_mailandMailThread.notifynow forwardcc/bcc/reply_toto the message row, so programmatic posts get the same multi-recipient semantics as the composer.