pushbullet-queue

Make a simple message queue driven task runner using PushBullet

Usage no npm install needed!

<script type="module">
  import pushbulletQueue from 'https://cdn.skypack.dev/pushbullet-queue';
</script>

README

PushBullet Queue

Make a simple message queue driven task runner using PushBullet

How it works

This works by listening for push events on a device and then passes the push data to all tasks that match. You write the tasks and there is no limit to how long they can run for.

Setup

Things you will need before you begin:

Create a device

Using the PushBullet API, create a device making a note of the iden that is returned.

Get ID of device to send errors to (optional)

If you want to be alerted of failed tasks, you can get it sent to a device for you to investigate - this would be best going to a mobile or browser device. Run the list devices API call, making a note of the iden of the device you want to use.

Application Setup

Logging is done using pino. You can either pass in your own instance of it, or let the library create an instance for you.

(async () => {
  try {
    await queue('access-token', {
      db: {
        type: 'mongodb', // only option currently
        opts: {}, // any valid mongoose options - https://mongoosejs.com/docs/connections.html#options
        url: 'mongodb://localhost:27017/queue', // MongoDB connection URL
      },
      logger: {
        logger: pino(), // optional - pass an instance of pino logger
        // or
        level: 'trace/debug/info/warn/error/fatal/silent', // optional - any valid pino level
        name: 'app-name', //optional
        redact: [], // optional - any keys to redact. It adds in 'db.url' by default
      },
      pushBullet: {
        alert: true, // optional - identify of the device you wish to alert errors to. Defaults to sending device
        errorOnClose: true, // optional - does a disconnect event result in an error being thrown?
        processAttempts: 3, // optional - number of times a task will be tried before failing
      },
      server: {
        domain: 'http://localhost:3000', // optional - the domain to use. This will normally be a fully-qualified domain name
        port: 3000, // optional - the port the async server runs on
      },
      tasks: [{
        deviceId: 'pushbullet-device-iden', // iden of the device you wish to listen on to trigger a task
        name: 'task1', // optional - name of the task
        async: false, // optional - async task. In order to complete, the HTTP endpoint needs to be hit
        task: async (push: IPush, { asyncUrl, logger }: IQueryOpts) : Promise<void> => {
          // Define your task here
          await new Promise(resolve => setTimeout(resolve, 1000));

          // Do something with the push data
          logger.event('info', 'New event', push);

          // Task now over - if async, will need to hit the `asyncUrl` endpoint
        },
      }],
    });
  } catch (err) {
    // This will only be triggered during a setup error - never if a task fails
    console.log(err.stack);
    process.exit(1);
  }
})();

Your first task

Tasks are as simple or as complex as you want them to be. They receive two arguments, push and logger and are expected to resolve or reject a Promise.

Push

This is the instance of the PushBullet Push object. Nothing is added or removed to this from what is received from PushBullet.

Logger

This is simple wrapper to the Pino.

Methods

  • pino: the Pino instance. You can use this if you don't want to use our wrapper
  • child(bindings: ILoggerChildBindings): the Pino child logger. This returns an instance of the log wrapper, NOT the Pino instance.
  • event(level: string, msg: string, obj: {[key: string] : any}, ...args: any[]): this wraps each of the Pino log methods

Asynchronous Tasks

This functionality exists to work with OpenFAAS Async Tasks. The workflow is for the function to resolve at some point in the future and to let us know by hitting the endpoint given.

Sometimes you may wish to perform the acknowledgement of the task yourself.