{"id":15678906,"url":"https://github.com/jaredwray/airhorn","last_synced_at":"2025-04-15T18:02:13.868Z","repository":{"id":37793376,"uuid":"335718854","full_name":"jaredwray/airhorn","owner":"jaredwray","description":"Cloud Native Notifications Library","archived":false,"fork":false,"pushed_at":"2025-04-06T13:29:35.000Z","size":1095,"stargazers_count":16,"open_issues_count":0,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-10T08:01:19.346Z","etag":null,"topics":["airhorn","cloud-native","email","mobile-push","notifications","sms","webhooks"],"latest_commit_sha":null,"homepage":"https://airhorn.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jaredwray.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-03T18:32:36.000Z","updated_at":"2025-04-09T10:17:46.000Z","dependencies_parsed_at":"2024-01-06T16:37:06.326Z","dependency_job_id":"9103e013-48d4-4578-a826-6480e492af8a","html_url":"https://github.com/jaredwray/airhorn","commit_stats":{"total_commits":446,"total_committers":6,"mean_commits":74.33333333333333,"dds":0.07399103139013452,"last_synced_commit":"c80eb029a0eb135c4a1cc0cceb96df11a314130c"},"previous_names":[],"tags_count":53,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredwray%2Fairhorn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredwray%2Fairhorn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredwray%2Fairhorn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaredwray%2Fairhorn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaredwray","download_url":"https://codeload.github.com/jaredwray/airhorn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249125963,"owners_count":21216705,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["airhorn","cloud-native","email","mobile-push","notifications","sms","webhooks"],"created_at":"2024-10-03T16:25:21.602Z","updated_at":"2025-04-15T18:02:13.854Z","avatar_url":"https://github.com/jaredwray.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Airhorn](site/logo.svg \"Airhorn\")\n\n---\n\n[![tests](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/airhorn/actions/workflows/tests.yml)\n[![codecov](https://codecov.io/gh/jaredwray/airhorn/branch/main/graph/badge.svg?token=4OJEEB67Q5)](https://codecov.io/gh/jaredwray/airhorn)\n[![license](https://img.shields.io/github/license/jaredwray/airhorn)](https://github.com/jaredwray/airhorn/blob/master/LICENSE)\n[![npm](https://img.shields.io/npm/dm/airhorn)](https://npmjs.com/package/airhorn)\n[![npm](https://img.shields.io/npm/v/airhorn)](https://npmjs.com/package/airhorn)\n\n# Cloud Native Notifications Library\n\nAirhorn makes it easy to send SMS, SMTP, Webhooks, and mobile push notifications easily using templates through your standard cloud providers. We focused on making it cloud native by default (using cloud services).\n\n# Table of Contents\n* [Features](#features)\n* [Getting Started](#getting-started)\n* [Library API](#library-api)\n* [Templates](#templates)\n* [Template Providers (In Memory, MongoDB, Postgres)](#template-providers-in-memory-mongodb-postgres)\n* [File System Templates](#file-system-templates)\n* [Examples for using this library](#examples-for-using-this-library)\n* [Supported Cloud Service Providers](#supported-cloud-service-providers)\n* [ESM and Node Version Support](#esm-and-node-version-support)\n* [How to Contribute](#how-to-contribute)\n* [Setting up your Development Environment](#setting-up-your-development-environment)\n* [Licensing and Copyright](#licensing-and-copyright)\n\n# Features\n\n* GitOps Based Templating System - email, SMS, mobile push, and webhooks all in one place!\n* Email Notifications - easily send email across multiple providers and even load balance or active/passive fail over. \n* SMS Notifications - SMS that is easy to use via a robust template system. \n* Mobile Push Notifications - Push to IOS and Android devices.\n* Webhook Notifications - Built right into the system as a native feature.\n* 100% Code Coverage / Tested with Integration Tests\n* Built using [ecto](https://github.org/jaredwray/ecto) for handling multiple templates such as EJS, Handlebars, and more.\n\n# Gettign Started\n\nTo get started with Airhorn, you can install the package via npm:\n\n```bash\nnpm install airhorn\n```\n\nThen, you can use the library in your code:\n\n```js\nimport { createAirhorn, AirhornProviderType } from 'airhorn';\n\nconst airhorn = new createAirhorn({\n    TEMPLATE_PATH: './your-template-path',\n    DEFAULT_TEMPLATE_LANGUAGE: 'en',\n    SENDGRID_API_KEY: 'YOUR_SEND_GRID_API_KEY',\n});\nconst data = {\n    // your data to render the template goes here\n}\n\nairhorn.send('me@you.com', 'no-contact@company.com', 'template-name', AirhornProviderType.SMTP, data, 'en');\n```\n\n# Library API\n\n## `send()`\n\nThe `send()` function, located in `airhorn.ts`, is used to send notifications. It accepts the following parameters:\n\n* `to` (string): The address to send the message to. Based on the message provider, this address can be either a phone number, an email address, or a web address.\n* `from` (string): The address of the sender of the message.\n* `templateName` (string): The name of the template to use for the message.\n* `providerType` (AirhornProviderType): The type of message to be sent. `AirhornProviderType` is an enum with the values `SMTP`, `SMS`, `WEBHOOK`, and `MOBILE_PUSH`.\n* `data` (any): The information to pass to the message. This parameter is typically a data object or a string. The data can include the raw message to be sent, or it can be used to populate a message template.\n* `languageCode` (string): The language code of the message template to be sent.\n\n## `sendSMTP()`\n\nThe `sendSMTP()` function, located in `airhorn.ts`, is used to send `SMTP` notifications. It accepts the following parameters:\n\n* `to` (string): The address to send the message to. Based on the message provider, this address can be either a phone number, an email address, or a web address.\n* `from` (string): The address of the sender of the message.\n* `templateName` (string): The name of the template to use for the message.\n* `data` (any): The information to pass to the message. This parameter is typically a data object or a string. The data can include the raw message to be sent, or it can be used to populate a message template.\n* `languageCode` (string): The language code of the message template to be sent.\n\n## `sendSMS()`\n\nThe `sendSMS()` function, located in `airhorn.ts`, is used to send `SMS` notifications. It accepts the following parameters:\n\n* `to` (string): The address to send the message to. Based on the message provider, this address can be either a phone number, an email address, or a web address.\n* `from` (string): The address of the sender of the message.\n* `templateName` (string): The name of the template to use for the message.\n* `data` (any): The information to pass to the message. This parameter is typically a data object or a string. The data can include the raw message to be sent, or it can be used to populate a message template.\n* `languageCode` (string): The language code of the message template to be sent.\n\n## `sendWebhook()`\n\nThe `sendWebhook()` function, located in `airhorn.ts`, is used to send `Webhook` notifications. It accepts the following parameters:\n\n* `to` (string): The address to send the message to. Based on the message provider, this address can be either a phone number, an email address, or a web address.\n* `from` (string): The address of the sender of the message.\n* `templateName` (string): The name of the template to use for the message.\n* `data` (any): The information to pass to the message. This parameter is typically a data object or a string. The data can include the raw message to be sent, or it can be used to populate a message template.\n* `languageCode` (string): The language code of the message template to be sent.\n\n## `sendMobilePush()`\n\nThe `sendMobilePush()` function, located in `airhorn.ts`, is used to send `Mobile Push` notifications. It accepts the following parameters:\n\n* `to` (string): The address to send the message to. Based on the message provider, this address can be either a phone number, an email address, or a web address.\n* `from` (string): The address of the sender of the message.\n* `templateName` (string): The name of the template to use for the message.\n* `data` (any): The information to pass to the message. This parameter is typically a data object or a string. The data can include the raw message to be sent, or it can be used to populate a message template.\n* `languageCode` (string): The language code of the message template to be sent.\n\n## `options`\n\nThe `AirhornOptions` enables you to configure the settings of Airhorn. It accepts the following parameters:\n\n* `TEMPLATE_PATH` (string): The path where the notification system checks for templates. By default, this is set to './templates'\n* `DEFAULT_TEMPLATE_LANGUAGE` (string): The default language code the notification system uses for localization, if a language code is not provided. By default, this is set to `en` for English localization.\n* `TWILIO_SMS_ACCOUNT_SID` (string): The ID of your Twilio SMS account. By default, this value is undefined.\n* `TWILIO_SMS_AUTH_TOKEN` (string): The authentication token for your Twilio SMS account. By default, this value is undefined.\n* `TWILIO_SENDGRID_API_KEY` (string): The API key for your Twilio SendGrid account. By default, this value is undefined.\n* `AWS_SES_REGION` (string): For AWS, the endpoint region where an email is sent. By default, this value is undefined.\n* `AWS_SMS_REGION` (string): For AWS, The endpoint region where an SMS is sent. By default, this value is undefined.\n* `AWS_SNS_REGION` (string): For AWS, the endpoint region where a push notification is sent. By default, this value is undefined.\n* `FIREBASE_CERT` (string): The certificate for sending push notifications through Google Firebase. By default, this value is undefined.\n* `TEMPLATE_PROVIDER` (AirhornTemplateProvider): The template provider to use. By default, this value is `MemoryTemplateProvider`.\n\nThese settings can be overridden by passing them in when you create a new instance of `Airhorn`:\n\n```javascript\nconst airhorn = new createAirhorn({\n    TEMPLATE_PATH: './templates',\n    DEFAULT_TEMPLATE_LANGUAGE: 'en',\n    TWILIO_SMS_ACCOUNT_SID: 'YOUR TWILIO ACCOUNT SID',\n    TWILIO_SMS_AUTH_TOKEN: 'YOUR TWILIO AUTH TOKEN',\n    TWILIO_SENDGRID_API_KEY: 'YOUR SENDGRID API KEY',\n    AWS_SES_REGION: 'YOUR AWS SES REGION',\n    AWS_SMS_REGION: 'YOUR AWS SMS REGION',\n    AWS_SNS_REGION: 'YOUR AWS SNS REGION',\n    FIREBASE_CERT: 'YOUR FIREBASE CERTIFICATE',\n    TEMPLATE_PROVIDER: 'YOUR TEMPLATE PROVIDER'\n});\n```\n\n# Templates\n\nThis library supports the use of templates to easily send formatted messages to different providers. Sample templates can be found in `test/templates` within the subdirectories `cool-multi-lingual`, `generic-template-foo`, and `multiple-types-bar`.\n\n## Language Localization\n\nWith templates, users can easily send messages in different languages. A sample architecture for language localized templates can be found in the `cool-multi-lingual` directory within `test/templates`. This directory contains folders for English and Spanish language codes, 'en' and 'es' respectively. Each of these directories contains SMS, SMTP, and Webhook templates in the appropriate language. To send notifications in a specific language, users can simply provide the appropriate `languageCode` parameter to the `send()` function.\n\n## Template Overrides\n\nWhen looking at the sample templates, we can see that some of them support word substitution. For example, the generic SMTP template looks like this:\n\n``` hbs\n\u003cp\u003eHello {{ firstName }} {{ lastName }}\u003c/p\u003e\n\u003cp\u003eYour email is {{ email }} and this is a generic template\u003c/p\u003e\n```\n\nTo substitute the appropriate text for `firstName`, `lastName`, and `email`, users can provide the appropriate data to the `send()` function. This data is then passed to the template and rendered automatically.\n\n# Template Providers (In Memory, MongoDB, Postgres)\n\nBy default Airhorn uses an in-memory provider called `MemoryTemplateProvider`. This is great for testing and quick use cases. Which means that you can load your templates into memory and use then. This is done when you call `createAirhorn()` with the `TEMPLATE_PATH` set.\n\n```javascript\nimport { createAirhorn } from 'airhorn';\nconst airhorn = new createAirhorn({ TEMPLATE_PATH: './your-template-path' });\n```\n\nIf you want to use `MongoDB` or `Postgres` you can use the `MongoTemplateProvider` or `PostgresTemplateProvider`. This is great for production and long running services. \n\n```javascript\nimport { createAirhorn, MongoTemplateProvider } from 'airhorn';\n\nconst airhorn = new createAirhorn({\n    TEMPLATE_PATH: './your-template-path',\n    TEMPLATE_PROVIDER: new MongoTemplateProvider('mongodb://localhost:27017', 'airhorn')\n});\n```\n\nYou can also do it by just passing in the uri note that the other options will be set to the defaults. :\n\n```javascript\nimport { createAirhorn } from 'airhorn';\n\nconst airhorn = new createAirhorn({\n    TEMPLATE_PATH: './your-template-path',\n    TEMPLATE_PROVIDER: 'postgres://localhost:5432/airhorn'\n});\n```\n\nOnce you load a specific provider you will want to sync your templates to the provider. This is done using the `syncTemplatesToAirhorn` function. \n\n```javascript\nimport { syncTemplatesToAirhorn, createAirhorn } from 'airhorn';\n\nconst airhorn = new createAirhorn({\n    TEMPLATE_PATH: './your-template-path',\n    TEMPLATE_PROVIDER: 'postgres://localhost:5432/airhorn'\n});\n\nawait syncTemplatesToAirhorn('./your-template-path', airhorn);\n```\n\n# File System Templates\n\nIn most cases we want to use the file system to store our templates for all the benefits of gitops and versioning. We have added good support for loading templates from the file system based on the following structure:\n\n```\ntemplates\n├── cool-multi-lingual\n│   ├── en\n│   │   ├── sms.hbs\n│   │   ├── smtp.hbs\n│   │   └── webhook.hbs\n│   └── es\n│       ├── sms.hbs\n│       ├── smtp.hbs\n│       └── webhook.hbs\n├── generic-template-foo\n│   ├── sms.hbs\n|   ├── smtp.hbs\n|   └── webhook.hbs\n```\n\nIn this example you can see that we have the template name `cool-multi-lingual` and then the language code `en` for English. Then we have the type of template `sms`, `smtp`, and `webhook`. This is the structure that we use to load templates from the file system.\n\nIf you do not need to support multiple languages you can just have the template name and the type of template like the example of `generic-template-foo`.\n\n# Examples for using this library\n\nThis library can be used to easily send a variety of notifications. In this section, we'll cover how to implement some simple use cases.\n\n## Sending a simple email\n\nUsing the send function, we can email 'john@doe.org' from 'hello@testing.com' using the generic template 'generic-template-foo'. We'll also use the provider type `AirhornProviderType.SMTP` to indicate that we're sending an email:\n\n```javascript\nimport { createAirhorn, AirhornProviderType } from 'airhorn';\nconst airhorn = new createAirhorn({ TEMPLATE_PATH: './your-template-path' });\nawait airhorn.send('john@doe.org', 'hello@testing.com', 'generic-template-foo', AirhornProviderType.SMTP);\n```\n\n## Sending a simple webhook\n\nHere, we'll send a simple webhook to the URL 'https://mockhttp.org/post':\n\n``` javascript\nconst airhorn = new createAirhorn({ TEMPLATE_PATH: './your-template-path' });\nairhorn.send('https://mockhttp.org/post', 'foo', 'bar', AirhornProviderType.WEBHOOK);\n```\n\n## Using multiple providers\n\nIn this example, we'll send a message using multiple email providers:\n\n1. Add in the AWS SES configuration\n2. Add in the Sendgrid configuration\n3. Send the message and it will randomly balance between the two providers.\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        AWS_SES_REGION = 'us-east-1',\n        TWILIO_SENDGRID_API_KEY = 'SENDGRID_API_KEY'\n\t});\n\nawait airhorn.send('john@doe.org', 'hello@testing.com', 'generic-template-foo', AirhornProviderType.SMTP);\n\n```\n\n# Supported Cloud Service Providers\n\nThis library supports sending notifications via email, SMS, and Mobile Push for the following providers:\n\n* Email: AWS SES and Twilio Sendgrid\n* SMS: AWS SMS and Twilio\n* Mobile Push: AWS SNS and Google Firebase\n\nIn this section, we'll describe how to use each of these notification services.\n\n## Email providers\n\nThis library supports sending emails via AWS SES and Twilio Sendgrid.\n\n## AWS SES\n\nAfter configuring your system to use AWS SES, you can easily use `airhorn` to send emails. In this example, we'll email 'john@doe.org' from 'hello@testing.com' using the email template 'generic-template-foo'. We'll list the provider type as `AirhornProviderType.SMTP` to indicate that we're sending an email:\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        AWS_SES_REGION = 'us-east-1',\n\t});\nawait airhorn.send('john@doe.org', 'hello@testing.com', 'generic-template-foo', AirhornProviderType.SMTP);\n```\n\n## Twilio Sendgrid\n\nTo send emails via Twilio Sendgrid, first update the `TWILIO_SENDGRID_API_KEY` value via `AirhornOptions`. Then, we can use the same syntax as above to send an email through Twilio Sendgrid:\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        TWILIO_SENDGRID_API_KEY = 'SENDGRID_API_KEY'\n\t});\nawait airhorn.send('john@doe.org', 'hello@testing.com', 'generic-template-foo', AirhornProviderType.SMTP);\n```\n\n## SMS providers\n\nThis library supports sending SMS using AWS SMS and Twilio.\n\n### AWS SMS\n\nOnce your system is configured to use AWS SMS, you can send SMS notifications through AWS SMS. In this example, we'll send the notification to the phone number '5555555555' from the number '5552223333' with the raw text data 'Test message text'. Then, we'll list the provider type as `AirhornProviderType.SMS`.\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        AWS_SMS_REGION = 'us-east-1',\n    });\nawait airhorn.send('5555555555', '5552223333', 'Test message text', AirhornProviderType.SMS);\n```\n\n### Twilio SMS\n\nTo send SMS notifications via Twilio SMS, first update the `TWILIO_SMS_ACCOUNT_SID` and the `TWILIO_SMS_AUTH_TOKEN` values via the `AirhornOptions` as shown below. Then, we can send an SMS notification using the same syntax as above:\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        TWILIO_SMS_ACCOUNT_SID = 'TWILIO_SMS_ACCOUNT_SID',\n        TWILIO_SMS_AUTH_TOKEN = 'TWILIO_SMS_AUTH_TOKEN'\n    });\nawait airhorn.send('5555555555', '5552223333', 'Test message text', AirhornProviderType.SMS);\n```\n\n## Mobile push providers\n\nThis library supports sending Mobile Push notifications using AWS SNS and Google Firebase.\n\n### AWS SNS\n\nTo use AWS SNS you will need to create a new SNS application in the AWS console and integrate the AWS SNS SDK into your application. \n\n1. [Obtain the credentials and device token](https://docs.aws.amazon.com/sns/latest/dg/sns-prerequisites-for-mobile-push-notifications.html) for the mobile platforms that you want to support.\n2. Use the credentials to create a platform application object (PlatformApplicationArn) using Amazon SNS. For more information, see [Creating a platform endpoint](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html). \n3. Use the returned credentials to request a device token for your mobile app and device from the mobile platforms. The token you receive represents your mobile app and device.\n4. Use the device token and the PlatformApplicationArn to create a platform endpoint object (EndpointArn) using Amazon SNS. For more information, see [Creating a platform endpoint](https://docs.aws.amazon.com/sns/latest/dg/mobile-platform-endpoint.html).\n\nThen, you can send the push message to the device endpoint using `airhorn`:\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        AWS_SNS_REGION = 'us-east-1',\n    });\nawait airhorn.send('endpointArn', '', 'generic-template-foo', AirhornProviderType.MOBILE_PUSH);\n```\n\n### Firebase for Mobile Push\n\nTo use Firebase in your application, you will need to create a new project in the Firebase console and integrate the Firebase SDK according to the [Firebase documentation](https://firebase.google.com/docs/cloud-messaging).\n\nIn your Firebase Project Settings, go to the `Service accounts` tab to generate your `private key` as a json file and put the content of the file as `FIREBASE_CERT` environment variable.\n\nThen, you can send the push message to the device endpoint using `airhorn`:\n\n```javascript\nconst airhorn = new createAirhorn({\n        TEMPLATE_PATH: './your-template-path',\n        FIREBASE_CERT = 'FIREBASE_CERT'\n    });\nawait airhorn.send('endpointArn', '', 'generic-template-foo', AirhornProviderType.MOBILE_PUSH);\n```\n\n# ESM and Node Version Support\n\nThis package is ESM only and tested on the current lts version and its previous. Please don't open issues for questions regarding CommonJS / ESM or previous Nodejs versions.\n\n# How to Contribute \n\nNow that you've set up your workspace, you're ready to contribute changes to the `airhorn` repository you can refer to the [CONTRIBUTING](CONTRIBUTING.md) guide. If you have any questions please feel free to ask by creating an issue and label it `question`.\n\n# Setting up your Development Environment\n\nTo set up your development environment, you'll need the following dependencies:\n* Node.js (latest)\n* Docker\n* Firebase Account (this is for the firebase-cert.json file)\n\nSet up your firebase account and generate the firebase-cert.json file. Then, place the file in the root of the project. This is needed even for testing as mocking the firebase-admin is almost impossible. After that you should run the following commands:\n\n```bash\nnpm i \u0026\u0026 npm run test:services:start \u0026\u0026 npm test\n```\n\nThis will start the services needed for testing and run the tests.\n\nTo stop the services, you can run:\n\n```bash\nnpm run test:services:stop\n```\n\nIf you are using `nvm` you can run the following:\n\n```bash\nnvm use \u0026\u0026 npm i \u0026\u0026 npm run test:services:start \u0026\u0026 npm test\n```\n\n# Licensing and Copyright\n\nThis project is [MIT License © Jared Wray](LICENSE)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredwray%2Fairhorn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaredwray%2Fairhorn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaredwray%2Fairhorn/lists"}