kannon.js
v1.0.2
Published
Kannon node client libreary
Readme
Kannon.js
The official Node.js client library for Kannon Email Sender.
Installation
npm install kannon.jsQuick Start
import { KannonCli } from 'kannon.js';
const kannon = new KannonCli(
'your-domain.com',
'your-api-key',
{
email: '[email protected]', // this should match the domain host
alias: 'Kannon',
},
{
endpoint: 'https://api.kannon.dev',
},
);
// Send a simple HTML email
await kannon.sendHtml(
['[email protected]'],
'Welcome to Kannon!',
'<h1>Hello!</h1><p>Welcome to our platform.</p>',
);MailSender - Simple Email API
For straightforward email sending without templating, use MailSender. It provides a traditional mail client API with To, CC, and BCC support.
Basic Usage
import { KannonCli, MailSender } from 'kannon.js';
const kannon = new KannonCli(
'your-domain.com',
'your-api-key',
{ email: '[email protected]', alias: 'Kannon' },
{ endpoint: 'https://api.kannon.dev' },
);
const mailSender = new MailSender(kannon);
await mailSender.send({
to: '[email protected]',
subject: 'Hello',
content: '<p>Hello, World!</p>',
});With CC and BCC
await mailSender.send({
to: ['[email protected]', '[email protected]'],
cc: '[email protected]',
bcc: '[email protected]',
subject: 'Project Update',
content: '<h1>Status Report</h1><p>All systems operational.</p>',
});With Attachments
import { readFileSync } from 'fs';
await mailSender.send({
to: '[email protected]',
subject: 'Monthly Report',
content: '<h1>Report</h1><p>See attachment.</p>',
attachments: [
{
filename: 'report.pdf',
content: readFileSync('./report.pdf'),
},
],
});Scheduled Delivery
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
await mailSender.send({
to: '[email protected]',
subject: 'Scheduled Reminder',
content: '<p>This email was scheduled.</p>',
scheduledTime: tomorrow,
});MailSender API Reference
SendParams
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| to | string \| string[] | Yes | Primary recipient(s) |
| subject | string | Yes | Email subject line |
| content | string | Yes | HTML email body |
| cc | string \| string[] | No | Carbon copy recipients (visible to all) |
| bcc | string \| string[] | No | Blind carbon copy recipients (hidden) |
| attachments | Attachment[] | No | File attachments |
| scheduledTime | Date | No | Schedule for future delivery |
SendResult
| Field | Type | Description |
|-------|------|-------------|
| messageId | string | Unique identifier for the sent message |
| scheduledTime | Date \| undefined | Scheduled delivery time (if applicable) |
Usage Examples (KannonCli)
Basic Email Sending
Simple HTML Email
const html = `
<h1>Welcome to Kannon!</h1>
<p>Thank you for signing up.</p>
<a href="https://kannon.dev">Visit our website</a>
`;
await kannon.sendHtml(['[email protected]'], 'Welcome to Kannon', html);Multiple Recipients
const recipients = ['[email protected]', '[email protected]', '[email protected]'];
await kannon.sendHtml(recipients, 'Important Update', '<h1>System Update</h1><p>We have important news for you.</p>');With Attachments
import { readFileSync } from 'fs';
const pdfBuffer = readFileSync('./document.pdf');
await kannon.sendHtml(
['[email protected]'],
'Your Invoice',
'<h1>Invoice Attached</h1><p>Please find your invoice attached.</p>',
{
attachments: [
{
filename: 'invoice.pdf',
content: pdfBuffer,
},
{
filename: 'terms.txt',
content: Buffer.from('Terms and conditions...'),
},
],
},
);Template Emails
Using Template IDs
await kannon.sendTemplate(['[email protected]'], 'Your Order Confirmation', 'order-confirmation-template');Templates with Attachments
await kannon.sendTemplate(['[email protected]'], 'Monthly Report', 'monthly-report-template', {
attachments: [
{
filename: 'report.pdf',
content: reportBuffer,
},
],
});Personalized Emails
Individual Fields
const html = `
<h1>Hello {{name}}!</h1>
<p>Your account balance is: {{balance}}</p>
<p>Last login: {{lastLogin}}</p>
`;
await kannon.sendHtml(
[
{
email: '[email protected]',
fields: {
name: 'John',
balance: '$1,250',
lastLogin: '2024-01-15',
},
},
{
email: '[email protected]',
fields: {
name: 'Jane',
balance: '$890',
lastLogin: '2024-01-14',
},
},
],
'Account Update',
html,
);Mixed Recipient Types
const recipients = [
'[email protected]', // String format
{
email: '[email protected]',
fields: { name: 'Alice', role: 'Admin' },
}, // Object format
{
email: '[email protected]',
fields: { name: 'Bob', role: 'User' },
},
];
const html = `
<h1>Hello {{name || 'there'}}!</h1>
<p>Your role: {{role || 'Guest'}}</p>
`;
await kannon.sendHtml(recipients, 'Welcome', html);Global Fields
Shared Content for All Recipients
const html = `
<h1>Hello {{name}}!</h1>
<p>This is a message from {{company}}.</p>
<p>Current date: {{currentDate}}</p>
<p>Support email: {{supportEmail}}</p>
`;
await kannon.sendHtml(
[
{ email: '[email protected]', fields: { name: 'John' } },
{ email: '[email protected]', fields: { name: 'Jane' } },
],
'Company Update',
html,
{
globalFields: {
company: 'Kannon Corp',
currentDate: new Date().toLocaleDateString(),
supportEmail: '[email protected]',
},
},
);Scheduled Emails
Future Delivery
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
await kannon.sendHtml(
['[email protected]'],
"Tomorrow's Reminder",
"<h1>Don't forget!</h1><p>Your meeting is tomorrow.</p>",
{
scheduledTime: tomorrow,
},
);Specific Date and Time
const scheduledTime = new Date('2024-02-01T10:00:00Z');
await kannon.sendTemplate(['[email protected]'], 'Weekly Newsletter', 'newsletter-template', {
scheduledTime,
globalFields: {
weekNumber: '5',
year: '2024',
},
});Email Headers (To/CC)
Adding CC Recipients
await kannon.sendHtml(
['[email protected]'],
'Project Update',
'<h1>Project Status</h1><p>Here is the latest update.</p>',
{
headers: {
cc: ['[email protected]', '[email protected]'],
},
},
);Custom To Header
await kannon.sendHtml(
['[email protected]'],
'Meeting Invitation',
'<h1>You are invited!</h1><p>Please join us for the quarterly review.</p>',
{
headers: {
to: ['[email protected]'],
cc: ['[email protected]'],
},
},
);Advanced Configuration
Custom Domain Setup
const kannon = new KannonCli(
'mycompany.com',
'your-api-key',
{
email: '[email protected]',
alias: 'My Company',
},
{
endpoint: 'https://api.mycompany.com',
},
);Development Environment
const kannon = new KannonCli(
'dev.example.com',
'dev-api-key',
{
email: '[email protected]',
alias: 'Dev Environment',
},
{
endpoint: 'http://localhost:8080', // HTTP for local development
},
);Production with Custom Port
const kannon = new KannonCli(
'production.com',
'prod-api-key',
{
email: '[email protected]',
alias: 'Production System',
},
{
endpoint: 'https://api.production.com:8443', // Custom HTTPS port
},
);API Reference
KannonCli Constructor
new KannonCli(
domain: string,
apiKey: string,
sender: KannonSender,
config: KannonConfig
)Parameters:
domain: Your Kannon domainapiKey: Your Kannon API keysender: Sender configurationemail: Sender email addressalias: Sender display name
config: Client configurationendpoint: API endpoint (must include protocol)
Methods
sendHtml(recipients, subject, html, options?)
Sends an HTML email.
Parameters:
recipients: Array of recipients (strings or objects with fields)subject: Email subject linehtml: HTML content of the emailoptions: Optional configuration
sendTemplate(recipients, subject, templateId, options?)
Sends a template email.
Parameters:
recipients: Array of recipients (strings or objects with fields)subject: Email subject linetemplateId: ID of the template to useoptions: Optional configuration
Options
type SendOptions = {
scheduledTime?: Date; // When to send the email
globalFields?: Record<string, string>; // Fields shared by all recipients
attachments?: {
// File attachments
filename: string;
content: Buffer;
}[];
headers?: {
// Email headers
to?: string[]; // Additional To header addresses
cc?: string[]; // CC header addresses
};
};Types
type Recipient =
| string // Simple email address
| {
// Email with personalized fields
email: string;
fields?: Record<string, string>;
};
type KannonSender = {
email: string;
alias: string;
};
type KannonConfig = {
endpoint: string;
};Error Handling
try {
await kannon.sendHtml(['[email protected]'], 'Test Email', '<h1>Hello</h1>');
console.log('Email sent successfully!');
} catch (error) {
console.error('Failed to send email:', error.message);
if (error.code === 'AUTHENTICATION_FAILED') {
console.error('Check your API key and domain');
} else if (error.code === 'INVALID_RECIPIENT') {
console.error('Check recipient email addresses');
}
}🚨 Breaking Changes in v1.0.0
This version introduces breaking changes due to the migration from ts-proto to connect-es:
Endpoint Configuration Changes
Before (v1.0.0):
const kannon = new KannonCli(
'your-domain.com',
'your-api-key',
{ email: '[email protected]', alias: 'Kannon' },
{ host: 'api.kannon.dev:443' }, // ❌ Old format
);After (v1.0.0):
const kannon = new KannonCli(
'your-domain.com',
'your-api-key',
{ email: '[email protected]', alias: 'Kannon' },
{ endpoint: 'https://api.kannon.dev' }, // ✅ New format with protocol
);Key Changes:
- Protocol required: You must now specify the protocol (
https://orhttp://) - Port optional: Standard ports (443 for HTTPS, 80 for HTTP) are automatically used
- TLS handling: The
skipTLSoption is no longer supported - Parameter renamed:
hostparameter is nowendpointfor clarity
Migration Examples:
| Old Format (host) | New Format (endpoint) |
| -------------------- | ------------------------ |
| api.kannon.dev:443 | https://api.kannon.dev |
| api.kannon.dev:80 | http://api.kannon.dev |
| localhost:8080 | http://localhost:8080 |
| localhost:8443 | https://localhost:8443 |
Migration Guide
If you're upgrading from v1.0.0:
- Update endpoint configuration to include protocol
- Rename
hosttoendpointin your configuration - Remove port numbers if using standard ports (443/80)
- Test your integration to ensure compatibility
Example migration:
// Before
const kannon = new KannonCli('domain', 'key', sender, {
host: 'api.kannon.dev:443',
});
// After
const kannon = new KannonCli('domain', 'key', sender, {
endpoint: 'https://api.kannon.dev',
});The host parameter is removed. Please use endpoint instead:
const kannon = new KannonCli('domain', 'key', sender, {
endpoint: 'https://api.kannon.dev',
});License
ISC
