Mailbot Save

Mail Bot: IMAP client sorting entering emails and triggering operations of your choice

Project README

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 } = require('mailbot')

const bot = createBot(options)

bot.start()

API

// Start watching, returns a Promise
bot.start()

// 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 parameter
bot.stop(destroy = false)

// Restarts
bot.restart(destroy = false)

// Update configuration option
// Note: if you update 'imap', 'mailbox', or 'filter', it will restart the bot
// unless said otherwise
bot.configure('imap', connectionInfo, autoRestart = true, destroy = false)

Options

{

// IMAP configuration, see module "imap"
imap: {
	user: "[email protected]",
	password: "password",
	host: "imap.googlemail.com",
	port: 993,
	keepalive: true,
	tls: true,
	tlsOptions: {
		rejectUnauthorized: false
	},
},

// Watched inbox
mailbox: '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 emails
markSeen: true,

// Search filter to fetch emails
filter: ['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 helpers
triggerOnHeaders: 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
trigger ({ headers }) {
	// Example: work with e-mails whose subject is 'BOT: <something>'
	const match = headers.subject.match(/BOT: (.*)$/)
	return match && match[1]
},

// The mail handler: this is the "job executor"
// Input: a mail object, and the trigger value
mailHandler (mail, trigger) {
	console.log({
		subject: mail.headers.subject,
		trigger
	})
},

// 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…
errorHandler (error, context, mail) {
	console.error(context, error)
	if (mail) {
		sendErrorMailTo(mail.from)
	}
},

// IMAP client reconnection
autoReconnect: true,
autoReconnectTimeout: 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 streams
streamAttachments: true,

// If true, mail.text will not contain signature
// Properties 'textSignature' and 'textOriginal' will be added
removeTextSignature: 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 prefixes
cleanSubject: 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 search
searchPeriod: 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,
	trigger: ({ headers }) => {
		console.log(headers.to) // "Bob" <[email protected]>
		parseAddresses(headers)
		console.log(headers.to) // [ { address: '[email protected]', raw: '"Bob" <[email protected]>', phrase: '"Bob"' } ]
	}
}

Extract signature from text body

This function will help you remove signature from e-mail body, using talon:

const { text, signature } = extractSignature(mail.text)

Strip HTML tags

This function will remove any HTML tag from a string, using striptags internally:

const text = stripTags(mail.html)

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.

Open Source Agenda is not affiliated with "Mailbot" Project. README Source: byteclubfr/mailbot
Stars
33
Open Issues
2
Last Commit
6 years ago
Repository
License
MIT

Open Source Agenda Badge

Open Source Agenda Rating