tripstorekrabi-shared 1.25.6 → 1.25.7
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/package.json +4 -4
- package/telegram.js +73 -28
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tripstorekrabi-shared",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.7",
|
|
4
4
|
"description": "Shared library for Trip Store Krabi",
|
|
5
5
|
"author": "Stefan Sommer <tonprince@gmail.com>",
|
|
6
6
|
"repository": {
|
|
@@ -17,10 +17,10 @@
|
|
|
17
17
|
"./telegram": "./telegram.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"dayjs": "^1.11.
|
|
21
|
-
"libphonenumber-js": "^1.13.
|
|
20
|
+
"dayjs": "^1.11.23",
|
|
21
|
+
"libphonenumber-js": "^1.13.12",
|
|
22
22
|
"nanoid": "^6.0.1",
|
|
23
|
-
"firebase-admin": "^14.
|
|
23
|
+
"firebase-admin": "^14.3.0"
|
|
24
24
|
},
|
|
25
25
|
"scripts": {
|
|
26
26
|
"deploy": "npm publish"
|
package/telegram.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
1
|
+
const getEnv = (key) => typeof process !== 'undefined' && process.env ? process.env[key] : undefined;
|
|
2
|
+
|
|
3
|
+
const ENV_BOT_TOKEN = getEnv('TELEGRAM_API_TOKEN') || getEnv('PUBLIC_TELEGRAM_API_TOKEN');
|
|
4
|
+
const ENV_CHAT_ID = getEnv('TELEGRAM_CHAT_ID');
|
|
3
5
|
const TELEGRAM_MAX_CHARS = 4096;
|
|
4
6
|
|
|
5
7
|
export async function sendTelegramMessage(message, options = {}) {
|
|
@@ -8,14 +10,18 @@ export async function sendTelegramMessage(message, options = {}) {
|
|
|
8
10
|
chatId,
|
|
9
11
|
parseMode = 'HTML',
|
|
10
12
|
prefix = '',
|
|
11
|
-
truncate = true
|
|
13
|
+
truncate = true,
|
|
14
|
+
maxRetries = 3,
|
|
15
|
+
throwOnError = true
|
|
12
16
|
} = options;
|
|
13
17
|
|
|
14
18
|
const BOT_TOKEN = botToken || ENV_BOT_TOKEN;
|
|
15
19
|
const CHAT_ID = chatId || ENV_CHAT_ID;
|
|
16
20
|
|
|
17
21
|
if (!BOT_TOKEN || !CHAT_ID) {
|
|
18
|
-
|
|
22
|
+
const errorMsg = "FATAL: Telegram secrets are not configured in options or the environment.";
|
|
23
|
+
console.error(errorMsg);
|
|
24
|
+
if (throwOnError) throw new Error(errorMsg);
|
|
19
25
|
return false;
|
|
20
26
|
}
|
|
21
27
|
|
|
@@ -28,33 +34,72 @@ export async function sendTelegramMessage(message, options = {}) {
|
|
|
28
34
|
console.warn(`Message truncated from ${message.length} to ${TELEGRAM_MAX_CHARS} characters.`);
|
|
29
35
|
}
|
|
30
36
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
37
|
+
const telegramApiUrl = `https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`;
|
|
38
|
+
const fetchOptions = {
|
|
39
|
+
method: 'POST',
|
|
40
|
+
headers: {
|
|
41
|
+
'Content-Type': 'application/json'
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify({
|
|
34
44
|
chat_id: CHAT_ID,
|
|
35
45
|
text: finalMessage,
|
|
36
46
|
parse_mode: parseMode.toUpperCase(),
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
})
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
51
|
+
try {
|
|
52
|
+
const res = await fetch(telegramApiUrl, fetchOptions);
|
|
53
|
+
|
|
54
|
+
if (res.ok) {
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const json = await res.json().catch(() => null);
|
|
59
|
+
|
|
60
|
+
if (res.status === 429 && json?.parameters?.retry_after) {
|
|
61
|
+
const retryAfterSeconds = json.parameters.retry_after;
|
|
62
|
+
const waitTimeMs = (retryAfterSeconds + 1) * 1000;
|
|
63
|
+
|
|
64
|
+
console.warn(`Telegram Rate Limit hit. Retrying after ${retryAfterSeconds}s...`);
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, waitTimeMs));
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let errorMessage = 'Telegram API request failed';
|
|
70
|
+
if (json?.description) {
|
|
71
|
+
errorMessage = json.description;
|
|
72
|
+
} else if (typeof json?.error === 'string') {
|
|
73
|
+
errorMessage = json.error;
|
|
74
|
+
} else if (json?.error?.message) {
|
|
75
|
+
errorMessage = json.error.message;
|
|
76
|
+
} else {
|
|
77
|
+
errorMessage = `HTTP ${res.status}: ${res.statusText || 'Unknown Error'}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
throw new Error(`An error occurred while communicating with Telegram:\n${errorMessage}`);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
const safeError = err instanceof Error ? err : new Error(String(err));
|
|
83
|
+
const msg = safeError.message || '';
|
|
84
|
+
|
|
85
|
+
if (msg.includes('communicating with Telegram') && !msg.includes('429')) {
|
|
86
|
+
if (throwOnError) throw safeError;
|
|
87
|
+
console.error(safeError);
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (attempt === maxRetries - 1) {
|
|
92
|
+
if (throwOnError) throw safeError;
|
|
93
|
+
console.error(safeError);
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await new Promise((resolve) => setTimeout(resolve, 1000 * (attempt + 1)));
|
|
55
98
|
}
|
|
56
|
-
} catch (e) {
|
|
57
|
-
console.error('An error occurred while trying to send a Telegram message:', e);
|
|
58
|
-
return false;
|
|
59
99
|
}
|
|
100
|
+
|
|
101
|
+
const timeoutError = new Error('Telegram request failed: Exceeded maximum retries.');
|
|
102
|
+
if (throwOnError) throw timeoutError;
|
|
103
|
+
console.error(timeoutError);
|
|
104
|
+
return false;
|
|
60
105
|
}
|