Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phenomnomnominal/4263594f41ed77a488f835581239ad02 to your computer and use it in GitHub Desktop.
Save phenomnomnominal/4263594f41ed77a488f835581239ad02 to your computer and use it in GitHub Desktop.
const request = require('request').defaults({ jar: true});
const nodemailer = require('nodemailer');
const LOCATIONS = {
STOCKHOLM: 'Z209',
GÖTEBORG: 'Z102',
MALMÖ: 'KCMA',
TILLSTÅNDSPRÖVNING: 'BBBO',
BORLÄNGE: 'NHL',
JÖNKÖPING: 'Z085',
NORRKÖPING: 'Z083',
SUNDSVALL: 'BBSU',
UMEÅ: 'BBUM',
UPPSALA: 'MUP1',
VISBY: 'Z115',
VÄSTERÅS: 'BBVS',
VÄXJÖ: 'BBVX',
ÖREBRO: 'MAOM',
};
const LOCATION_NAMES = Object.keys(LOCATIONS);
const ALL_APPOINTMENTS = {};
console.log('🇸🇪💉 Info: Starting loop!');
let index = 0;
setInterval(() => {
getAppointmentsForLocation(LOCATION_NAMES[index]);
if (index === LOCATION_NAMES.length - 1) {
index = 0;
return;
}
index = index + 1;
}, 5000);
let hasInitialised = false;
setTimeout(() => {
console.log('🇸🇪💉 Info: Assuming stable, will start sending emails now!');
hasInitialised = true;
const events = Object.keys(ALL_APPOINTMENTS).map(key => {
ALL_APPOINTMENTS[key].key = key;
return ALL_APPOINTMENTS[key];
});
console.log('🇸🇪💉 Info: Initial appointments sorted by earliest!');
console.log(events.sort((a, b) => {
a = new Date(a.start);
b = new Date(b.start);
return a < b ? -1 : a > b ? 1 : 0;
}));
}, 120000);
const PAGE_REGEXP = /(\d+-\d+)\.IBehaviorListener/;
function getAppointmentsForLocation (location) {
console.log(`🇸🇪💉 Getting appointments for ${location}!`);
request(getBookingPageUrl(location), (error, _, body) => {
if (error) {
console.error('🇸🇪💉Error:', error);
return;
}
let page;
try {
[, page] = body.match(PAGE_REGEXP);
} catch {
return;
}
request(getAppointmentsUrl(page), (error, _, body) => {
if (error) {
console.error('🇸🇪💉Error:', error);
return;
}
const appointments = JSON.parse(body);
appointments.forEach(appointment => {
const key = `${location}_${appointment.id}`;
if (!ALL_APPOINTMENTS[key]) {
const info = `🇸🇪💉 Available appointment in ${location} at ${new Date(appointment.start)}!`;
ALL_APPOINTMENTS[key] = appointment;
if (hasInitialised) {
sendEmail(info);
}
}
});
});
});
}
function getBookingPageUrl (location) {
return `https://www.migrationsverket.se/ansokanbokning/valjtyp?sprak=en&bokningstyp=2&enhet=${LOCATIONS[location]}&sokande=1`;
}
function getAppointmentsUrl (page) {
const start = new Date();
const end = new Date();
end.setDate(start.getDate() + 60);
let startString = start.toISOString().substring(0, 10);
let endString = end.toISOString().substring(0, 10);
return `https://www.migrationsverket.se/ansokanbokning/wicket/page?${page}.IBehaviorListener.1-form-kalender-kalender&start=${startString}T00%3A00%3A00%2B00%3A00&end=${endString}T00%3A00%3A00%2B00%3A00&_=${Date.now()}`;
}
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.SENDER_EMAIL,
pass: process.env.SENDER_PASSWORD
}
});
async function sendEmail (info) {
try {
console.log(info);
await transporter.sendMail({
from: '"BIOMETRICS APPOINTMENT FINDER 💉" <biometrics@not.real>',
to: 'craigspence0+biometrics-appointment@gmail.com',
subject: info,
text: info,
html: `<b>${info}</b>`
});
console.log('🇸🇪💉 Info: Sent email');
} catch (error) {
console.error('🇸🇪💉 Error:', error);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment