All Projects → khaosdoctor → zaqar

khaosdoctor / zaqar

Licence: MIT license
Email microservice writen in Node.js

Programming Languages

HTML
75241 projects
typescript
32286 projects
shell
77523 projects
Dockerfile
14818 projects
javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to zaqar

release-notify-action
GitHub Action that triggers e-mails with release notes when these are created
Stars: ✭ 64 (+23.08%)
Mutual labels:  email-sender, sendgrid
Omnimail
Send email across all platforms using one interface
Stars: ✭ 325 (+525%)
Mutual labels:  email-sender, sendgrid
Mailer
A light-weight, modular, message representation and mail delivery framework for Python.
Stars: ✭ 225 (+332.69%)
Mutual labels:  email-sender, sendgrid
emailqueue
A fast, simple yet very efficient email queuing system for PHP/MySQL
Stars: ✭ 75 (+44.23%)
Mutual labels:  email-sender
Meteor-Mailer
📮 Bulletproof email queue on top of NodeMailer with support of multiple clusters and servers setup
Stars: ✭ 21 (-59.62%)
Mutual labels:  email-sender
Bon Voyage
A Hotel booking Android application. This app consists of a Google, Facebook and email login. Firebase is used as the database. The user can select the destination, select the hotel, and book the rooms there. After the booking process is complete, a confirmation email is sent to the user.
Stars: ✭ 19 (-63.46%)
Mutual labels:  email-sender
smart-email-support
Smart Email Support for Telecom Organisations - Provide automated customer support for emails
Stars: ✭ 19 (-63.46%)
Mutual labels:  sendgrid
wgpu-mc
Rust-based replacement for the default Minecraft renderer
Stars: ✭ 254 (+388.46%)
Mutual labels:  renderer
rottenjs
An all-in-one (2.6kb) Javascript library for web development
Stars: ✭ 15 (-71.15%)
Mutual labels:  renderer
Portfolio
A Next.js & Material UI portfolio that stylizes markdown files from the GitHub API and Contentful CMS.
Stars: ✭ 18 (-65.38%)
Mutual labels:  sendgrid
mailer
Generic mailer
Stars: ✭ 16 (-69.23%)
Mutual labels:  email-sender
polyred
📺 3D Graphics in Go.
Stars: ✭ 31 (-40.38%)
Mutual labels:  renderer
PicoRenderer
Low-Level, 8-bit Colored, 3D Software Renderer written in C99
Stars: ✭ 55 (+5.77%)
Mutual labels:  renderer
AyaRay
A Modern C++ Windows-platform physically based renderer developing by Chang Yu.
Stars: ✭ 29 (-44.23%)
Mutual labels:  renderer
onionSkinRenderer
This is an Onion Skin Renderer for Autodesk Maya
Stars: ✭ 93 (+78.85%)
Mutual labels:  renderer
manta-ray
An open source physically based renderer.
Stars: ✭ 604 (+1061.54%)
Mutual labels:  renderer
nautilus
another graphics engine
Stars: ✭ 16 (-69.23%)
Mutual labels:  renderer
Tetra3d
Tetra3D is a 3D hybrid software/hardware renderer made for games written in Go with Ebitengine.
Stars: ✭ 271 (+421.15%)
Mutual labels:  renderer
smtp-email-spoofer-py
Python 3.x based email spoofer
Stars: ✭ 134 (+157.69%)
Mutual labels:  email-sender
chisel
A library to sculpt text on any device that you can handle pixels
Stars: ✭ 37 (-28.85%)
Mutual labels:  renderer

Zaqar

Microservice to send emails

Summary

Considerations

This microservice was made because we often have problems sending emails or we need a default backend that will do this for us.

This is why Zaqar was built. To become a fast approach to email handling in Node using microservices.

Usage

Important: Zaqar is not meant to be used as a library, so there's no instalation instructions that eventually would led you to an npm install.

Docker

Zaqar was created to be a fully implemented microservice, in other words, you have to run it instead of installing it as a library, that's why there's a Docker Image you should pull and run within your infrastructure.

  • The image exposes port 3000

Helm Chart

Zaqar also comes with a helm chart so you can run it in a kubernetes infrastructure, this helm chart is located in this same repository so you can "run":

helm repo add zaqar https://lsantos.me/zaqar/helm

This is going to add Zaqar to your helm repo list. Then you can "run":

If you're running helm < 3.0 you should pass a --name:

helm install zaqar/zaqar --name=zaqar-mail-server --set "environment.SENDGRID_APIKEY=key" ...

Otherwise, if you are on Helm version >3.0:

helm install zaqar-mail-server zaqar/zaqar --set "environment.SENDGRID_APIKEY=key" ...

Zaqar is exposed locally only, this means you will not be able to access it externally unless you manually create an Ingress. This is due to the best practices where microservices should only communicate with each other in the local network

Heroku

Click the button below to deploy zaqar to Heroku

Deploy

Envs

You should set some environment variables:

  • SENDGRID_APIKEY: As of now, Zaqar only accepts Sendgrid as mail sender, so this is where you put your API key
  • DEFAULT_FROM_ADDRESS: The email to be the "from" address in case there's no from address in the email.
  • DEFAULT_FROM_NAME: The name to be the "from" name in case there's no name specified.
  • RENDERER_LIST: A space-separated list of renderer packages to be loaded on load (see renderers section for more details)
  • AUTH_USERNAME: If provided, will set the basic auth username
  • AUTH_PASSWORD: If provided, will set the basic auth password

Basic Authentication

If both AUTH_USERNAME and AUTH_PASSWORD are provided, Zaqar will enter the auth mode. This mode only allows requests with the Authorization Basic header set, if the user or the password do not match, the service will return 401.

If one of the two variables are not set, Zaqar will run in authless mode.

API

Zaqar only has the POST /send endpoint which takes the following "payload":

{
  "to": ["[email protected]"],
  "from": "[email protected]",
  "subject": "subject",
  "template": {
    "lang": "renderer-language", // Renderer to be used
    "text": "your {{template-like}} <% structure %>" // See renderer section
  },
  "cc": ["[email protected]"],
  "bcc": ["[email protected]"],
  "replyTo": "[email protected]"
}

You can also send "complex" email fields with given names:

{
  "to": [{email: "[email protected]", name: "Someone"}],
  "from": {email: "[email protected]", name: "Someone"},
  "subject": "subject",
  "template": {
    "lang": "renderer-language", // Renderer to be used
    "text": "your {{template-like}} <% structure %>" // See renderer section
  },
  "cc": ["[email protected]"],
  "bcc": ["[email protected]"],
  "replyTo": "[email protected]"
}

Only 'to', 'subject', 'template' fields are required.

Following the schema:

{
  type: 'object',
  properties: {
    from: { oneOf: [{ type: 'string', format: 'email' }, { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string', format: 'email' } } }] },
    to: {
      type: 'array',
      items: {
        anyOf: [{ type: 'string', format: 'email' }, { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string', format: 'email' } } }]
      }
    },
    subject: {
      type: 'string'
    },
    template: {
      type: 'object',
      properties: {
        text: { type: 'string' },
        lang: { type: 'string' }
      },
      additionalProperties: false,
      required: ['text', 'lang']
    },
    cc: {
      type: 'array',
      items: {
        anyOf: [{ type: 'string', format: 'email' }, { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string', format: 'email' } } }]
      }
    },
    data: {
      type: 'object'
    },
    replyTo: {
      oneOf: [{ type: 'string', format: 'email' }, { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string', format: 'email' } } }]
    },
    bcc: {
      type: 'array',
      items: {
        anyOf: [{ type: 'string', format: 'email' }, { type: 'object', properties: { name: { type: 'string' }, email: { type: 'string', format: 'email' } } }]
      }
    }
  },
  required: ['to', 'subject', 'template'],
  additionalProperties: false
}

The data key is reserved to template data variables, so if you have a variable called username in your email, you should send a { data: { username: "user" } } in the payload.

If from is not filled, then the value of DEFAULT_FROM_ADDRESS and DEFAULT_FROM_NAME variables will be used

In case there's no replyTo the from data will be used.

Which answers:

{
  "to": [
    "[email protected]"
  ],
  "from": "[email protected]",
  "subject": "test",
  "bcc": [],
  "cc": [],
  "template": "<p>test</p>"
}

The whole API is described at the api documentation

Renderer Plugins

Zaqar is extensible, which means you can use different renderers to render your email using different templating engines. The template engine to be used for an specific email is set by the lang key in the template object within the /send payload.

Loading a renderer

Renderers can be load by the environment variable called RENDERER_LIST, which receive a space-separated list of renderer package names. For example, if we wanted to load both the mustache and ejs template engines we could set it to: zaqar-renderer-mustache zaqar-renderer-ejs.

Renderers will be loaded everytime a new instance of Zaqar is spinned up. There's no cache, Zaqar uses NPM to install the packages within the strucutre.

If this environment variable is not set, Zaqar will set it to zaqar-renderer-mustache zaqar-renderer-ejs by default

Creating your own renderer

A renderer is just a simple JavaScript function which takes the following signature:

async function renderer (text: string, data: any = {}, renderer: typeof yourRenderer = yourRenderer): Promise<string>

The renderer parameter is completely optional and is there just for testing purposes

The file should export an object with the following keys:

{
  name: 'mustache', // name of the renderer, this will be the "lang" parameter in the API
  fn: renderFunction, // Function to be used as renderer
  errClass: MustacheRendererError // Any additional data you want to share with external libraries
}

Take a look at this example taken from Mustache Renderer for Zaqar:

import mustache from 'mustache'

export class MustacheRendererError extends Error {
  constructor (message: string) {
    super(`[Zaqar renderer error - Mustache]: ${message}`)
  }
}

async function renderFunction (text: string, data: any = {}, renderer: typeof mustache = mustache): Promise<string> {
  try {
    return renderer.render(text, data)
  } catch (error) {
    throw new MustacheRendererError(error.message)
  }
}

const rendererObj = {
  name: 'mustache',
  fn: renderFunction,
  errClass: MustacheRendererError
}

export default rendererObj
module.exports = rendererObj

Then publish on NPM using any name. Then add it to RENDERER_LIST to be loaded.

List of renderers

These are the currently supported renderers for Zaqar:

If you want to add yours, please send a PR :)

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].