Skip to content

Commit

Permalink
Adds diff notifications
Browse files Browse the repository at this point in the history
  • Loading branch information
luismeyer committed Jan 29, 2020
1 parent 1edc127 commit cc0c08e
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 27 deletions.
39 changes: 26 additions & 13 deletions handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,56 @@ const lambda = require("./src/lambda");

const {
CHAT_ID,
IS_LOCAL
} = process.env;

const printProgess = max => (current, message) =>
console.info(`${current}/${max}: ${message}`);
let progress = 1;
const printProgess = max => message => {
console.info(`${progress}/${max}: ${message}`);
progress += 1;
};

module.exports.formatter = async (event, context, callback) => {
const print = printProgess(6);
progress = 0;
const print = printProgess(8);

print(1, "Calculating current semester");
print("Calculating current semester");
const currentSemester = nak.currentSemester();
if (!currentSemester) return;

print(2, "Fetching nordakademie timetable");
print("Fetching timetable");
const nakCal = await nak.fetchCalendar(currentSemester.semester)
if (!nakCal) return;

print(3, "Formatting timetable");
print("Formatting timetable");
const formattedCalendar = calendar.format(nakCal);

print(4, "Fetching mensa timetable");
print("Fetching old timetable and compares calendars");
const oldTimetable = await bucket.fetchCalendarFile();
const calendarDiff = await calendar.checkEventDifference(oldTimetable, formattedCalendar);

if (calendarDiff.length) {
bot.sendMessage(`kalendar veränderung hier: ${calendarDiff.join()}`);
}

print("Fetching mensa timetable");
const mensaHtml = await nak.fetchMensaTimetable();
const mensaTimetable = nak.formatMensaTimetable(mensaHtml)

if (mensaTimetable) {
print(5, "Creating mensa events");
print("Creating mensa events");
calendar.createMensaEvents(formattedCalendar, mensaTimetable);
} else {
print(5, "Skipping mensa event creation")
print("Skipping mensa event creation")
}

if (CHAT_ID && !IS_LOCAL) {
console.info("Sending Notification");
if (CHAT_ID) {
print("Sending notification");
await bot.sendMessage(CHAT_ID, "hab fertig! lol 🥳");
} else {
print("Skipping notification");
}

print(6, "Uploading file to S3");
print("Uploading file to S3");
await bucket
.uploadToS3(formattedCalendar.toString())
.then(res => callback(null, res), callback);
Expand Down
6 changes: 1 addition & 5 deletions serverless.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,9 @@ provider:
stage: dev
region: eu-central-1
iamRoleStatements:
- Effect: Allow
Action:
- s3:PutObject
- s3:PutObjectAcl
Resource: "arn:aws:s3:::${self:custom.bucket}/*"
- Effect: "Allow"
Action:
- s3:*
- lambda:InvokeFunction
Resource: "*"
environment:
Expand Down
10 changes: 8 additions & 2 deletions src/bot.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
const nodeFetch = require("node-fetch");

const { BOT_TOKEN } = process.env;
const {
BOT_TOKEN,
IS_LOCAL
} = process.env;

module.exports.requestUrl = token => method => `https://api.telegram.org/bot${token}/${method}`;

Expand All @@ -9,7 +12,10 @@ module.exports.fetch = (url, params) =>
.then(res => res.json())

const telegramUrl = this.requestUrl(BOT_TOKEN);
const telegramFetch = (method, params) => this.fetch(telegramUrl(method), params)
const telegramFetch = (method, params) =>
IS_LOCAL ? (
console.info(`Calling telegram "${method}" with params: ${JSON.stringify(params)}`)
) : this.fetch(telegramUrl(method), params)

module.exports.sendMessage = (chat, message) => {
return telegramFetch("sendMessage", {
Expand Down
28 changes: 23 additions & 5 deletions src/bucket.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const AWS = require("aws-sdk");
const ical = require("node-ical");

const FILENAME = "NAK.ics";
const {
Expand All @@ -15,13 +16,30 @@ const s3Params = {
};
const s3 = new AWS.S3(IS_LOCAL && s3Params);

module.exports.uploadToS3 = (data, filename = FILENAME, bucket = BUCKET) => {
const uploadParams = {
module.exports.uploadToS3 = (data, filename = FILENAME, bucket = BUCKET) =>
s3.putObject({
Bucket: bucket,
Key: filename,
Body: data,
ACL: "public-read"
};
}).promise();

return s3.putObject(uploadParams).promise();
};
module.exports.fetchCalendarFile = async (filename = FILENAME, bucket = BUCKET) => {
const headData = await s3.headObject({
Bucket: bucket,
Key: filename
})
.promise()
.catch(_ => {
console.info("No old calendar found");
});

if (headData) {
const ics = await s3.getObject({
Bucket: bucket,
Key: filename
}).promise();

return ical.async.parseICS(ics.Body.toString());
}
}
29 changes: 27 additions & 2 deletions src/calendar.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const generator = require("ical-generator");
const {
subDays,
parseISO
parseISO,
isEqual,
format
} = require("date-fns");

module.exports.formatSummary = summary => {
Expand All @@ -12,7 +14,7 @@ module.exports.formatSummary = summary => {
.replace(/([A-Z] [A-Z]\d{3} )|[A-Z] /, "");
};

module.exports.format = (calendar) => {
module.exports.format = (calendar, oldEvents) => {
const cal = generator();
const events = Object.values(calendar);

Expand Down Expand Up @@ -49,4 +51,27 @@ module.exports.createMensaEvents = (calendar, mensaTimetable) => {
location: 'Mensa',
})
})
}

module.exports.checkEventDifference = (oldCal, newCal) => {
if (!oldCal) return [];

const oldEvents = Object.values(oldCal);
const newEvents = newCal.events();

return newEvents
.filter((newEvent, index) => {
const oldEvent = oldEvents[index];
const {
start: oldStart,
end: oldEnd
} = oldEvent;
const {
start: newStart,
end: newEnd
} = newEvent.toJSON();

return !isEqual(new Date(oldStart), new Date(newStart)) || !isEqual(new Date(oldEnd), new Date(newEnd));
})
.map(event => format(new Date(event.start(), "dd.MM.yyyy")));
}
16 changes: 16 additions & 0 deletions src/scripts/info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const bot = require("../bot");
const secrets = require("../../secrets/secrets.json");

(async () => {
const url = bot.requestUrl(secrets.token)("setWebhook");
const res = await bot.fetch(url, {
method: "post",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: secrets.webhookUrl
})
})
console.info(res);
})();

0 comments on commit cc0c08e

Please sign in to comment.