MailBot
This module will help you build an imap bot reacting to incoming emails.
You mainly provide two functions:
- A trigger which will be called for each received e-mail and should return a promise of a truthy if mail should trigger some job
- A mailHandler which will be called for each triggered e-mail and will do its job
Warning: Missing tests
There are actually no test because I found a bit too time-consuming to mock an Imap server for testing. They will come later.
Installation
npm install --save mailbot
Usage
const createBot = const bot = botstart
API
// Start watching, returns a Promisebotstart // Stops watching, returns a Promise// if argument is true, it will destroy the connection immediately// you're strongly advised to gracefully disconnect by not setting this parameterbot // Restartsbot // Update configuration option// Note: if you update 'imap', 'mailbox', or 'filter', it will restart the bot// unless said otherwisebot
Options
// IMAP configuration, see module "imap"imap: user: "user@gmail.com" password: "password" host: "imap.googlemail.com" port: 993 keepalive: true tls: true tlsOptions: rejectUnauthorized: false // Watched inboxmailbox: 'INBOX' // Should bot mark fetched emails as read?// If true, you're sure you will never fetch same mail twice even when restarting// If false, you'll mess with server emailsmarkSeen: true // Search filter to fetch emailsfilter: 'UNSEEN' // Should the trigger be checked when receiving headers, or when body has been parsed?// If your control depends only on headers (subject, recipient, sender…), you can set it to true// Warning: in 'headers' phase, headers are not parsed yet and you may need helperstriggerOnHeaders: false // The trigger: this function is called for each e-mail// Input: a mail object (if triggerOnHeaders is true, it will only have 'headers' property)// Output: a value or a promise of a value// The mail will be "handled" only if final value is truthy { // Example: work with e-mails whose subject is 'BOT: <something>' const match = headerssubject return match && match1} // The mail handler: this is the "job executor"// Input: a mail object, and the trigger value { console} // The error handler, called for each error occurring during processes// As there may be error thrown from very different places,// the function is called with a "context", which can be one of:// - 'IMAP_ERROR': global error// - 'SEARCH': failed searching or fetching mails// - 'TRIGGER': when trying to calculate trigger result (*)// - 'MAIL': when trying to handle mail (*)// (*) in those cases the third parameter will be a complete mail object// allowing you to access sender, subject, etc… { console if mail } // IMAP client reconnectionautoReconnect: trueautoReconnectTimeout: 5000 // false: attachments contents will be directly accessible as Buffer in 'content' property// true: attachments will be streamed via 'stream' property// Note: you can safely set it to false if you use triggerOnHeaders, otherwise you should work with streamsstreamAttachments: true // If true, mail.text will not contain signature// Properties 'textSignature' and 'textOriginal' will be addedremoveTextSignature: true // If true, if embedded images are found in signature of mail.html// they will be dropped from 'attachments' and moved to 'ignoredAttachments'ignoreAttachmentsInSignature: true // If true, property 'cleanSubject' will contain the subject without all messy prefixescleanSubject: true // Set to a strictly positive number to define period (milliseconds) between automatic search// Note that this delay starts AFTER a batch has been handled// Any falsey value will disable periodic searchsearchPeriod: false
Mail objects
Mail objects are generated by mailparser
(version 0.x, not the buggy 2.0): see full description of parsed mail object.
Following custom properties are added:
- ignoredAttachments
- textSignature
- textOriginal
- cleanSubject
Helpers
parse addresses in raw headers
Working with triggerOnHeaders: true
is interesting for performance purpose, but you get unparsed headers. This function will help you working with to/cc/bcc
headers:
triggerOnHeaders: true { console // "Bob" <bob@a.b> console // [ { address: 'bob@a.b', raw: '"Bob" <bob@a.b>', phrase: '"Bob"' } ] }
Extract signature from text body
This function will help you remove signature from e-mail body, using talon
:
const text signature =
Strip HTML tags
This function will remove any HTML tag from a string, using striptags
internally:
const text =
Debugging
This module uses debug
internally, and you can enable internal debug messages adding mailbot
to your environment variable DEBUG
:
env DEBUG=mailbot node mybot.js
Full sample
See sample.js
in repository: it's a mail bot which will react on every mail which subject starts with 'upload to …'. It will fetch all attachments and save it to <upload dir>/<sender address>/<requested path>
.
This illustrates how you can easily create that type of bot.