In short:
- An outreach campaign held in a spreadsheet always ends the same way: nobody knows who is left to call.
- The idea behind the module: the cadence becomes a rule of the campaign, not a discipline each person carries in their head.
- In Canada, email and phone calls are not governed by the same law. Both require you to keep a do-not-contact list, on different deadlines: ten business days on one side, fourteen on the other.
- A refusal travels, blocks sending, and keeps the proof: who recorded it, when, and in whose words.
- Replies received, calls placed and bookings made record themselves.
- Free software, LGPL-3, on your own Odoo Community.
Open the spreadsheet from your last outreach campaign. There is a "call back when?" column, filled in by hand, with dates in whatever format the typist felt like. A few rows down, an empty cell nobody has looked at in six weeks. And somewhere in the list, a contact your colleague rang on Tuesday without noting it, because they were on the road.
This is not a discipline problem. It is a tooling problem: a spreadsheet does not know a follow-up is due. It waits to be told.
The spreadsheet that decides for you
An outreach campaign is three things at once: a list, a rhythm and a memory. The spreadsheet handles the list well. It handles neither the rhythm nor the memory.
The rhythm first. You decide up front to call three times and write twice, a week apart. Nobody argues with the plan. But nothing in the file says, on a Tuesday morning, who is due today. So the follow-up depends on whoever thinks of it, and the lukewarm files, the ones that say neither yes nor no, go quiet and die.
The memory next. The refusal. Someone tells you to stop contacting them, you note it in the "status" column, and two months later they come back in the next imported list because the new list knows nothing of the old one. That is not merely awkward. In Canada, it is a breach.
The idea behind it: cadence as a rule
The outreach module we built for Odoo starts from a simple principle: the cadence belongs to the campaign, not to the person dialling the number.
So each campaign carries a quota and an interval for each of the three channels: how many calls per target and at what pace, how many emails, how many letters. You set that once, at the start.
From there, each file works out its own next contact date. A logged call pushes the next one back by the interval you set. Once the quota is met the channel goes quiet and the next one takes over. A follow-up that would land on a Saturday moves to the Monday, if you want it to. And the moment someone replies they leave the automatic cadence: the follow-up turns human again, which is rather the point.
That leaves the question of what counts as a reply. Five interaction outcomes do the job: person reached, reply received, interest expressed, callback requested, and refusal. A "no" stops the cadence just as a "yes" does, which is the right way to treat a "no".
One design choice worth flagging: these dates are computed and then stored, never recalculated at the moment you happen to open the screen. An "overdue" list that does not depend on when you look at it is a list you can trust, sort and export. The campaign counters do the opposite: they recompute on display, because a frozen reply rate would be wrong from the first interaction of the day.
What changes on a Tuesday morning
You open the app and the first thing you see is "due today". Not the full list. Not a table to sort. The files that are due, each with the kind of contact expected.
Beside it, an "overdue" list that flatters nobody, and a "never contacted" list that tells you how much of the campaign has not been worked yet. The kanban board shows where each file stands, across six stages running from "To contact" through to "Converted" or "Not retained", by way of "In discussion" and "Meeting booked". The first logged contact moves the target out of the "To contact" column without anyone having to drag it.
On the campaign side, the indicators recompute on their own: coverage, meaning the share of the list actually worked, the reply rate among the people you contacted, the conversion rate, and progress against the contacts the cadence plans for. You no longer have to add anything up to know whether the campaign is moving.
Each record also keeps the full history: every call, every email, every letter, with its outcome and its duration. Seven interaction types can be logged, including text messages, meetings and LinkedIn messages. Those three count in the history and in the coverage figure, without entering the cadence of the three channels you set at the start.
When the answer is "call me back in September"
Most files do not die. They sleep. And that is precisely what a spreadsheet cannot represent: a cell either holds a date or it is empty, there is no third state.
Two settings handle this case. A "do not follow up before" date pushes the cadence back without closing the file, and the wizard used to log a call lets you set it in passing, in days, while the conversation is still fresh. The target disappears from the day's lists and comes back on its own when the time comes, with its cadence intact.
When a file closes for good, a closing reason is asked for: converted, not interested, never reached, bad timing, invalid contact details, already served elsewhere, other. Seven boxes, chosen so they can be ticked in a second. At the end of a campaign they answer a question few businesses can document: are we losing because the offer does not land, or because we never managed to speak to anyone? Those two problems are not fixed the same way at all.
Email and phone are not governed by the same law
This is the part we treated most seriously, because it is the one that costs money when it is done badly. It is also the part where most teams get it wrong, by assuming a single regime covers the whole campaign.
Canada's anti-spam legislation governs commercial electronic messages: email, text messages, instant messaging. It says nothing about telephone calls. Outreach by phone falls under a different body of rules, the Unsolicited Telecommunications Rules, administered by the same regulator but built differently.
On the email side
| The obligation | What it means | What the module does about it |
|---|---|---|
| Consent, express or implied | Implied consent covers, among other things, an existing business relationship: two years after a purchase or a contract, but only six months after a simple enquiry. A published business address counts too, on two conditions: nothing beside it says the person does not want to be solicited, and the message is relevant to their role. | Nothing: the basis for the first message stays your decision, not a piece of software's. |
| Identify yourself in the message | Your name and contact details, including a mailing address valid for at least sixty days. | The campaign's email template, written once and reused. |
| An unsubscribe mechanism | A simple way, in every message, to ask you to stop. | A refusal is recorded in two clicks, whatever channel it arrives through. |
| Honour the withdrawal within ten business days | Past that deadline, each message is a separate violation. | The exclusion takes effect at once, and it is dated. |
On the phone side
Many small businesses do not realise this: a company that calls only other businesses is exempt from the part of the rules that imposes the National Do Not Call List. No subscription to pay for, no national list to reload every month.
The exemption stops there, and it is often misread on one detail: it covers the subscription, not the registration. Every telemarketer must register with the administrator of the national list, exempt or not. It is free and it is done once. The rest of the telemarketing rules apply as well, and they contain the obligation closest to our subject.
| The rule | What it requires |
|---|---|
| Your own do-not-call list | The number of anyone asking not to be called again must be added within fourteen days, and stay there for three years and fourteen days. |
| Calling hours | 9 a.m. to 9:30 p.m. on weekdays, 10 a.m. to 6 p.m. at the weekend, in the called person's local time. |
| Identification | Give the name of the person calling and of the business they are calling for, and display a reachable number, valid for at least sixty days after the call. |
The module's exclusion register does exactly the work of that internal list, with the date and the person who recorded the request. It does not do the other two: it consults no national list and it will not stop you dialling a number at 10 p.m. Those two points stay with the team, and they are worth saying out loud when the cadence is being built.
The penalties, in real numbers
The maximum administrative monetary penalties set the tone: one million dollars for an individual, ten million for a business, per violation. Those are ceilings, and nobody wakes up to a ten million dollar fine over one email too many. The real figures are more instructive.
Over the six months from April to September 2025, the Spam Reporting Centre received 152,603 complaints, an average of 5,869 a week. The regulator issued 153 notices to produce, 123 warning letters, a single notice of violation and one penalty of $50,000. In other words: a great many complaints, few penalties, and above all letters asking for explanations.
The most telling case remains the undertaking signed by Hudson's Bay Company in June 2024: $120,000, for promotional messages sent between January 2022 and November 2023 whose unsubscribe mechanism could not be readily carried out. The amount is not the heaviest part. The company also undertook to overhaul its compliance programme: staff training, tracking of complaints and their resolution, monitoring and audit mechanisms, and written confirmation from a senior officer within eight months.
That is the real risk for a small business. Not ruin, but an open file, months spent reconstructing who consented to what, and proof to produce with a spreadsheet as the only archive.
The refusal, from first click to proof
In the module, a refusal does four things at once. It freezes the file's cadence. It travels up to the Odoo contact, so it holds for every campaign, present and future. It makes the target be rejected when someone tries to add them to a campaign. And it keeps who recorded the refusal, when, and in whose words.
Two clarifications, because they are what determines whether the mechanism really holds.
The first: the propagation goes through the Odoo contact. A target imported in bulk, with a name and an email address but no contact record behind it, keeps its exclusion to itself. Which is why the good practice is to attach targets to real contacts, something the module does with one button. The second: it is the add wizard that refuses an excluded target and counts duplicate emails and phone numbers. A file pushed through Odoo's generic importer bypasses that check. The target then enters the campaign, but if it is linked to an excluded contact, its cadence is born frozen and the email refuses to go out. The control therefore exists in two places, not only at the front door.
One detail we are rather pleased with: if you already keep a consent register in your Odoo, the module reads it before every approach rather than copying its state across. Consent withdrawn blocks outreach with no synchronisation having to run. Two systems that talk to each other beat two truths that drift apart, and we wrote a whole article about that in our write-up on designing our customer experience module.
What we set up for a client starting a campaign:
- Decide the cadence before importing anything. Three calls and two emails over six weeks is a plan. "We'll call them back" is not.
- Attach every target to an Odoo contact at import time, so a refusal holds everywhere and not only in this campaign.
- Decide who on the team gets what. Automatic assignment gives the next target to whoever is carrying the least, which avoids the list that belongs to one person only.
- Write the email template once, with the identification the law requires already in it.
- Agree on what counts as a reply, and on what goes in the closing reason. That is the only place a lesson will come from at the end of the campaign.
Is your prospect list personal information?
The question comes up at every deployment, and the Quebec answer is more nuanced than people expect. Section 1 of the Act respecting the protection of personal information in the private sector puts outside two of its divisions the information concerning "the performance of duties within an enterprise by the person concerned, such as the person's name, title and duties, as well as the address, email address and telephone number of the person's place of work".
Those two divisions are collection and confidentiality. A strictly professional outreach list, with work contact details, therefore falls outside the rules on collection and consent. That is why business-to-business outreach is possible in Quebec without asking permission before writing.
Three limits to that reading, and they arrive quickly. The exclusion covers only those two divisions: the governance obligations, including the handling of confidentiality incidents, continue to apply, and so does a person's right of access to their own file, because it lives in a division the exclusion does not touch. It does not cover personal mobile numbers, home addresses or lists of individuals. And above all, it does not cover what you write about the person: the note saying "difficult on the phone", the summary of a call, an opinion about an executive. A well-kept outreach record always ends up holding information that is not work contact details.
The practical consequence is not to lock everything down. It is to know where those notes live, who can see them, and how long they are kept, which connects to the broader subject of jurisdictions and where your data is hosted.
What records itself
Manual entry is what kills adoption of this kind of tool. Nobody notes their calls for three weeks straight. So we wired the module into what already lives in the Odoo, through three bridges that install themselves when the matching modules are present.
An email received from a target becomes a reply in its history, and freezes its cadence. Calls actually placed attach to the right record with their real duration, including the ones dialled from the browser. A confirmed booking logs the meeting and moves the file to the "Meeting booked" stage, that one on the spot.
For the first two, the matching is done by periodic sweep rather than to the second: a reply arriving late in the afternoon shows up in the history a little later, not instantly. The matching runs on the normalised email address and on the number in international format, which assumes clean contact details on the record. Each of these bridges keeps a link back to its source, which guarantees the same event is never counted twice, even if the sweep passes over it again.
And a qualified target becomes an opportunity in the pipeline in one click, call history included, with the originating campaign recorded on it. That is what lets you answer, three months later, the one question worth a dashboard: how many calls per contract.
The blind spots
This module does not do newsletters. No A/B testing, no open tracking, no sending-address warm-up. For bulk email, Odoo's marketing tool does that job and does it better.
It does not dial your numbers for you either, and it does not post your letters. It keeps the calendar and the memory, the person makes the contact. That is a choice: a tool that calls on its own is called an auto-dialler, and that is not the same conversation with your clients. It can, on the other hand, prepare a letter merge from the targets you have selected, if the postal mailing module is installed alongside.
It does not find your prospects either. You bring the list.
It watches neither calling hours nor national do-not-call lists, as noted above. And the most important point: it helps you honour a refusal and prove it, it does not give you the right to send the first message. The basis for consent stays a business decision, to be made before the list is imported.
The module is free software, published under LGPL-3, and its code is open: you can read it, install it and change it. It sits alongside our other Odoo modules in our module catalogue, and the source code is in the bf_outreach GitHub repository.
At Blue Fox
We build this kind of module for the same reason every time: because a client was living with a spreadsheet and the data they needed was nowhere. It was true for hour banks, it was true for electronic signatures, and it is true for outreach.
The principle stays the same: on Odoo Community, as free software, hosted in Quebec under your control. Your prospect lists, the outcomes of your calls and the refusals you have received are sensitive data. They have no business living with an American vendor who bills per contact.
If your team does outreach and the question "who is left to call?" has no simple answer, let's talk about your situation.
Sources
- CRTC, Spam and malware: the portal for Canada's anti-spam legislation and its enforcement.
- CRTC, Frequently asked questions about CASL: the maximum penalties of $1M and $10M, the ten business day deadline and the mailing address valid for sixty days.
- CRTC, Guidance on implied consent: the two years following a purchase, the six months following an enquiry, and the conditions attaching to a published business address.
- CRTC, CASL enforcement from April to September 2025: the 152,603 complaints, the notices, the warning letters and the $50,000 penalty.
- CRTC, Hudson's Bay Company undertaking: the $120,000, the period covered and the compliance programme required.
- CRTC, Unsolicited Telecommunications Rules: the internal do-not-call list of three years and fourteen days, the calling hours and the identification requirements.
- CRTC, understanding the telemarketing rules: the exemption for businesses that call only other businesses, and the registration that remains mandatory despite the exemption.
- Innovation, Science and Economic Development Canada: the official CASL site.
- Act respecting the protection of personal information in the private sector, section 1: the exclusion from Divisions II and III covering work contact details.
- Module source code on GitHub: LGPL-3 licence, technical documentation and test suite.