@jsm-mit/whatsapp-package 0.0.1
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 +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/whatsapp.service.d.ts +15 -0
- package/dist/whatsapp.service.d.ts.map +1 -0
- package/dist/whatsapp.service.js +140 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
## Whatapp-package
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Observable } from 'rxjs';
|
|
2
|
+
import type { Pigeon } from '@jsm-mit/pigeon-package';
|
|
3
|
+
export declare class WhatsAppService {
|
|
4
|
+
private pigeon;
|
|
5
|
+
private readonly createdAt;
|
|
6
|
+
private waClient;
|
|
7
|
+
private readonly messageSubject;
|
|
8
|
+
get messages$(): Observable<any[]>;
|
|
9
|
+
constructor(pigeon: Pigeon);
|
|
10
|
+
private formatUptime;
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
sendMessageAsyncSafe(to: string, body: string): Promise<void>;
|
|
13
|
+
isRegisteredAsyncSafe(number: string): Promise<boolean>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=whatsapp.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.service.d.ts","sourceRoot":"","sources":["../src/whatsapp.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAW,MAAM,MAAM,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAItD,qBAAa,eAAe;IAWpB,OAAO,CAAC,MAAM;IATlB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsB;IAChD,OAAO,CAAC,QAAQ,CAAM;IACtB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAwB;IAEvD,IAAW,SAAS,IAAI,UAAU,CAAC,GAAG,EAAE,CAAC,CAExC;gBAGW,MAAM,EAAE,MAAM;IAI1B,OAAO,CAAC,YAAY;IAcb,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAgHrB,oBAAoB,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc7D,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAQvE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import pkg from 'whatsapp-web.js';
|
|
2
|
+
import qrcode from 'qrcode-terminal';
|
|
3
|
+
import { Observable, Subject } from 'rxjs';
|
|
4
|
+
import { toJson, polandTimeOptions, serverTimeOptions } from '@jsm-mit/utils-package';
|
|
5
|
+
const { Client: WAClient, LocalAuth } = pkg;
|
|
6
|
+
export class WhatsAppService {
|
|
7
|
+
get messages$() {
|
|
8
|
+
return this.messageSubject.asObservable();
|
|
9
|
+
}
|
|
10
|
+
constructor(pigeon) {
|
|
11
|
+
this.pigeon = pigeon;
|
|
12
|
+
this.createdAt = Date.now();
|
|
13
|
+
this.messageSubject = new Subject();
|
|
14
|
+
}
|
|
15
|
+
formatUptime(ms) {
|
|
16
|
+
const totalMinutes = Math.floor(ms / 60000);
|
|
17
|
+
const days = Math.floor(totalMinutes / 1440);
|
|
18
|
+
const hours = Math.floor((totalMinutes % 1440) / 60);
|
|
19
|
+
const minutes = totalMinutes % 60;
|
|
20
|
+
const parts = [];
|
|
21
|
+
if (days > 0)
|
|
22
|
+
parts.push(`${days} day${days === 1 ? '' : 's'}`);
|
|
23
|
+
if (hours > 0)
|
|
24
|
+
parts.push(`${hours} hour${hours === 1 ? '' : 's'}`);
|
|
25
|
+
if (minutes > 0 || parts.length === 0)
|
|
26
|
+
parts.push(`${minutes} minute${minutes === 1 ? '' : 's'}`);
|
|
27
|
+
return parts.join(' ');
|
|
28
|
+
}
|
|
29
|
+
initialize() {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
if (this.waClient) {
|
|
32
|
+
console.warn("WhatsApp client is already initialized.");
|
|
33
|
+
return resolve();
|
|
34
|
+
}
|
|
35
|
+
this.pigeon.reportInfoAsyncSafe('Log in to WhatsApp by scanning the QR code in the terminal required.', '');
|
|
36
|
+
this.waClient = new WAClient({
|
|
37
|
+
authStrategy: new LocalAuth(),
|
|
38
|
+
puppeteer: {
|
|
39
|
+
headless: true,
|
|
40
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu']
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
this.waClient.on('qr', (qr) => {
|
|
44
|
+
console.log("QR code received, please scan it with your WhatsApp app:");
|
|
45
|
+
qrcode.generate(qr, { small: true });
|
|
46
|
+
});
|
|
47
|
+
this.waClient.on('ready', async () => {
|
|
48
|
+
try {
|
|
49
|
+
const uptime = this.formatUptime(Date.now() - this.createdAt);
|
|
50
|
+
await this.sendMessageAsyncSafe("48601926367", `⚠️ Common Notifier is up for ${uptime}`);
|
|
51
|
+
resolve();
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
this.pigeon.reportUrgentAsyncSafe('Whatsapp Service Error', toJson(err));
|
|
55
|
+
console.error('❌ Error handling "ready" event:');
|
|
56
|
+
console.error(toJson(err));
|
|
57
|
+
reject(err);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
this.waClient.on('auth_failure', (msg) => {
|
|
62
|
+
this.pigeon.reportUrgentAsyncSafe('Whatsapp Service Error - auth_failure', msg);
|
|
63
|
+
console.error(`❌ WhatsApp authentication failure: ${msg}`);
|
|
64
|
+
return reject(new Error(`Authentication failure: ${msg}`));
|
|
65
|
+
});
|
|
66
|
+
this.waClient.on('error', (err) => {
|
|
67
|
+
this.pigeon.reportUrgentAsyncSafe('Whatsapp Service Error - error', toJson(err));
|
|
68
|
+
console.error('❌ WhatsApp client error');
|
|
69
|
+
console.error(toJson(err));
|
|
70
|
+
return reject(err);
|
|
71
|
+
});
|
|
72
|
+
this.waClient.on('disconnected', (reason) => {
|
|
73
|
+
this.pigeon.reportUrgentAsyncSafe('Whatsapp Service Warning - disconnected', reason);
|
|
74
|
+
console.warn(`⚠️ WhatsApp disconnected: ${reason}`);
|
|
75
|
+
});
|
|
76
|
+
this.waClient.initialize().catch((err) => {
|
|
77
|
+
this.pigeon.reportUrgentAsyncSafe('Error initializing WhatsApp', toJson(err));
|
|
78
|
+
console.error('❌ Cannot initialize WhatsApp client');
|
|
79
|
+
console.error(toJson(err));
|
|
80
|
+
return reject(err);
|
|
81
|
+
});
|
|
82
|
+
this.waClient.on('message', async (message) => {
|
|
83
|
+
console.log(`[WhatsApp] Received message from ${message.from}: ${message.body}`);
|
|
84
|
+
if (message.body.toLowerCase() === 'ping') {
|
|
85
|
+
message.reply('pong').catch((err) => {
|
|
86
|
+
this.pigeon.reportUrgentAsyncSafe(`Error sending ping response`, toJson(err));
|
|
87
|
+
console.error('❌ Error sending ping response');
|
|
88
|
+
console.error(toJson(err));
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (message.body.toLowerCase() === 'test') {
|
|
93
|
+
this.sendMessageAsyncSafe("48601926367", `Test successful, application is up since ${new Date(this.createdAt).toLocaleDateString('pl-PL', polandTimeOptions)}, server time: ${new Date(this.createdAt).toLocaleTimeString('pl-PL', serverTimeOptions)}`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// if (message.body.toLowerCase() === 'roundtrip') {
|
|
97
|
+
// this.sendMessageAsyncSafe(
|
|
98
|
+
// "48601926367",
|
|
99
|
+
// `Roundtrip test started at ${new Date().toLocaleDateString('pl-PL', polandTimeOptions)}`
|
|
100
|
+
// );
|
|
101
|
+
// const args: AddTaskArgs = {
|
|
102
|
+
// channel: this.channel,
|
|
103
|
+
// payload: `Roundtrip test successful`,
|
|
104
|
+
// parentIds: []
|
|
105
|
+
// };
|
|
106
|
+
// await this.actor.addTaskAsync(args, true).catch((err: any) => {
|
|
107
|
+
// this.pigeon.reportUrgentAsyncSafe(`Error adding task`, toJson(err));
|
|
108
|
+
// console.error('❌ Error adding task');
|
|
109
|
+
// console.error(toJson(err));
|
|
110
|
+
// });
|
|
111
|
+
// return;
|
|
112
|
+
// }
|
|
113
|
+
const chat = await this.waClient.getChatById(message.from);
|
|
114
|
+
const messages = await chat.fetchMessages({ limit: 10 });
|
|
115
|
+
this.messageSubject.next(messages);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
async sendMessageAsyncSafe(to, body) {
|
|
120
|
+
try {
|
|
121
|
+
const chatId = to.includes('@c.us') ? to : `${to}@c.us`;
|
|
122
|
+
await this.waClient.sendMessage(chatId, body);
|
|
123
|
+
console.log(`[WhatsApp] Message sent successfully to: ${to}`);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
this.pigeon.reportUrgentAsyncSafe(`[WhatsApp] Error sending to ${to}`, toJson(err));
|
|
127
|
+
console.error(`[WhatsApp] Error sending to ${to}`);
|
|
128
|
+
console.error(toJson(err));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async isRegisteredAsyncSafe(number) {
|
|
132
|
+
try {
|
|
133
|
+
const chatId = number.includes('@c.us') ? number : `${number}@c.us`;
|
|
134
|
+
return await this.waClient.isRegisteredUser(chatId);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jsm-mit/whatsapp-package",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"homepage": "https://github.com/JSM-Common/whatsapp-package#readme",
|
|
6
|
+
"bugs": {
|
|
7
|
+
"url": "https://github.com/JSM-Common/whatsapp-package/issues"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/JSM-Common/whatsapp-package.git"
|
|
12
|
+
},
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"author": "",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "dist/index.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"types": "./dist/index.d.ts"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist/"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "tsc --build",
|
|
29
|
+
"clean": "rimraf dist",
|
|
30
|
+
"prepare": "npm run build",
|
|
31
|
+
"publish-public": "npm install && npm login && npm publish --access public",
|
|
32
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"qrcode-terminal": "0.12.0",
|
|
36
|
+
"whatsapp-web.js": "1.34.6"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"@jsm-mit/pigeon-package": "0.0.12",
|
|
40
|
+
"@jsm-mit/utils-package": "0.0.15"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@types/qrcode-terminal": "^0.12.2",
|
|
44
|
+
"typescript": "^6.0.2"
|
|
45
|
+
}
|
|
46
|
+
}
|