medusajs-talksasa-sms-plugin 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # Medusajs Talksasa SMS plugin
2
+
3
+ [![Medusa Plugin](https://img.shields.io/badge/Medusa-Plugin-violet.svg)](https://medusajs.com/)
4
+ [![NPM Version](https://img.shields.io/npm/v/medusajs-talksasa-sms-plugin.svg)](https://www.npmjs.com/package/medusajs-talksasa-sms-plugin)
5
+
6
+ A robust, production-ready SMS notification provider plugin for **MedusaJS v2**.
7
+
8
+ This plugin seamlessly integrates the [Talksasa API](https://talksasa.com/) into your Medusa store's Notification Module, allowing you to send transactional SMS messages (like order confirmations, shipping updates, and verification codes) to your customers globally.
9
+
10
+ ---
11
+
12
+ ## 🌟 Features
13
+
14
+ - **Native Medusa v2 Support**: Built specifically for the Medusa v2 Notification Module architecture (`AbstractNotificationProviderService`).
15
+ - **Cost Saving Guardrails**: Automatically skips sending (and bypasses API calls) if a customer's phone number is missing, preventing unnecessary API errors or costs.
16
+ - **Omni-Channel Ready**: Designed to work flawlessly alongside Email and WhatsApp notification providers in your global subscribers.
17
+ - **Simple Configuration**: Plugs directly into your `medusa-config.ts` without complex setup.
18
+
19
+ ## 📋 Prerequisites
20
+
21
+ - [Medusa backend](https://docs.medusajs.com/) (version 2.0.0 or higher)
22
+ - A [Talksasa](https://talksasa.com/) account with an active API Token and registered Sender ID.
23
+
24
+ ## 🚀 Installation
25
+
26
+ Install the plugin using your preferred package manager in your Medusa backend project:
27
+
28
+ ```bash
29
+ npm install medusajs-talksasa-sms-plugin
30
+ # or
31
+ yarn add medusajs-talksasa-sms-plugin
32
+ ```
33
+
34
+ ## ⚙️ Configuration
35
+
36
+ ### 1. Environment Variables
37
+
38
+ Add your Talksasa API credentials to your Medusa backend's `.env` file. You can find these in your Talksasa developer dashboard.
39
+
40
+ *(Note: Ensure your API Token includes the ID prefix if provided, e.g., `3318|cjVm7zz...`)*
41
+
42
+ ```env
43
+ TALKSASA_API_TOKEN=your_full_talksasa_api_token
44
+ TALKSASA_SENDER_ID=your_registered_sender_id
45
+ ```
46
+
47
+ ### 2. Medusa Config
48
+
49
+ Next, register the plugin in your `medusa-config.ts` file under the Notification Module:
50
+
51
+ ```typescript
52
+ import { loadEnv, defineConfig } from '@medusajs/framework/utils'
53
+ import { Modules } from "@medusajs/framework/utils"
54
+
55
+ loadEnv(process.env.NODE_ENV || 'development', process.cwd())
56
+
57
+ module.exports = defineConfig({
58
+ projectConfig: {
59
+ // ... your standard project config
60
+ },
61
+ modules: [
62
+ {
63
+ resolve: Modules.NOTIFICATION,
64
+ options: {
65
+ providers: [
66
+ // ... your other providers (e.g. Resend, SendGrid)
67
+ {
68
+ resolve: "medusajs-talksasa-sms-plugin",
69
+ id: "talksasa-sms",
70
+ options: {
71
+ channels: ["sms"],
72
+ apiToken: process.env.TALKSASA_API_TOKEN,
73
+ senderId: process.env.TALKSASA_SENDER_ID,
74
+ },
75
+ },
76
+ ],
77
+ },
78
+ },
79
+ ],
80
+ })
81
+ ```
82
+
83
+ ## 💻 Usage Example
84
+
85
+ Once installed, the plugin listens for notification requests directed to the `"sms"` channel.
86
+
87
+ You can dispatch SMS notifications directly from your Medusa Workflows or Subscribers. The plugin will automatically extract the plain-text message from the `text` field in your `data` payload.
88
+
89
+ ### In a Subscriber
90
+
91
+ ```typescript
92
+ import { SubscriberArgs } from "@medusajs/framework"
93
+ import { Modules } from "@medusajs/framework/utils"
94
+ import { INotificationModuleService } from "@medusajs/framework/types"
95
+
96
+ export default async function orderPlacedHandler({
97
+ event,
98
+ container,
99
+ }: SubscriberArgs<any>) {
100
+ const notificationModuleService: INotificationModuleService = container.resolve(Modules.NOTIFICATION)
101
+
102
+ const customerPhoneNumber = "254700000000" // Fetch this from your order/customer data
103
+
104
+ await notificationModuleService.createNotifications({
105
+ to: customerPhoneNumber,
106
+ channel: "sms",
107
+ template: "order-placed-sms", // Required by Medusa type definitions
108
+ data: {
109
+ text: `Great news! Your order #${event.data.id} has been placed successfully.`,
110
+ },
111
+ })
112
+ }
113
+ ```
114
+
115
+ ## 🤝 Contributing
116
+
117
+ Contributions are welcome! If you find a bug or have a feature request, please open an issue on the repository.
118
+
119
+ ## 📄 License
120
+
121
+ This project is licensed under the MIT License.
@@ -0,0 +1,2 @@
1
+ declare const _default: import("@medusajs/types").ModuleProviderExports;
2
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const service_1 = __importDefault(require("./service"));
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.NOTIFICATION, {
9
+ services: [service_1.default],
10
+ });
@@ -0,0 +1,16 @@
1
+ import { AbstractNotificationProviderService } from "@medusajs/framework/utils";
2
+ import { ProviderSendNotificationDTO, ProviderSendNotificationResultsDTO } from "@medusajs/types";
3
+ type InjectedDependencies = {};
4
+ export type TalksasaSmsServiceOptions = {
5
+ apiToken: string;
6
+ senderId: string;
7
+ };
8
+ export declare class TalksasaSmsService extends AbstractNotificationProviderService {
9
+ static readonly identifier = "talksasa-sms";
10
+ private readonly apiToken;
11
+ private readonly senderId;
12
+ constructor(container: InjectedDependencies, options: TalksasaSmsServiceOptions);
13
+ static validateOptions(options: Record<any, any>): void | never;
14
+ send(notification: ProviderSendNotificationDTO): Promise<ProviderSendNotificationResultsDTO>;
15
+ }
16
+ export default TalksasaSmsService;
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TalksasaSmsService = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ class TalksasaSmsService extends utils_1.AbstractNotificationProviderService {
6
+ static identifier = "talksasa-sms";
7
+ apiToken;
8
+ senderId;
9
+ constructor(container, options) {
10
+ super();
11
+ this.apiToken = options.apiToken;
12
+ this.senderId = options.senderId;
13
+ }
14
+ static validateOptions(options) {
15
+ if (!options.apiToken) {
16
+ throw new Error("apiToken is required for talksasa-sms notification provider");
17
+ }
18
+ if (!options.senderId) {
19
+ throw new Error("senderId is required for talksasa-sms notification provider");
20
+ }
21
+ }
22
+ async send(notification) {
23
+ const { to, content, template, data } = notification;
24
+ if (!to || to.trim() === "") {
25
+ return {
26
+ id: `talksasa-skipped-${Date.now()}`
27
+ };
28
+ }
29
+ // For SMS, we typically just use the content text directly.
30
+ const contentText = content?.text || data?.text || `Notification from template: ${template}`;
31
+ try {
32
+ const response = await fetch("https://bulksms.talksasa.com/api/v3/sms/send", {
33
+ method: "POST",
34
+ headers: {
35
+ "Authorization": `Bearer ${this.apiToken}`,
36
+ "Content-Type": "application/json",
37
+ "Accept": "application/json"
38
+ },
39
+ body: JSON.stringify({
40
+ recipient: to,
41
+ sender_id: this.senderId,
42
+ type: "plain",
43
+ message: contentText
44
+ })
45
+ });
46
+ const responseData = await response.json();
47
+ if (responseData.status === "error") {
48
+ throw new Error(responseData.message || "Unknown error from Talksasa API");
49
+ }
50
+ return {
51
+ // Talksasa returns a contact object in data, which might contain an id
52
+ // We can just return a generic success id or extract it if available
53
+ id: responseData.data?.uid || `talksasa-${Date.now()}`,
54
+ };
55
+ }
56
+ catch (error) {
57
+ throw new Error(`Failed to send SMS via Talksasa: ${error.message}`);
58
+ }
59
+ }
60
+ }
61
+ exports.TalksasaSmsService = TalksasaSmsService;
62
+ exports.default = TalksasaSmsService;
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "medusajs-talksasa-sms-plugin",
3
+ "version": "1.0.3",
4
+ "description": "Talksasa SMS Notification Provider for MedusaJS",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "package.json",
10
+ "README.md"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc"
14
+ },
15
+ "keywords": [
16
+ "medusa",
17
+ "medusa-plugin",
18
+ "medusa-notification",
19
+ "medusa-v2",
20
+ "talksasa",
21
+ "sms",
22
+ "notification",
23
+ "ecommerce"
24
+ ],
25
+ "author": "Medusa Community",
26
+ "license": "MIT",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/urbandevicecare/medusa-plugin-talksasa-sms.git"
30
+ },
31
+ "bugs": {
32
+ "url": "https://github.com/urbandevicecare/medusa-plugin-talksasa-sms/issues"
33
+ },
34
+ "dependencies": {},
35
+ "devDependencies": {
36
+ "@medusajs/framework": "^2.0.0",
37
+ "@medusajs/types": "^2.0.0",
38
+ "typescript": "^5.3.3"
39
+ },
40
+ "peerDependencies": {
41
+ "@medusajs/framework": "^2.0.0"
42
+ }
43
+ }