npm package: @janooma/jms-core
Description: Provider-based messaging core for Email and SMS with pluggable integrations
Latest version: 0.1.0

# @janooma/jms-core

Provider-driven messaging module for **Email** and **SMS**.

| Channel | Provider |
|---------|----------|
| Email   | [ZeptoMail](https://www.zoho.com/zeptomail/) (Zoho) |
| SMS     | [Zixflow](https://zixflow.com/) (OTP / Transactional) |

Credentials are injected at call time by your worker/service — nothing is hardcoded in this package.

---

## Install

```bash
npm install @janooma/jms-core
```

---

## Environment Variables

Create a `.env.local` file (already in `.gitignore`) with the following variables:

### Email — ZeptoMail

| Variable | Required | Description |
|---|---|---|
| `ZEPTOMAIL_API_KEY` | ✅ | API key from ZeptoMail dashboard |
| `ZEPTOMAIL_BASE_URL` | ✅ | API base URL, e.g. `https://api.zeptomail.in` |
| `ZEPTOMAIL_FROM` | ✅ | Verified sender email address |
| `ZEPTOMAIL_FROM_NAME` | ☑️ | Display name for sender |
| `ZEPTOMAIL_TO` | ✅ | Recipient email address |
| `ZEPTOMAIL_TO_NAME` | ☑️ | Display name for recipient |
| `ZEPTOMAIL_SUBJECT` | ☑️ | Email subject line |
| `ZEPTOMAIL_HTML` | ☑️ | HTML body |

### SMS — Zixflow

| Variable | Required | Description |
|---|---|---|
| `ZIXFLOW_API_KEY` | ✅ | API key from Zixflow dashboard |
| `ZIXFLOW_SENDER_ID` | ✅ | Registered sender ID (e.g. `JANOMA`) |
| `ZIXFLOW_ROUTE` | ✅ | Route type: `otp`, `transactional`, or `promotional` |
| `ZIXFLOW_TO` | ✅ | Recipient mobile number with country code, e.g. `919886627324` |
| `ZIXFLOW_MESSAGE` | ✅ | SMS message body |
| `ZIXFLOW_DLT_TEMPLATE_ID` | ☑️ | DLT template ID registered with your telecom operator |
| `ZIXFLOW_DLT_ENTITY_ID` | ☑️ | DLT entity ID registered with your telecom operator |

> ✅ Required &nbsp; ☑️ Optional

---

## Usage

### Send a plain email

```ts
import { EmailService, ZeptomailProvider } from '@janooma/jms-core';

const service = new EmailService(new ZeptomailProvider());

await service.sendEmail(
  {
    from: { email: 'noreply@janooma.com', name: 'Janooma' },
    to: [{ email: 'user@example.com', name: 'User Name' }],
    subject: 'Hello from Janooma',
    html: '<p>Welcome aboard!</p>',
  },
  {
    apiKey: env.ZEPTOMAIL_API_KEY,
    baseUrl: env.ZEPTOMAIL_BASE_URL,
  },
);
```

### Send a template email

Use `{{token}}` placeholders in `subject`, `html`, and `text`. They are replaced at send time with the `variables` map.

```ts
import { EmailService, ZeptomailProvider } from '@janooma/jms-core';

const service = new EmailService(new ZeptomailProvider());

await service.sendTemplateEmail(
  {
    from: { email: 'noreply@janooma.com', name: 'Janooma' },
    to: [{ email: 'user@example.com', name: 'Madan' }],
    template: {
      subject: 'Hi {{name}}, your OTP is ready',
      html: '<h1>Hello {{name}}</h1><p>Your OTP is <b>{{otp}}</b>. Never share it with anyone.</p>',
    },
    variables: {
      name: 'Madan',
      otp: 123456,
    },
  },
  {
    apiKey: env.ZEPTOMAIL_API_KEY,
    baseUrl: env.ZEPTOMAIL_BASE_URL,
  },
);
```

### Send an SMS (OTP)

```ts
import { SmsService, ZixflowProvider } from '@janooma/jms-core';

const service = new SmsService(new ZixflowProvider());

await service.sendSms(
  {
    to: '919886627324',
    message: 'Use 123456 to complete your transaction on JANOOMA. Never share your OTP with anyone.',
    route: 'otp',
    dltTemplateId: env.ZIXFLOW_DLT_TEMPLATE_ID,
    dltEntityId: env.ZIXFLOW_DLT_ENTITY_ID,
  },
  {
    apiKey: env.ZIXFLOW_API_KEY,
    senderId: env.ZIXFLOW_SENDER_ID,
  },
);
```

### Use MessagingClient (email + SMS together)

```ts
import { MessagingClient, ZeptomailProvider, ZixflowProvider } from '@janooma/jms-core';

const client = new MessagingClient({
  emailProvider: new ZeptomailProvider(),
  smsProvider: new ZixflowProvider(),
});

// Email
await client.email.sendTemplateEmail({ ... }, { apiKey, baseUrl });

// SMS
await client.sms.sendSms({ ... }, { apiKey, senderId });
```

---

## SendResult

Every send method returns a `SendResult`:

```ts
interface SendResult {
  success: boolean;
  provider: string;       // 'zeptomail' | 'zixflow'
  messageId?: string;
  error?: string;         // set when success is false
  raw?: unknown;          // full raw API response
}
```

---

## Package scripts

| Script | Description |
|---|---|
| `npm run build` | Compile TypeScript to `dist/` |
| `npm run typecheck` | Type-check without emitting |
| `npm run test` | Run unit tests |
| `npm run live:email` | Send a real email using `.env.local` |
| `npm run live:sms` | Send a real SMS using `.env.local` |

---

## Live test

Copy the example below into `.env.local` and fill in your credentials, then run the live scripts.

```bash
# ZeptoMail
ZEPTOMAIL_API_KEY=your-zeptomail-api-key
ZEPTOMAIL_BASE_URL=https://api.zeptomail.in
ZEPTOMAIL_FROM=noreply@yourdomain.com
ZEPTOMAIL_FROM_NAME=Your App
ZEPTOMAIL_TO=recipient@example.com
ZEPTOMAIL_TO_NAME=Recipient Name
ZEPTOMAIL_SUBJECT=Test Email
ZEPTOMAIL_HTML=<div><b>Test email sent successfully.</b></div>

# Zixflow
ZIXFLOW_API_KEY=your-zixflow-api-key
ZIXFLOW_SENDER_ID=YOURID
ZIXFLOW_ROUTE=otp
ZIXFLOW_TO=91xxxxxxxxxx
ZIXFLOW_MESSAGE=Use 123456 to complete your transaction. Never share your OTP.
ZIXFLOW_DLT_TEMPLATE_ID=your-dlt-template-id
ZIXFLOW_DLT_ENTITY_ID=your-dlt-entity-id
```

```bash
npm run live:email
npm run live:sms
```

---

## Publish

```bash
npm run build
npm login
npm publish --access public
```