How to add email automation to Odoo
Short answer
Odoo already turns inbound mail into records through mail aliases and incoming mail servers, so start there. For structured work such as customer POs, vendor RFQ replies and supplier confirmations, add a parsing service that reads the message, drafts the transaction through the external API and sends it to a review queue.
A lot of manufacturing order entry still arrives as email: customer purchase orders as PDFs, supplier acknowledgements in free text, RFQ replies with prices in a table. Someone retypes these into Odoo, which is slow and introduces mistakes.
Odoo has a good foundation for this. The mail gateway creates records from messages and keeps the thread on the record, and aliases let different inboxes land in different models. What it does not do on its own is understand the contents of an order PDF or a supplier's reply.
The practical design is a draft-and-review loop: parse, create a draft, flag low confidence fields, and let a person confirm. Anything that sends or confirms stays behind a human step.
What teams use it for
Customer PO to draft sales order
Read a customer purchase order from a shared mailbox, match the customer and products, and create a draft sale.order with the customer reference filled in.
RFQ reply capture
Parse supplier replies to a purchase RFQ, extract unit prices and lead times, and propose updates to the draft purchase.order lines.
Order acknowledgement matching
Read supplier confirmations, match to the PO by reference, and propose a new expected date on the receipt.
Vendor bill intake
Route emailed invoices to the vendor bill alias so a draft account.move is created, then check totals against the PO.
Customer service triage
Classify inbound email to the support alias into helpdesk categories and attach it to the right sale order or ticket.
Odoo integration surface
- Mail aliases (mail.alias) per model, so a sales@, purchase@ or bills@ address creates the right record type; Odoo's default alias handling is configured in settings and per team or journal.
- Incoming and outgoing mail servers (fetchmail.server and ir.mail_server), IMAP or POP, with OAuth for Microsoft 365 and Google on recent versions.
- message_new override: a custom module can override a model's message_new to parse the subject and body and set fields at creation.
- mail.message and mail.thread: the original email and attachments are stored as chatter and ir.attachment on the record.
- External API (XML-RPC, JSON-RPC, and a newer JSON-2 endpoint on recent versions) for an outside parser to create drafts and attach files.
How it works
- 1
Separate inboxes by intent
Use distinct addresses for customer POs, supplier replies and invoices so each has a known document type and parser.
- 2
Connect the mailbox
Configure an incoming server or alias with OAuth. Decide whether Odoo or an external service is the first reader of the mailbox.
- 3
Extract fields
Parse attachments and body text for customer reference, lines, quantities, prices and dates. Use rules for stable formats and a model for messy ones.
- 4
Match masters
Resolve customer to res.partner and items to product.product through customer part number maps (product.supplierinfo or custom fields). Unmatched items are flagged, never guessed.
- 5
Create drafts
Create draft sale.order or purchase.order records via the API with the source email linked in the chatter.
- 6
Review and confirm
Show the planner a diff between email and draft. They confirm in Odoo; confirmation is never automatic.
- 7
Learn from corrections
Record every correction as a mapping rule so repeat customers need less review.
Example flows
Emailed PO becomes a draft order
Trigger: A customer sends a PO PDF to the orders address.
- The parser extracts lines and the customer PO number.
- It maps the customer's part numbers to Odoo products.
- It creates a draft sale.order and attaches the PDF.
- Unmatched or low-confidence lines are highlighted for the planner.
Result: A planner reviews and confirms in a minute or two instead of retyping.
Supplier date update
Trigger: A supplier replies to a confirmed purchase order.
- The service finds the PO reference in the subject or body.
- It extracts the new ship date and quantity.
- It posts a proposed change to the PO chatter and notifies the buyer.
Result: The buyer approves the date change with the evidence in front of them.
Keeping data on-prem
Email automation is a natural fit for on-prem because the sensitive part, reading customer orders and supplier pricing, can run entirely inside your network. Odoo can run on your servers, the mailbox can be on Exchange or an internal IMAP server, and the parsing service can use an open-weight model on your own GPUs through vLLM or Ollama, so order content never goes to a public AI API. Use OAuth or app passwords scoped to the shared mailbox rather than a user's credentials. If the mailbox is Microsoft 365 or Gmail, the mail itself is already in a cloud, so decide whether only the parsing stays local. For ITAR or defense work, keep the parser in an enclave and restrict which mailboxes it can read.
Security checklist
- Use a dedicated mailbox identity with least privilege rather than a personal account.
- Treat attachments as untrusted: scan for malware and restrict file types before parsing.
- Guard against prompt injection in email text; the parser must never execute instructions found in a message.
- Keep draft creation separate from confirmation and require a named reviewer.
- Retain the original email on the record for audit and dispute resolution.
Ways to get it done
Odoo mail aliases and gateway
Effort: Hours to configure.
Simple intake where a person fills in the fields after the record is created.
In-house parser with the external API
Effort: Three to six weeks including review UI.
A few standard document types from known customers.
Partner build with Netray
Effort: Typically a few weeks per document family.
Messy multi-format inboxes and a private model for sensitive orders.
Pitfalls
- !Auto-confirming orders from email, which turns a parsing error into a shipped wrong order.
- !Customer part numbers that do not map to your internal items, silently matched to a similar product.
- !Reply-chain noise: parsing quoted earlier text and extracting stale values.
- !Mailbox rate limits and OAuth token expiry that stop intake without an alert.
- !Ignoring duplicate sends, so the same PO creates two orders.
Frequently asked questions
Can Odoo create sales orders from email out of the box?
Odoo can create a record from an incoming email through aliases, for example a lead or a draft order depending on the model and configuration, but it will not read line items from a PDF. Extracting products and quantities needs a custom parser or an OCR or AI service.
Where should the parsing run, inside Odoo or outside?
Simple rules can live in a message_new override in a custom module. Anything involving OCR or a language model is easier to maintain as an external service that calls the API, since it can be deployed and scaled separately and does not slow Odoo workers.
How do we prevent wrong orders?
Create only drafts, show confidence per field, never guess unmatched items, and require a person to confirm. Add duplicate detection on customer PO number and keep the source email attached so reviewers can compare quickly.
Does it work with Microsoft 365 mailboxes?
Yes. Recent Odoo versions support OAuth for Microsoft and Google mail servers. Alternatively an external service can read the mailbox through Graph and push drafts to Odoo, which also lets you use shared mailbox permissions. Confirm which option your Odoo version supports.
Can this handle multiple languages?
Yes if the parser uses a multilingual model. Rule-based parsers need per-language rules. Always test on real samples from each customer, because the layout of the attachment matters more than the language of the body.
Want Email automation working on your Odoo?
A free 30 minute assessment: we map the integration path for your version and setup, and where it should run.
Get a free assessment