This commit is contained in:
m5r 2024-10-17 22:45:29 +02:00
parent 984d0c3be4
commit e3c8aa7084
Signed by: mokhtar
GPG Key ID: 1509B54946D08A95
8 changed files with 1150 additions and 5189 deletions

View File

@ -1,6 +0,0 @@
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript',
],
};

4
src/main.ts → main.ts Normal file → Executable file
View File

@ -1,4 +1,6 @@
import run from "./run";
#!/usr/bin/env -S npx tsx
import run from "./src/run.js";
async function main() {
while (true) {

6227
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,26 +2,25 @@
"name": "cosmosarb",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"module": "main.ts",
"scripts": {
"start": "node ./build/main.js",
"build": "tsc -p tsconfig.json",
"dev": "ts-node-dev --respawn ./src/main.ts"
"start": "./main.ts",
"dev": "tsx watch ./main.ts"
},
"keywords": [],
"author": "m5r",
"license": "ISC",
"devDependencies": {
"@babel/core": "7.15.8",
"@babel/preset-env": "7.15.8",
"@babel/preset-typescript": "7.15.0",
"@types/node": "16.11.6",
"ts-node-dev": "1.1.8",
"typescript": "4.4.4"
"@tsconfig/node20": "20.1.4",
"@types/node": "22.7.6",
"typescript": "5.6.3"
},
"dependencies": {
"dotenv": "10.0.0",
"got": "11.8.2",
"twilio": "3.71.3"
"dotenv": "16.4.5",
"got": "14.4.3",
"telegraf": "4.16.3",
"tsx": "4.19.1",
"twilio": "5.3.4"
}
}

View File

@ -1,16 +1,41 @@
import twilio from "twilio";
import dotenv from "dotenv";
import twilio from "twilio";
import { Telegraf } from "telegraf";
const pad = (str: number) => str.toString().padStart(2, "0");
const format = (date: Date) => `RDV chez Bag dispo le ${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${pad(date.getFullYear())} à ${pad(date.getHours())}:${pad(date.getMinutes())}.\nhttps://booking.wavy.pro/hairnewscoiffure`;
dotenv.config();
const twilioClient = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
/* const twilioClient = twilio(process.env.TWILIO_ACCOUNT_SID, process.env.TWILIO_AUTH_TOKEN);
export default async function notify(date: Date) {
async function sendSMS(date: Date, to: string) {
await twilioClient.messages.create({
body: `RDV chez Bag dispo le ${pad(date.getDate())}/${pad(date.getMonth() + 1)}/${pad(date.getFullYear())} à ${pad(date.getHours())}:${pad(date.getMinutes())}.\nhttps://booking.wavy.pro/hairnewscoiffure`,
to: "+33613370787",
body: format(date),
to,
from: "+33757592025",
});
}
const pad = (str: number) => str.toString().padStart(2, "0");
// const notifiers = ["+33613370787", "+33673899359"] as const;
const notifiers = ["+33613370787"] as const;
export default async function notify(date: Date) {
await Promise.all(notifiers.map(async phoneNumber => sendSMS(date, phoneNumber)));
}
*/
const bot = new Telegraf(process.env.TELEGRAM_BOT_TOKEN!);
bot.launch();
// Enable graceful stop
process.once("SIGINT", () => bot.stop("SIGINT"))
process.once("SIGTERM", () => bot.stop("SIGTERM"))
const notifiers = [
async (date: Date) => bot.telegram.sendMessage(716477900, format(date)),
];
export default async function notify(date: Date) {
await Promise.all(notifiers.map(notifier => notifier(date)));
}

View File

@ -1,5 +1,5 @@
import notify from "./notify";
import { getFirstAvailableSlot, getSlots } from "./slots";
import notify from "./notify.js";
import { getFirstAvailableSlot, getSlots } from "./slots.js";
export default async function run() {
const slots = await getSlots();
@ -9,6 +9,11 @@ export default async function run() {
return sleep();
}
if (new Date() > availableSlot) {
console.log("found one but already expired", availableSlot.toISOString());
return sleep();
}
console.log("found one", availableSlot.toISOString());
await notify(availableSlot);
}

View File

@ -1,6 +1,6 @@
import got from "got";
import { addKnownSlot, getKnownSlots } from "./cache";
import { addKnownSlot, getKnownSlots } from "./cache.js";
export function getFirstAvailableSlot(response: Response): Date | null {
const knownSlots = getKnownSlots();
@ -29,15 +29,15 @@ export function getFirstAvailableSlot(response: Response): Date | null {
export async function getSlots() {
const { body } = await got.post<Response>(
"https://booking.wavy.pro/api/shops/c5593def-a89c-4296-ac87-f484d8a22ecb/booking/v2/slot",
"https://api.wavy.fr/shops/c5593def-a89c-4296-ac87-f484d8a22ecb/booking/v2/slot",
{
body: JSON.stringify({
startDate: "2021-12-12T23:00:00.000Z",
endDate: "2021-12-29T22:59:59.999Z",
startDate: "2024-06-05T22:00:00.000Z",
endDate: "2024-06-22T21:59:59.999Z",
itemsQuery: [{
"id": "5cb74891ff800f00007f32d5",
"priceValue": 15,
"staffIds": ["5cb721b52561230000f9f5dd", "5cb721b52561230000f9f5dd"],
id: "5cb74891ff800f00007f32d5",
priceValue: 16,
staffIds: ["5cb721b52561230000f9f5dd","5cb721b52561230000f9f5dd"],
}],
}),
headers: { "Content-Type": "application/json;charset=utf-8" },
@ -45,6 +45,8 @@ export async function getSlots() {
},
);
console.log("body", body)
return body;
}

View File

@ -1,14 +1,9 @@
{
"extends": "@tsconfig/node20/tsconfig.json",
"compilerOptions": {
"target": "ES2021",
"lib": ["ESNext"],
"moduleResolution": "node",
"module": "commonjs",
"outDir": "build",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true
"module": "NodeNext",
"moduleResolution": "NodeNext",
"noEmit": true,
},
"include": ["src/**/*"]
"include": ["src/**/*", "main.ts"]
}