Skip to content

Instantly share code, notes, and snippets.

@foxel
Forked from bushaev-denis/midpass.js
Created February 27, 2023 15:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save foxel/267668eb3277b429972d60d2e4845da2 to your computer and use it in GitHub Desktop.
Save foxel/267668eb3277b429972d60d2e4845da2 to your computer and use it in GitHub Desktop.
Midpass calendar notify has available record
const beep = (date) => {
const context = new AudioContext();
const oscillator = context.createOscillator();
oscillator.type = "sawtooth";
oscillator.frequency.value = 1200;
oscillator.connect(context.destination);
oscillator.start();
if (confirm("Появилась запись")) {
oscillator.stop();
document.location.href = 'https://q.midpass.ru/ru/Booking/Date?serviceId=54030d6a-e145-08e2-60fb-33344fac2455&date=' + date;
}
};
const getDate = (month, year) => [
(month > 11 ? month - 12 : month) + 1,
month > 11 ? year + Math.floor(month / 11) : year
];
const randSeconds = (n, x) => {
return Math.floor(Math.random() * (x * 1000 - n * 1000 + 1) + n * 1000);
};
const fetchSlots = async (month, year) => {
const res = await fetch("https://q.midpass.ru/ru/Booking/GetMonthSchedule", {
headers: {
accept: "application/json, text/javascript, */*; q=0.01",
"accept-language": "ru,en;q=0.9",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"sec-ch-ua":
'"Chromium";v="106", "Google Chrome";v="106", "Not;A=Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"macOS"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"x-requested-with": "XMLHttpRequest"
},
referrer:
"https://q.midpass.ru/ru/Booking?serviceId=54030d6a-e145-08e2-60fb-33344fac2455",
referrerPolicy: "strict-origin-when-cross-origin",
body: `serviceId=54030d6a-e145-08e2-60fb-33344fac2455&month=${month}&year=${year}&day=1&k=7431`,
method: "POST",
mode: "cors",
credentials: "include"
});
if (res.ok) {
return await res.json();
}
return null;
};
const start = async () => {
if (!started) {
return;
}
const date = new Date();
const month = date.getMonth();
const year = date.getFullYear();
const dates = [getDate(month, year), getDate(month + 1, year)];
const slots = await Promise.all(dates.map(async (date) => await fetchSlots(...date)));
const totalAvailableSlots = slots.reduce((res, cur) => res + cur.AvailableSlots, 0);
if (totalAvailableSlots > 0) {
const days = slots.flatMap(slot => slot.Month.Days.filter(day => day.AvailableAppointmentsCount > 0));
const selected = days.sort((a, b) => b.AvailableAppointmentsCount - a.AvailableAppointmentsCount)[0];
const date = new Date(+selected.Date.replaceAll(/[^0-9]/g, '')).toISOString().replace(/T.*$/, '');
beep(date);
} else {
setTimeout(start, randSeconds(30, 90));
}
};
let started = false;
const buttonText = ['▶ запустить скрипт️', '⏸ остановить скрипт'];
const Button = document.createElement('button');
Button.style.cssText = 'position: fixed; top: 20px; left: 20px; font-size: 1.5rem';
Button.textContent = buttonText[0];
document.documentElement.appendChild(Button)
Button.addEventListener('click', () => {
started = !started;
Button.textContent = buttonText[Number(started)];
start();
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment