npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mailbot

v3.1.1

Published

Mail Bot: IMAP client sorting and processing entering emails

Downloads

18

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.