Skip to content

About

An IMAP email trigger plugin for the xyOps workflow automation system.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

3 Commits

Folders and files

Repository files navigation

IMAP Email Trigger

IMAP Email Trigger

An IMAP trigger plugin for the xyOps Workflow Automation System. It watches an email mailbox on a schedule, launches a job when matching messages are found, and passes the parsed email data plus attachments into the job input.

Use it for inbound order processing, support queues, report ingestion, approval emails, document dropboxes, alert mailboxes, or any workflow where email arrival should start automation.

Features

  • Pure Node.js / npx plugin.
  • Works as a xyOps Trigger Plugin.
  • Polls any IMAP-compatible mailbox on the cadence of a normal xyOps schedule.
  • Defaults to unread messages with UNSEEN style behavior via IMAP search criteria.
  • Processes up to a configurable maximum number of messages per trigger run.
  • Always passes input.data.emails as an array to the launched job.
  • Downloads attachments and passes them to the launched job as normal xyOps input files.
  • Can optionally attach the raw .eml message for archival or forensic workflows.
  • Supports post-processing actions: mark as read, move to folder, delete, or leave unchanged.
  • Uses a xyOps Secret Vault variable for the IMAP password.

Requirements

  • Node.js and npx
  • Network access from the xyOps primary conductor host to your IMAP server

Secrets / Environment Variables

Create a Secret Vault in xyOps and assign this plugin to it. Add:

  • IMAP_PASSWORD

Enter the hostname and username directly in the plugin parameters.

Data Collection

This plugin does not collect, store, or transmit telemetry, analytics, or usage metrics. It only connects to the IMAP server you configure. Your email provider may log IMAP connections and mailbox actions according to its own policies.

How It Works

This is a schedule modifier. Add it alongside a normal xyOps schedule trigger, such as every minute, every five minutes, or hourly. The schedule decides when xyOps asks the plugin for a launch decision. This plugin then checks the configured mailbox and returns yes or no (along with the matched message data).

When matching email is found, the plugin:

  1. Downloads and parses up to Maximum Messages.
  2. Returns launch: true to trigger a job launch.
  3. Passes parsed email records in input.data.emails.
  4. Passes attachments as xyOps input files.
  5. Applies the selected post-processing action.

If no matching email is found, the job is not launched.

Parameters

Parameter Required Description
IMAP Hostname Yes IMAP server hostname.
Username Yes IMAP username.
Port No IMAP TCP port. Defaults to 993.
Use TLS No Use IMAP over TLS. Enabled by default.
Reject Unauthorized TLS Certs No Reject untrusted TLS certificates. Enabled by default.
Timeout (sec) No Connection and socket timeout. Defaults to 30.
Mailbox No Mailbox folder to poll. Defaults to INBOX.
Search Criteria No IMAP search criteria as JSON. Defaults to { "seen": false }.
Maximum Messages No Maximum matching messages to process in one run. Defaults to 1.
Message Order No Process oldest or newest matching UIDs first. Defaults to oldest first.
Download Attachments No Attach email attachments to the launched xyOps job. Enabled by default.
Attach Raw Email No Also attach each raw .eml message. Disabled by default.
Max Body Characters No Maximum characters for text and HTML bodies. Defaults to 250000; 0 means no limit.
Post-Processing Action No Mark as Read, Move to Folder, Delete, or None. Defaults to Mark as Read.
Move to Folder Only for move Destination mailbox for move action. The folder must already exist.

Search Criteria

The default search criteria is:

{
	"seen": false
}

That means the plugin only processes unread messages. After a successful fetch and staging step, the default post-processing action marks those messages as read so they will not be picked up again.

You can customize the search criteria in the native JSON editor. Examples:

Unread messages from one sender:

{
	"seen": false,
	"from": "orders@example.com"
}

Unread messages with a case-insensitive subject match:

{
	"seen": false,
	"subject": "Invoice"
}

Messages received since a date:

{
	"since": "2026-07-01"
}

Unread Gmail messages with a specific label:

{
	"seen": false,
	"labels": {
		"has": [ "Cool" ]
	}
}

For Gmail label searches like this, set Mailbox to [Gmail]/All Mail. Some Gmail labels are not exposed as IMAP folders unless they are enabled for IMAP in Gmail settings.

Post-Processing Choices

Action Behavior
Mark as Read Adds the IMAP Seen flag after messages are staged. This is the safest default.
Move to Folder Moves processed messages to another mailbox folder, such as Processed. This is best for audit trails.
Delete Deletes processed messages from the mailbox. Use carefully.
None Leaves messages unchanged. Useful for testing, but will reprocess the same messages repeatedly.

Output Summary

When email is found, the launched job receives:

  • input.data.emails: Array of parsed email records.
  • input.data.imap: Summary of the mailbox poll and post-processing action.
  • input.files: Attachment files, and optionally raw .eml files.

Each emails array entry includes common fields such as:

  • uid
  • messageId
  • subject
  • date
  • from
  • to
  • cc
  • replyTo
  • headers
  • text
  • html
  • files

The files array inside each email describes the files attached to the xyOps job. The actual files are passed through xyOps as normal input files for the launched job.

General Notes

  • This plugin does not create jobs by itself. It modifies launches from a normal schedule trigger.
  • Trigger Plugins run on the xyOps primary conductor server, so that server needs network access to your IMAP host.
  • For Gmail, Outlook, Yahoo, and similar providers, you may need an app-specific password or provider-specific IMAP settings.
  • For Gmail labels that are not exposed as IMAP folders, use [Gmail]/All Mail as the mailbox and filter by labels in the search criteria.
  • Move to Folder requires the destination mailbox to already exist.
  • None is useful while testing, but it usually needs strict search criteria to avoid repeated launches.
  • Delete is intentionally opt-in because it removes mail from the source mailbox.
  • The plugin applies the post-processing action after email data and files are staged, but before xyOps launches the downstream job.

Local Testing

When invoked by xyOps, the plugin expects a single JSON document on STDIN using the xyOps Wire Protocol. You can simulate this locally by piping JSON into node index.js.

Example test using an environment variable for the password:

echo '{"xy":1,"type":"trigger","items":[{"timezone":"America/Los_Angeles","now":1783180800,"dargs":{"year":2026,"month":7,"day":4,"weekday":6,"hour":9,"minute":0},"params":{"hostname":"imap.example.com","username":"bot@example.com","mailbox":"INBOX","search_criteria":{"seen":false},"max_messages":2,"post_action":"mark_read","download_attachments":true},"job":{"id":"emexample","title":"Process Incoming Email"}}]}' | IMAP_PASSWORD=REPLACE_ME node index.js

Example test using the secrets object, which mirrors what xyOps provides:

{
	"xy": 1,
	"type": "trigger",
	"secrets": {
		"IMAP_PASSWORD": "REPLACE_ME"
	},
	"items": [
		{
			"timezone": "America/Los_Angeles",
			"now": 1783180800,
			"dargs": {
				"year": 2026,
				"month": 7,
				"day": 4,
				"weekday": 6,
				"hour": 9,
				"minute": 0
			},
			"params": {
				"hostname": "imap.example.com",
				"username": "bot@example.com",
				"mailbox": "INBOX",
				"search_criteria": {
					"seen": false
				},
				"max_messages": 2,
				"order": "oldest",
				"download_attachments": true,
				"post_action": "mark_read"
			},
			"job": {
				"id": "emexample",
				"title": "Process Incoming Email"
			}
		}
	]
}

Run it like this:

cat sample.json | node index.js

Example response when no matching messages are present:

{
	"xy":1,
	"items": [
		{ "launch":false }
	]
}

Example response shape when a matching message is found:

{
	"xy": 1,
	"items": [
		{
			"launch": true,
			"data": {
				"emails": [
					{
						"mailbox": "INBOX",
						"uid": 101,
						"subject": "Daily Report",
						"from": {
							"name": "Reports",
							"address": "reports@example.com"
						},
						"to": [
							{
								"name": "",
								"address": "bot@example.com"
							}
						],
						"text": "Report attached.",
						"html": "",
						"files": [
							{
								"type": "attachment",
								"filename": "email-101-attachment-1-report.csv",
								"originalFilename": "report.csv",
								"mimeType": "text/csv",
								"size": 2048
							}
						]
					}
				],
				"imap": {
					"mailbox": "INBOX",
					"count": 1,
					"postAction": "mark_read",
					"moveFolder": ""
				}
			},
			"files": [
				{
					"path": "/tmp/xyplug-imap-example/email-101-attachment-1-report.csv",
					"delete": true
				}
			]
		}
	]
}

The real plugin output is compacted onto one line, as required by the xyOps Wire Protocol.

License

MIT

About

An IMAP email trigger plugin for the xyOps workflow automation system.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages