diff --git a/imap-simple/imap-simple-tests.ts b/imap-simple/imap-simple-tests.ts new file mode 100644 index 0000000000..d54c16254e --- /dev/null +++ b/imap-simple/imap-simple-tests.ts @@ -0,0 +1,85 @@ +/// + +import * as imaps from "imap-simple"; + +let config = { + imap: { + user: "your@email.address", + password: "yourpassword", + host: "imap.gmail.com", + port: 993, + tls: true, + authTimeout: 3000 + } +}; + +imaps.connect(config).then(function (connection) { + + return connection.openBox("INBOX").then(function () { + let searchCriteria = [ + "UNSEEN" + ]; + + let fetchOptions = { + bodies: ["HEADER", "TEXT"], + markSeen: false + }; + + return connection.search(searchCriteria, fetchOptions).then(function (results) { + let subjects = results.map(function (res) { + return res.parts.filter(function (part) { + return part.which === "HEADER"; + })[0].body.subject[0]; + }); + + console.log(subjects); + // => + // [ "Hey Chad, long time no see!", + // "Your amazon.com monthly statement", + // "Hacker Newsletter Issue #445" ] + }); + }); +}); + +imaps.connect(config).then(function (connection) { + + connection.openBox("INBOX").then(function () { + + // Fetch emails from the last 24h + let delay = 24 * 3600 * 1000; + let yesterday = new Date(); + yesterday.setTime(Date.now() - delay); + let yesterdayString = yesterday.toISOString(); + let searchCriteria = ["UNSEEN", ["SINCE", yesterdayString]]; + let fetchOptions = { bodies: ["HEADER.FIELDS (FROM TO SUBJECT DATE)"], struct: true }; + + // retrieve only the headers of the messages + return connection.search(searchCriteria, fetchOptions); + }).then(function (messages) { + + let attachments: Promise<{filename: string, data: any}>[] = []; + + messages.forEach(function (message) { + let parts = imaps.getParts(message.attributes.struct); + attachments = attachments.concat(parts.filter(function (part) { + return part.disposition && part.disposition.type === "ATTACHMENT"; + }).map(function (part) { + // retrieve the attachments only of the messages with attachments + return connection.getPartData(message, part) + .then(function (partData) { + return { + filename: part.disposition.params.filename, + data: partData + }; + }); + })); + }); + + return Promise.all(attachments); + }).then(function (attachments: {filename: string, data: any}[]) { + console.log(attachments); + // => + // [ { filename: "cats.jpg", data: Buffer() }, + // { filename: "pay-stub.pdf", data: Buffer() } ] + }); +}); diff --git a/imap-simple/imap-simple.d.ts b/imap-simple/imap-simple.d.ts new file mode 100644 index 0000000000..6123a7e806 --- /dev/null +++ b/imap-simple/imap-simple.d.ts @@ -0,0 +1,69 @@ +// Type definitions for imap-simple v1.6.3 +// Project: https://github.com/chadxz/imap-simple +// Definitions by: Jeffery Grajkowski +// Definitions: https://github.com/psnider/DefinitelyTyped/imap-simple + +/// + +declare namespace IMAPS { + + export interface ImapSimpleOptions { + /** Options to pass to node-imap constructor. */ + imap: IMAP.Config; + + /** Time in milliseconds to wait before giving up on a connection attempt. (Deprecated: please use options.imap.authTimeout instead) */ + connectTimeout?: number; + } + + export interface MessageBodyPart extends IMAP.ImapMessageBodyInfo { + /** string type where which=='TEXT', complex Object where which=='HEADER' */ + body: any; + } + + export interface Message { + attributes: IMAP.ImapMessageAttributes; + parts: MessageBodyPart[]; + } + + export class ImapSimple { + constructor(imap: IMAP.Connection); + + /** Open a mailbox, calling the provided callback with signature (err, boxName), or resolves the returned promise with boxName. */ + openBox(boxName: string, callback?: (err: Error, boxName: string) => void): Promise; + + /** Search for and retrieve mail in the previously opened mailbox. */ + search(searchCriteria: any[], fetchOptions: IMAP.FetchOptions, callback?: (err: Error, messages: Message[]) => void): Promise; + + /** Close the connection to the imap server. */ + end(): void; + + /** Downloads part data (which is either part of the message body, or an attachment). Upon success, either the provided callback will be called with signature (err, data), or the returned promise will be resolved with data. The data will be automatically decoded based on its encoding. If the encoding of the part is not supported, an error will occur. */ + getPartData(message: Message, part: any, callback?: (err: Error, data: any) => void): Promise; + + /** Adds the provided label(s) to the specified message(s). source corresponds to a node-imap MessageSource which specifies the messages to be moved. label is either a string or array of strings indicating the labels to add. When completed, either calls the provided callback with signature (err), or resolves the returned promise. */ + addMessageLabel(source: string | string[], label: string | string[], callback?: (err: Error) => void): Promise; + + /** Moves the specified message(s) in the currently open mailbox to another mailbox. source corresponds to a node-imap MessageSource which specifies the messages to be moved. When completed, either calls the provided callback with signature (err), or resolves the returned promise. */ + moveMessage(source: string | string[], boxName: string, callback?: (err: Error) => void): Promise; + } + + /** Error thrown when a connection attempt has timed out. */ + export class ConnectionTimeoutError extends Error { + timeout: number; + constructor(timeout: number); + } +} + +declare module "imap-simple" { + /** Main entry point. Connect to an Imap server. */ + export const connect: (options: IMAPS.ImapSimpleOptions, callback?: Function) => Promise; + + export namespace errors { + export import ConnectionTimeoutError = IMAPS.ConnectionTimeoutError; + } + + export import ImapSimple = IMAPS.ImapSimple; + + /** Given the message.attributes.struct, retrieve a flattened array of parts objects that describe the structure of the different parts of the message's body. Useful for getting a simple list to iterate for the purposes of, for example, finding all attachments. */ + export const getParts: (struct: any[]) => any[]; +}