Skip to content

Commit 9f90dbc

Browse files
committed
feat: adds pushes to telegram
1 parent be088bb commit 9f90dbc

File tree

6 files changed

+93
-11
lines changed

6 files changed

+93
-11
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
MONGODB_URI=
2+
BOT_API_TOKEN=
3+
TELEGRAM_CHAT_ID=

global.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
declare global {
2+
namespace NodeJs {
3+
interface ProcessEnv {
4+
MONGODB_URI?: string;
5+
BOT_API_TOKEN?: string;
6+
TELEGRAM_CHAT_ID?: string;
7+
}
8+
}
9+
}

scripts/commands/handlers/updateUsageData.ts

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,32 @@
11
import { FeatureModel } from '@/server/models/features';
22
import { FeatureUpdateModel } from '@/server/models/featureUpdates';
33
import { FeatureSchemaNoTimeType } from '@/server/schemas/featureSchema';
4-
import { FeatureUpdateType } from '@/server/schemas/featureUpdateSchema';
4+
import {
5+
FeatureUpdateType,
6+
FeatureUpdateSchemaNoTimeType,
7+
} from '@/server/schemas/featureUpdateSchema';
58

69
import { getLastUsageDataVersion } from '../utils/getLastUsageDataVersion';
10+
import { sendMessageToTelegram } from '../utils/sendMessageToTelegram';
711

8-
export async function updateUsageData(initial: boolean) {
12+
type NotificationUpdate = FeatureUpdateSchemaNoTimeType;
13+
14+
type Params = {
15+
initial: boolean;
16+
sendToTelegram: boolean;
17+
};
18+
19+
export async function updateUsageData({ initial, sendToTelegram }: Params) {
920
if (initial) {
1021
await FeatureModel.deleteMany({});
1122
await FeatureUpdateModel.deleteMany({});
1223
}
1324

25+
const notificationUpdates: Record<FeatureUpdateType, NotificationUpdate[]> = {
26+
twoPercent: [],
27+
threePercent: [],
28+
};
29+
1430
for await (const lastFeatureData of getLastUsageDataVersion()) {
1531
const dbFeatureData = await FeatureModel.findById(lastFeatureData._id).exec();
1632

@@ -38,14 +54,36 @@ export async function updateUsageData(initial: boolean) {
3854
continue;
3955
}
4056

41-
await FeatureUpdateModel.create({
57+
const featureUpdate: FeatureUpdateSchemaNoTimeType = {
4258
key: lastFeatureData._id,
4359
title: lastFeatureData.title,
4460
updateType: lastDataUpdateType,
45-
});
61+
};
62+
63+
if (sendToTelegram) {
64+
notificationUpdates[lastDataUpdateType].push(featureUpdate);
65+
}
66+
67+
await FeatureUpdateModel.create(featureUpdate);
4668
console.info(`Feature "${lastFeatureData._id}" updated with "${lastDataUpdateType}" type`);
4769
}
4870
}
71+
72+
if (sendToTelegram && notificationUpdates.threePercent.length > 0) {
73+
const cutUpdates = notificationUpdates.threePercent.slice(0, 100);
74+
const chunkSize = 10;
75+
for (let i = 0; i < cutUpdates.length; i += chunkSize) {
76+
const chunk = notificationUpdates.threePercent.slice(i, i + chunkSize);
77+
const message = formatTelegramMessage(chunk);
78+
await sendMessageToTelegram(message);
79+
}
80+
}
81+
}
82+
83+
function formatTelegramMessage(featureUpdates: NotificationUpdate[]) {
84+
return featureUpdates
85+
.map((featureUpdate) => `[${featureUpdate.title}](https://caniuse.com/${featureUpdate.key})`)
86+
.join(`\n`);
4987
}
5088

5189
function getNewFeatureUpdateType(lastFeatureData: FeatureSchemaNoTimeType) {

scripts/commands/updateUsageData.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,25 @@ export const command = {
1212
};
1313

1414
function builder(yargs: Argv) {
15-
return yargs.option('initial', {
16-
type: 'boolean',
17-
description:
18-
'Treat all data as new, those features that pass check will be added as new update',
19-
default: false,
20-
});
15+
return yargs
16+
.option('initial', {
17+
type: 'boolean',
18+
description: 'Removes all feature data from db and add everything from scratch',
19+
default: false,
20+
})
21+
.option('telegram', {
22+
type: 'boolean',
23+
description: 'Send new updates to telegram chat',
24+
default: false,
25+
});
2126
}
2227

2328
async function handler(argv: Record<string, unknown>) {
2429
try {
25-
await updateUsageData(!!argv.initial);
30+
await updateUsageData({
31+
initial: !!argv.initial,
32+
sendToTelegram: !!argv.telegram,
33+
});
2634
} catch (error) {
2735
console.error('Error while updating usage data', error);
2836
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { URLSearchParams } from 'url';
2+
3+
export async function sendMessageToTelegram(message: string) {
4+
const token = process.env.BOT_API_TOKEN;
5+
const chatId = process.env.TELEGRAM_CHAT_ID;
6+
7+
if (!token) {
8+
throw new Error(`Telegram bot api token is not set`);
9+
}
10+
if (!chatId) {
11+
throw new Error(`Telegram chat id is not set`);
12+
}
13+
14+
const url = `https://api.telegram.org/bot${token}/sendMessage`;
15+
const body = new URLSearchParams({ chat_id: chatId, text: message, parse_mode: 'markdown' });
16+
const response = await fetch(url, { method: 'POST', body });
17+
18+
if (!response.ok || response.status !== 200) {
19+
throw new Error(`Can't send telegram message "${response.statusText}"`);
20+
}
21+
}

src/server/schemas/featureUpdateSchema.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@ export const FeatureUpdateSchema = new Schema(
1111
);
1212

1313
export type FeatureUpdateSchemaType = InferSchemaType<typeof FeatureUpdateSchema>;
14+
export type FeatureUpdateSchemaNoTimeType = Omit<
15+
FeatureUpdateSchemaType,
16+
'createdAt' | 'updatedAt'
17+
>;
1418
export type FeatureUpdateType = FeatureUpdateSchemaType['updateType'];

0 commit comments

Comments
 (0)