mbnotify-app 1.0.0
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/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.js +84 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.js +80 -0
- package/package.json +37 -0
- package/src/index.ts +127 -0
- package/tsconfig.cjs.json +7 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface NotificationPayload {
|
|
2
|
+
title?: string;
|
|
3
|
+
body?: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
image?: string;
|
|
6
|
+
url?: string;
|
|
7
|
+
data?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Request notification permission (Expo)
|
|
11
|
+
*/
|
|
12
|
+
export declare function requestPermission(): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Subscribe to notifications and return token
|
|
15
|
+
*/
|
|
16
|
+
export declare function getToken(appName: string, brokerUrl?: string): Promise<string>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.requestPermission = requestPermission;
|
|
4
|
+
exports.getToken = getToken;
|
|
5
|
+
const mqtt_1 = require("mqtt");
|
|
6
|
+
const Notifications = require("expo-notifications");
|
|
7
|
+
const async_storage_1 = require("@react-native-async-storage/async-storage");
|
|
8
|
+
const DEFAULT_BROKER = "wss://broker.hivemq.com:8884/mqtt";
|
|
9
|
+
let client = null;
|
|
10
|
+
/**
|
|
11
|
+
* Request notification permission (Expo)
|
|
12
|
+
*/
|
|
13
|
+
async function requestPermission() {
|
|
14
|
+
const { status } = await Notifications.requestPermissionsAsync();
|
|
15
|
+
return status === "granted";
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Generate or retrieve device token
|
|
19
|
+
*/
|
|
20
|
+
async function generateToken() {
|
|
21
|
+
let token = await async_storage_1.default.getItem("mbnotify_token");
|
|
22
|
+
if (!token) {
|
|
23
|
+
token =
|
|
24
|
+
"dev_" +
|
|
25
|
+
Math.random().toString(36).substring(2) +
|
|
26
|
+
Date.now().toString(36);
|
|
27
|
+
await async_storage_1.default.setItem("mbnotify_token", token);
|
|
28
|
+
}
|
|
29
|
+
return token;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Connect MQTT broker
|
|
33
|
+
*/
|
|
34
|
+
function connectMQTT(brokerUrl) {
|
|
35
|
+
if (client)
|
|
36
|
+
return client;
|
|
37
|
+
client = mqtt_1.default.connect(brokerUrl, {
|
|
38
|
+
reconnectPeriod: 5000,
|
|
39
|
+
connectTimeout: 10000
|
|
40
|
+
});
|
|
41
|
+
client.on("connect", () => {
|
|
42
|
+
console.log("mbnotify app connected");
|
|
43
|
+
});
|
|
44
|
+
client.on("error", (err) => {
|
|
45
|
+
console.error("MQTT error:", err);
|
|
46
|
+
});
|
|
47
|
+
return client;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Show notification using Expo
|
|
51
|
+
*/
|
|
52
|
+
async function showNotification(payload) {
|
|
53
|
+
await Notifications.scheduleNotificationAsync({
|
|
54
|
+
content: {
|
|
55
|
+
title: payload.title || "",
|
|
56
|
+
body: payload.body || "",
|
|
57
|
+
data: payload.data || {}
|
|
58
|
+
},
|
|
59
|
+
trigger: null
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Subscribe to notifications and return token
|
|
64
|
+
*/
|
|
65
|
+
async function getToken(appName, brokerUrl = DEFAULT_BROKER) {
|
|
66
|
+
if (!appName) {
|
|
67
|
+
throw new Error("appName required");
|
|
68
|
+
}
|
|
69
|
+
const token = await generateToken();
|
|
70
|
+
const topic = `/${appName}/${token}/notification`;
|
|
71
|
+
const mqttClient = connectMQTT(brokerUrl);
|
|
72
|
+
mqttClient.subscribe(topic);
|
|
73
|
+
console.log("Subscribed:", topic);
|
|
74
|
+
mqttClient.on("message", async (_, message) => {
|
|
75
|
+
try {
|
|
76
|
+
const payload = JSON.parse(message.toString());
|
|
77
|
+
await showNotification(payload);
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error("Invalid notification payload", err);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
return token;
|
|
84
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface NotificationPayload {
|
|
2
|
+
title?: string;
|
|
3
|
+
body?: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
image?: string;
|
|
6
|
+
url?: string;
|
|
7
|
+
data?: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Request notification permission (Expo)
|
|
11
|
+
*/
|
|
12
|
+
export declare function requestPermission(): Promise<boolean>;
|
|
13
|
+
/**
|
|
14
|
+
* Subscribe to notifications and return token
|
|
15
|
+
*/
|
|
16
|
+
export declare function getToken(appName: string, brokerUrl?: string): Promise<string>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import mqtt from "mqtt";
|
|
2
|
+
import * as Notifications from "expo-notifications";
|
|
3
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
4
|
+
const DEFAULT_BROKER = "wss://broker.hivemq.com:8884/mqtt";
|
|
5
|
+
let client = null;
|
|
6
|
+
/**
|
|
7
|
+
* Request notification permission (Expo)
|
|
8
|
+
*/
|
|
9
|
+
export async function requestPermission() {
|
|
10
|
+
const { status } = await Notifications.requestPermissionsAsync();
|
|
11
|
+
return status === "granted";
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Generate or retrieve device token
|
|
15
|
+
*/
|
|
16
|
+
async function generateToken() {
|
|
17
|
+
let token = await AsyncStorage.getItem("mbnotify_token");
|
|
18
|
+
if (!token) {
|
|
19
|
+
token =
|
|
20
|
+
"dev_" +
|
|
21
|
+
Math.random().toString(36).substring(2) +
|
|
22
|
+
Date.now().toString(36);
|
|
23
|
+
await AsyncStorage.setItem("mbnotify_token", token);
|
|
24
|
+
}
|
|
25
|
+
return token;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Connect MQTT broker
|
|
29
|
+
*/
|
|
30
|
+
function connectMQTT(brokerUrl) {
|
|
31
|
+
if (client)
|
|
32
|
+
return client;
|
|
33
|
+
client = mqtt.connect(brokerUrl, {
|
|
34
|
+
reconnectPeriod: 5000,
|
|
35
|
+
connectTimeout: 10000
|
|
36
|
+
});
|
|
37
|
+
client.on("connect", () => {
|
|
38
|
+
console.log("mbnotify app connected");
|
|
39
|
+
});
|
|
40
|
+
client.on("error", (err) => {
|
|
41
|
+
console.error("MQTT error:", err);
|
|
42
|
+
});
|
|
43
|
+
return client;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Show notification using Expo
|
|
47
|
+
*/
|
|
48
|
+
async function showNotification(payload) {
|
|
49
|
+
await Notifications.scheduleNotificationAsync({
|
|
50
|
+
content: {
|
|
51
|
+
title: payload.title || "",
|
|
52
|
+
body: payload.body || "",
|
|
53
|
+
data: payload.data || {}
|
|
54
|
+
},
|
|
55
|
+
trigger: null
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Subscribe to notifications and return token
|
|
60
|
+
*/
|
|
61
|
+
export async function getToken(appName, brokerUrl = DEFAULT_BROKER) {
|
|
62
|
+
if (!appName) {
|
|
63
|
+
throw new Error("appName required");
|
|
64
|
+
}
|
|
65
|
+
const token = await generateToken();
|
|
66
|
+
const topic = `/${appName}/${token}/notification`;
|
|
67
|
+
const mqttClient = connectMQTT(brokerUrl);
|
|
68
|
+
mqttClient.subscribe(topic);
|
|
69
|
+
console.log("Subscribed:", topic);
|
|
70
|
+
mqttClient.on("message", async (_, message) => {
|
|
71
|
+
try {
|
|
72
|
+
const payload = JSON.parse(message.toString());
|
|
73
|
+
await showNotification(payload);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
console.error("Invalid notification payload", err);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return token;
|
|
80
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mbnotify-app",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "React Native (Expo) client for mbnotify MQTT push notifications",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "npm run build:esm && npm run build:cjs",
|
|
11
|
+
"build:esm": "tsc",
|
|
12
|
+
"build:cjs": "tsc -p tsconfig.cjs.json"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/esm/index.js",
|
|
17
|
+
"require": "./dist/cjs/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"mqtt",
|
|
22
|
+
"expo",
|
|
23
|
+
"react-native",
|
|
24
|
+
"push-notification",
|
|
25
|
+
"mbnotify"
|
|
26
|
+
],
|
|
27
|
+
"author": "Manoj Gowda",
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"mqtt": "^5.15.0",
|
|
31
|
+
"expo-notifications": "^0.28.0",
|
|
32
|
+
"@react-native-async-storage/async-storage": "^1.23.1"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"typescript": "^5.9.3"
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import mqtt from "mqtt";
|
|
2
|
+
import * as Notifications from "expo-notifications";
|
|
3
|
+
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
4
|
+
|
|
5
|
+
const DEFAULT_BROKER = "wss://broker.hivemq.com:8884/mqtt";
|
|
6
|
+
|
|
7
|
+
let client: mqtt.MqttClient | null = null;
|
|
8
|
+
|
|
9
|
+
export interface NotificationPayload {
|
|
10
|
+
title?: string
|
|
11
|
+
body?: string
|
|
12
|
+
icon?: string
|
|
13
|
+
image?: string
|
|
14
|
+
url?: string
|
|
15
|
+
data?: Record<string, any>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Request notification permission (Expo)
|
|
20
|
+
*/
|
|
21
|
+
export async function requestPermission(): Promise<boolean> {
|
|
22
|
+
|
|
23
|
+
const { status } = await Notifications.requestPermissionsAsync();
|
|
24
|
+
|
|
25
|
+
return status === "granted";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Generate or retrieve device token
|
|
30
|
+
*/
|
|
31
|
+
async function generateToken(): Promise<string> {
|
|
32
|
+
|
|
33
|
+
let token = await AsyncStorage.getItem("mbnotify_token");
|
|
34
|
+
|
|
35
|
+
if (!token) {
|
|
36
|
+
|
|
37
|
+
token =
|
|
38
|
+
"dev_" +
|
|
39
|
+
Math.random().toString(36).substring(2) +
|
|
40
|
+
Date.now().toString(36);
|
|
41
|
+
|
|
42
|
+
await AsyncStorage.setItem("mbnotify_token", token);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return token;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Connect MQTT broker
|
|
50
|
+
*/
|
|
51
|
+
function connectMQTT(brokerUrl: string): mqtt.MqttClient {
|
|
52
|
+
|
|
53
|
+
if (client) return client;
|
|
54
|
+
|
|
55
|
+
client = mqtt.connect(brokerUrl, {
|
|
56
|
+
reconnectPeriod: 5000,
|
|
57
|
+
connectTimeout: 10000
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
client.on("connect", () => {
|
|
61
|
+
console.log("mbnotify app connected");
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
client.on("error", (err) => {
|
|
65
|
+
console.error("MQTT error:", err);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return client;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Show notification using Expo
|
|
73
|
+
*/
|
|
74
|
+
async function showNotification(payload: NotificationPayload) {
|
|
75
|
+
|
|
76
|
+
await Notifications.scheduleNotificationAsync({
|
|
77
|
+
content: {
|
|
78
|
+
title: payload.title || "",
|
|
79
|
+
body: payload.body || "",
|
|
80
|
+
data: payload.data || {}
|
|
81
|
+
},
|
|
82
|
+
trigger: null
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Subscribe to notifications and return token
|
|
89
|
+
*/
|
|
90
|
+
export async function getToken(
|
|
91
|
+
appName: string,
|
|
92
|
+
brokerUrl: string = DEFAULT_BROKER
|
|
93
|
+
): Promise<string> {
|
|
94
|
+
|
|
95
|
+
if (!appName) {
|
|
96
|
+
throw new Error("appName required");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const token = await generateToken();
|
|
100
|
+
|
|
101
|
+
const topic = `/${appName}/${token}/notification`;
|
|
102
|
+
|
|
103
|
+
const mqttClient = connectMQTT(brokerUrl);
|
|
104
|
+
|
|
105
|
+
mqttClient.subscribe(topic);
|
|
106
|
+
|
|
107
|
+
console.log("Subscribed:", topic);
|
|
108
|
+
|
|
109
|
+
mqttClient.on("message", async (_, message) => {
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
|
|
113
|
+
const payload: NotificationPayload =
|
|
114
|
+
JSON.parse(message.toString());
|
|
115
|
+
|
|
116
|
+
await showNotification(payload);
|
|
117
|
+
|
|
118
|
+
} catch (err) {
|
|
119
|
+
|
|
120
|
+
console.error("Invalid notification payload", err);
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
return token;
|
|
127
|
+
}
|