Skip to content

System messages ​

System messages come from outside your application: an S3 notification that an object was created, a receipt from a support mailbox, or an alert that a server is low on disk space. This page covers subscribing to and handling them.

Because other systems create these messages, they don't follow the @node-ts/bus conventions, such as having a $name. They're received as they are, and a resolver function you provide decides which handler they go to.

TIP

Have the handler of a system message publish an event of your own, as below. The rest of your application then handles your event, and doesn't depend on the other system's format.

Declaring a system message ​

Describe the message with an interface or class. If the other system doesn't publish a type for its messages, write one:

ts
/**
 * The notification S3 publishes each time an object is created
 */
export interface S3ObjectCreatedNotification {
  Records: {
    eventSource: 'aws:s3'
    eventName: string
    s3: { object: { key: string } }
  }[]
}

Handling a system message ​

Register the handler with withCustomHandler(). Its second argument has:

  • resolveWith, which is called with every message read from the queue and returns whether this handler handles it. Messages could be anything, so check their shape.
  • topicIdentifier, optionally, the topic the other system publishes to. The transport subscribes the service queue to it: for Amazon SQS it's an SNS topic ARN, and for RabbitMQ an exchange name. Without it, subscribe the queue yourself.
ts
const bus = Bus.configure()
  .withMessageTypes(messageTypes)
  .withCustomHandler(
    async (notification: S3ObjectCreatedNotification, _attributes, ctx) => {
      // Publish your own event, so the rest of the app doesn't depend on S3's format
      for (const record of notification.Records) {
        await ctx.publish(new DocumentUploaded(record.s3.object.key))
      }
    },
    {
      // Called for every message read from the queue, which could be
      // anything, so check its shape

      resolveWith: notification =>
        Array.isArray(notification.Records) &&
        notification.Records[0]?.eventSource === 'aws:s3',
      // Subscribes the service queue to the topic S3 publishes to
      topicIdentifier: 'arn:aws:sns:us-east-1:000000000000:s3-object-created'
    }
  )
  .build()

await bus.initialize()
await bus.start()

Messages handled this way don't need message types.

See also ​

Released under the MIT License.