1
0
mirror of https://github.com/elisspace/FxLifeSheet.git synced 2026-08-29 15:44:00 +00:00

Use tsconfig.json & remove comments in JS file

This commit is contained in:
Felix Krause
2021-11-04 15:23:39 +01:00
parent 57f0144190
commit 57f445a340
9 changed files with 109 additions and 234 deletions

View File

@@ -15,3 +15,4 @@ else {
console.log("Successfully loaded user config"); console.log("Successfully loaded user config");
module.exports.userConfig = userConfig; module.exports.userConfig = userConfig;
} }
//# sourceMappingURL=config.js.map

View File

@@ -12,3 +12,4 @@ client.query("SELECT NOW()", function (err, res) {
console.log(err, res); console.log(err, res);
}); });
module.exports.client = client; module.exports.client = client;
//# sourceMappingURL=postgres.js.map

View File

@@ -1,6 +1,6 @@
"use strict"; "use strict";
exports.__esModule = true; exports.__esModule = true;
// Telegram setup
var Telegraf = require("telegraf"); var Telegraf = require("telegraf");
var bot = new Telegraf(process.env.TELEGRAM_BOT_TOKEN); var bot = new Telegraf(process.env.TELEGRAM_BOT_TOKEN);
module.exports.bot = bot; module.exports.bot = bot;
//# sourceMappingURL=telegram.js.map

View File

@@ -1,7 +1,7 @@
{ {
"scripts": { "scripts": {
"prettier": "prettier worker.ts web.ts reminder.ts classes/*.ts --write", "prettier": "prettier worker.ts web.ts reminder.ts classes/*.ts --write",
"typescript": "tsc web.ts worker.ts reminder.ts classes/postgres.ts classes/telegram.ts classes/config.ts", "typescript": "tsc --p tsconfig.json",
"dev": "source .keys && npm run prettier && npm run typescript && heroku local", "dev": "source .keys && npm run prettier && npm run typescript && heroku local",
"web": "npm run prettier && npm run typescript && node web.js", "web": "npm run prettier && npm run typescript && node web.js",
"worker": "npm run prettier && npm run typescript && node worker.js", "worker": "npm run prettier && npm run typescript && node worker.js",

View File

@@ -1,13 +1,10 @@
"use strict"; "use strict";
exports.__esModule = true; exports.__esModule = true;
// Third party dependencies
var moment = require("moment"); var moment = require("moment");
// Internal dependencies
var config = require("./classes/config.js"); var config = require("./classes/config.js");
var postgres = require("./classes/postgres.js"); var postgres = require("./classes/postgres.js");
var telegram = require("./classes/telegram.js"); var telegram = require("./classes/telegram.js");
console.log("Checking if we need to send a reminder to the user..."); console.log("Checking if we need to send a reminder to the user...");
// Hacky, as fetching the config file takes a little while
setTimeout(function () { setTimeout(function () {
postgres.client.query({ postgres.client.query({
text: "SELECT * FROM last_run" text: "SELECT * FROM last_run"
@@ -28,7 +25,7 @@ setTimeout(function () {
break; break;
} }
var scheduleType = config.userConfig[command].schedule; var scheduleType = config.userConfig[command].schedule;
var timeDifferenceHours = moment().diff(moment(lastRun), "hours"); // hours var timeDifferenceHours = moment().diff(moment(lastRun), "hours");
var shouldRemindUser = false; var shouldRemindUser = false;
if (scheduleType == "eightTimesADay") { if (scheduleType == "eightTimesADay") {
if (timeDifferenceHours >= 24 / 8) { if (timeDifferenceHours >= 24 / 8) {
@@ -37,7 +34,6 @@ setTimeout(function () {
} }
else if (scheduleType == "daily") { else if (scheduleType == "daily") {
if (timeDifferenceHours >= 24 * 0.95) { if (timeDifferenceHours >= 24 * 0.95) {
// 0.95 to send that alert earlier to make it easier to tap
shouldRemindUser = true; shouldRemindUser = true;
} }
} }
@@ -52,7 +48,6 @@ setTimeout(function () {
} }
} }
else if (scheduleType == "manual") { else if (scheduleType == "manual") {
// Never remind the user
} }
else { else {
console.error("Unknown schedule type " + scheduleType); console.error("Unknown schedule type " + scheduleType);
@@ -98,3 +93,4 @@ setTimeout(function () {
console.log("Reminder check done"); console.log("Reminder check done");
}); });
}, 2000); }, 2000);
//# sourceMappingURL=reminder.js.map

13
tsconfig.json Normal file
View File

@@ -0,0 +1,13 @@
{
"compilerOptions": {
"module": "CommonJS",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true
},
"include": ["**/*.ts"],
"exclude": ["node_modules", "**/*.spec.ts"],
"types": [ "node" ],
"typeRoots": [ "../node_modules/@types" ]
}

10
web.js
View File

@@ -1,10 +1,8 @@
"use strict"; "use strict";
exports.__esModule = true; exports.__esModule = true;
// Third party dependencies
var http = require("http"); var http = require("http");
var moment = require("moment"); var moment = require("moment");
var postgres = require("./classes/postgres.js"); var postgres = require("./classes/postgres.js");
// State
var lastFetchedData = {}; var lastFetchedData = {};
function loadCurrentData(key) { function loadCurrentData(key) {
console.log("Refreshing latest moood entry..."); console.log("Refreshing latest moood entry...");
@@ -36,7 +34,6 @@ function loadCurrentData(key) {
}); });
} }
console.log("Launching up API web server..."); console.log("Launching up API web server...");
// Periodically refresh the value
var interval = 5 * 60 * 1000; var interval = 5 * 60 * 1000;
var keys = [ var keys = [
"mood", "mood",
@@ -65,7 +62,6 @@ var _loop_1 = function (i) {
for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
_loop_1(i); _loop_1(i);
} }
// One-off total computer usage
postgres.client.query({ postgres.client.query({
text: "SELECT SUM(value::int) FROM raw_data WHERE key = 'dailyComputerUse'" text: "SELECT SUM(value::int) FROM raw_data WHERE key = 'dailyComputerUse'"
}, function (err, res) { }, function (err, res) {
@@ -75,9 +71,8 @@ postgres.client.query({
return; return;
} }
var hoursComputerUsed = res.rows[0]["sum"] / 60.0; var hoursComputerUsed = res.rows[0]["sum"] / 60.0;
// calculate up averages since we don't import RescueTime every day var daysDifference = moment().diff(moment("2020-03-22"), "days");
var daysDifference = moment().diff(moment("2020-03-22"), "days"); // that's when we imported last hoursComputerUsed += daysDifference * 6.5;
hoursComputerUsed += daysDifference * 6.5; // average computer usage a day nowadays
lastFetchedData["totalComputerUsageHours"] = { lastFetchedData["totalComputerUsageHours"] = {
time: moment().format(), time: moment().format(),
value: Math.round(hoursComputerUsed) value: Math.round(hoursComputerUsed)
@@ -90,3 +85,4 @@ http
return res.end(); return res.end();
}) })
.listen(process.env.PORT); .listen(process.env.PORT);
//# sourceMappingURL=web.js.map

304
worker.js
View File

@@ -1,23 +1,16 @@
"use strict"; "use strict";
exports.__esModule = true; exports.__esModule = true;
// Third party dependencies
var moment = require("moment"); var moment = require("moment");
var needle = require("needle"); var needle = require("needle");
var _a = require("telegraf"), var _a = require("telegraf"), Router = _a.Router, Markup = _a.Markup, Extra = _a.Extra;
Router = _a.Router,
Markup = _a.Markup,
Extra = _a.Extra;
// Internal dependencies
var config = require("./classes/config.js"); var config = require("./classes/config.js");
var postgres = require("./classes/postgres.js"); var postgres = require("./classes/postgres.js");
var telegram = require("./classes/telegram.js"); var telegram = require("./classes/telegram.js");
var bot = telegram.bot; var bot = telegram.bot;
// State
var currentlyAskedQuestionObject = null; var currentlyAskedQuestionObject = null;
var currentlyAskedQuestionMessageId = null; // The Telegram message ID reference var currentlyAskedQuestionMessageId = null;
var currentlyAskedQuestionQueue = []; // keep track of all the questions about to be asked var currentlyAskedQuestionQueue = [];
initBot(); initBot();
function getButtonText(number) { function getButtonText(number) {
var emojiNumber = { var emojiNumber = {
"0": "0⃣", "0": "0⃣",
@@ -28,7 +21,6 @@ function getButtonText(number) {
"5": "5⃣" "5": "5⃣"
}[number]; }[number];
if (currentlyAskedQuestionObject.buttons == null) { if (currentlyAskedQuestionObject.buttons == null) {
// Assign default values
currentlyAskedQuestionObject.buttons = { currentlyAskedQuestionObject.buttons = {
"0": "Terrible", "0": "Terrible",
"1": "Bad", "1": "Bad",
@@ -40,12 +32,11 @@ function getButtonText(number) {
} }
return emojiNumber + " " + currentlyAskedQuestionObject.buttons[number]; return emojiNumber + " " + currentlyAskedQuestionObject.buttons[number];
} }
function printGraph(key, ctx, numberOfRecentValuesToPrint, additionalValue, skipImage) { function printGraph(key, ctx, numberOfRecentValuesToPrint, additionalValue, skipImage) {
postgres.client.query({ postgres.client.query({
text: "SELECT * FROM raw_data WHERE key = $1 ORDER BY timestamp DESC LIMIT 300", text: "SELECT * FROM raw_data WHERE key = $1 ORDER BY timestamp DESC LIMIT 300",
values: [key] values: [key]
}, function(err, res) { }, function (err, res) {
console.log(res); console.log(res);
if (err) { if (err) {
console.error(err); console.error(err);
@@ -81,11 +72,9 @@ function printGraph(key, ctx, numberOfRecentValuesToPrint, additionalValue, skip
": " + ": " +
Number(additionalValue).toFixed(2)); Number(additionalValue).toFixed(2));
} }
// Print the raw values
if (numberOfRecentValuesToPrint > 0) { if (numberOfRecentValuesToPrint > 0) {
ctx.reply(rawText.join("\n") + "\nMinimum: " + minimum + "\nMaximum: " + maximum); ctx.reply(rawText.join("\n") + "\nMinimum: " + minimum + "\nMaximum: " + maximum);
} }
// Generate the graph
if (!skipImage) { if (!skipImage) {
minimum -= 2; minimum -= 2;
maximum += 2; maximum += 2;
@@ -106,14 +95,12 @@ function printGraph(key, ctx, numberOfRecentValuesToPrint, additionalValue, skip
} }
}); });
} }
function triggerNextQuestionFromQueue(ctx) { function triggerNextQuestionFromQueue(ctx) {
var keyboard = Extra.markup(function(m) { return m.removeKeyboard(); }); // default keyboard var keyboard = Extra.markup(function (m) { return m.removeKeyboard(); });
var questionAppendix = ""; var questionAppendix = "";
currentlyAskedQuestionObject = currentlyAskedQuestionQueue.shift(); currentlyAskedQuestionObject = currentlyAskedQuestionQueue.shift();
if (currentlyAskedQuestionObject == null) { if (currentlyAskedQuestionObject == null) {
ctx.reply("All done for now, let's do this 💪", keyboard); ctx.reply("All done for now, let's do this 💪", keyboard);
// Finished
return; return;
} }
if (currentlyAskedQuestionObject.question == null) { if (currentlyAskedQuestionObject.question == null) {
@@ -121,18 +108,14 @@ function triggerNextQuestionFromQueue(ctx) {
console.error(currentlyAskedQuestionObject); console.error(currentlyAskedQuestionObject);
} }
if (currentlyAskedQuestionObject.type == "header") { if (currentlyAskedQuestionObject.type == "header") {
// This is information only, just print and go to the next one
ctx ctx
.reply(currentlyAskedQuestionObject.question, keyboard) .reply(currentlyAskedQuestionObject.question, keyboard)
.then(function(_a) { .then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
}); });
return; return;
} }
// Looks like Telegram has some limitations:
// - No way to use `force_reply` together with a custom keyboard (https://github.com/KrauseFx/FxLifeSheet/issues/5)
// - No way to update existing messages together with a custom keyboard https://core.telegram.org/bots/api#updating-messages
if (currentlyAskedQuestionObject.type == "range") { if (currentlyAskedQuestionObject.type == "range") {
var allButtons = [ var allButtons = [
[getButtonText("5")], [getButtonText("5")],
@@ -146,19 +129,18 @@ function triggerNextQuestionFromQueue(ctx) {
keyboard = Markup.keyboard(allButtons) keyboard = Markup.keyboard(allButtons)
.oneTime() .oneTime()
.extra(); .extra();
} else if (currentlyAskedQuestionObject.type == "boolean") { }
keyboard = Markup.keyboard([ else if (currentlyAskedQuestionObject.type == "boolean") {
["1: Yes"], keyboard = Markup.keyboard([["1: Yes"], ["0: No"]])
["0: No"]
])
.oneTime() .oneTime()
.extra(); .extra();
} else if (currentlyAskedQuestionObject.type == "text") { }
// use the default keyboard we set here anyway else if (currentlyAskedQuestionObject.type == "text") {
questionAppendix += questionAppendix +=
"You can use a Bear note, and then paste the deep link to the note here"; "You can use a Bear note, and then paste the deep link to the note here";
} else if (currentlyAskedQuestionObject.type == "location") { }
keyboard = Extra.markup(function(markup) { else if (currentlyAskedQuestionObject.type == "location") {
keyboard = Extra.markup(function (markup) {
return markup.keyboard([ return markup.keyboard([
markup.locationRequestButton("📡 Send location") markup.locationRequestButton("📡 Send location")
]); ]);
@@ -172,18 +154,16 @@ function triggerNextQuestionFromQueue(ctx) {
questionAppendix = "last question"; questionAppendix = "last question";
} }
var question = currentlyAskedQuestionObject.question + " (" + questionAppendix + ")"; var question = currentlyAskedQuestionObject.question + " (" + questionAppendix + ")";
ctx.reply(question, keyboard).then(function(_a) { ctx.reply(question, keyboard).then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
currentlyAskedQuestionMessageId = message_id; currentlyAskedQuestionMessageId = message_id;
}); });
if (currentlyAskedQuestionObject.type == "number" || if (currentlyAskedQuestionObject.type == "number" ||
currentlyAskedQuestionObject.type == "range" || currentlyAskedQuestionObject.type == "range" ||
currentlyAskedQuestionObject.type == "boolean") { currentlyAskedQuestionObject.type == "boolean") {
// To show the graph before, as it takes a while to load
printGraph(currentlyAskedQuestionObject.key, ctx, 0, null, false); printGraph(currentlyAskedQuestionObject.key, ctx, 0, null, false);
} }
} }
// Taken from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
function shuffleArray(array) { function shuffleArray(array) {
var _a; var _a;
for (var i = array.length - 1; i > 0; i--) { for (var i = array.length - 1; i > 0; i--) {
@@ -191,14 +171,14 @@ function shuffleArray(array) {
_a = [array[j], array[i]], array[i] = _a[0], array[j] = _a[1]; _a = [array[j], array[i]], array[i] = _a[0], array[j] = _a[1];
} }
} }
function insertNewValue(parsedUserValue, ctx, key, type, fakeDate) { function insertNewValue(parsedUserValue, ctx, key, type, fakeDate) {
if (fakeDate === void 0) { fakeDate = null; } if (fakeDate === void 0) { fakeDate = null; }
console.log("Inserting value '" + parsedUserValue + "' for key " + key); console.log("Inserting value '" + parsedUserValue + "' for key " + key);
var dateToAdd; var dateToAdd;
if (fakeDate) { if (fakeDate) {
dateToAdd = fakeDate; dateToAdd = fakeDate;
} else { }
else {
dateToAdd = moment(ctx.update.message.date * 1000); dateToAdd = moment(ctx.update.message.date * 1000);
} }
var questionText = null; var questionText = null;
@@ -219,38 +199,26 @@ function insertNewValue(parsedUserValue, ctx, key, type, fakeDate) {
Key: key, Key: key,
Question: questionText, Question: questionText,
Type: type, Type: type,
Value: parsedUserValue Value: parsedUserValue,
Source: "telegram"
}; };
postgres.client.query({ postgres.client.query({
text: "INSERT INTO raw_data (" + text: "INSERT INTO raw_data (" +
Object.keys(row).join(",") + Object.keys(row).join(",") +
") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)", ") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)",
values: Object.values(row) values: Object.values(row)
}, function(err, res) { }, function (err, res) {
console.log(res); console.log(res);
if (err) { if (err) {
ctx.reply("Error saving value: " + err); ctx.reply("Error saving value: " + err);
console.log(err.stack); console.log(err.stack);
} else {} }
else {
}
}); });
if (ctx) { if (ctx) {
// we don't use this for location sending as we have many values for that, so that's when `ctx` is nil
// Show that we saved the value
// Currently the Telegram API doens't support updating of messages that have a custom keyboard
// for no good reason, as mentioned here https://github.com/TelegramBots/telegram.bot/issues/176
//
// Bad Request: Message can't be edited
//
// Please note, that it is currently only possible to edit messages without reply_markup or with inline keyboards
// ctx.telegram.editMessageText(
// ctx.update.message.chat.id,
// currentlyAskedQuestionMessageId,
// null,
// "✅ " + lastQuestionAskedDupe + " ✅"
// );
} }
} }
function parseUserInput(ctx, text) { function parseUserInput(ctx, text) {
if (text === void 0) { text = null; } if (text === void 0) { text = null; }
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
@@ -260,34 +228,32 @@ function parseUserInput(ctx, text) {
if (currentlyAskedQuestionMessageId == null) { if (currentlyAskedQuestionMessageId == null) {
ctx ctx
.reply("Sorry, I forgot the question I asked, this usually means it took too long for you to respond, please trigger the question again by running the `/` command") .reply("Sorry, I forgot the question I asked, this usually means it took too long for you to respond, please trigger the question again by running the `/` command")
.then(function(_a) { .then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
sendAvailableCommands(ctx); sendAvailableCommands(ctx);
}); });
return; return;
} }
// user replied with a value
var userValue; var userValue;
if (text != null) { if (text != null) {
userValue = text; userValue = text;
} else { }
else {
userValue = ctx.match[1]; userValue = ctx.match[1];
} }
var parsedUserValue = null; var parsedUserValue = null;
if (currentlyAskedQuestionObject.type != "text") { if (currentlyAskedQuestionObject.type != "text") {
// First, see if it starts with emoji number, for which we have to do custom
// parsing instead
if (currentlyAskedQuestionObject.type == "range" || if (currentlyAskedQuestionObject.type == "range" ||
currentlyAskedQuestionObject.type == "boolean") { currentlyAskedQuestionObject.type == "boolean") {
var tryToParseNumber = parseInt(userValue[0]); var tryToParseNumber = parseInt(userValue[0]);
if (!isNaN(tryToParseNumber)) { if (!isNaN(tryToParseNumber)) {
parsedUserValue = tryToParseNumber; parsedUserValue = tryToParseNumber;
} else { }
else {
ctx.reply("Sorry, looks like your input is invalid, please enter a valid number from the selection", Extra.inReplyTo(ctx.update.message.message_id)); ctx.reply("Sorry, looks like your input is invalid, please enter a valid number from the selection", Extra.inReplyTo(ctx.update.message.message_id));
} }
} }
if (parsedUserValue == null) { if (parsedUserValue == null) {
// parse the int/float, support both ints and floats
userValue = userValue.match(/^(\d+(\.\d+)?)$/); userValue = userValue.match(/^(\d+(\.\d+)?)$/);
if (userValue == null) { if (userValue == null) {
ctx.reply("Sorry, looks like you entered an invalid number, please try again", Extra.inReplyTo(ctx.update.message.message_id)); ctx.reply("Sorry, looks like you entered an invalid number, please try again", Extra.inReplyTo(ctx.update.message.message_id));
@@ -295,11 +261,11 @@ function parseUserInput(ctx, text) {
} }
parsedUserValue = userValue[1]; parsedUserValue = userValue[1];
} }
} else { }
parsedUserValue = userValue; // raw value is fine else {
parsedUserValue = userValue;
} }
if (currentlyAskedQuestionObject.type == "range") { if (currentlyAskedQuestionObject.type == "range") {
// ensure the input is 0-6
if (parsedUserValue < 0 || parsedUserValue > 6) { if (parsedUserValue < 0 || parsedUserValue > 6) {
ctx.reply("Please enter a value from 0 to 6", Extra.inReplyTo(ctx.update.message.message_id)); ctx.reply("Please enter a value from 0 to 6", Extra.inReplyTo(ctx.update.message.message_id));
return; return;
@@ -308,7 +274,6 @@ function parseUserInput(ctx, text) {
if (currentlyAskedQuestionObject.type == "number" || if (currentlyAskedQuestionObject.type == "number" ||
currentlyAskedQuestionObject.type == "range" || currentlyAskedQuestionObject.type == "range" ||
currentlyAskedQuestionObject.type == "boolean") { currentlyAskedQuestionObject.type == "boolean") {
// To show potential streaks and the history
printGraph(currentlyAskedQuestionObject.key, ctx, 5, parsedUserValue, true); printGraph(currentlyAskedQuestionObject.key, ctx, 5, parsedUserValue, true);
} }
console.log("Got a new value: " + console.log("Got a new value: " +
@@ -317,56 +282,46 @@ function parseUserInput(ctx, text) {
currentlyAskedQuestionObject.key); currentlyAskedQuestionObject.key);
if (currentlyAskedQuestionObject.replies && if (currentlyAskedQuestionObject.replies &&
currentlyAskedQuestionObject.replies[parsedUserValue]) { currentlyAskedQuestionObject.replies[parsedUserValue]) {
// Check if there is a custom reply, and if, use that
ctx.reply(currentlyAskedQuestionObject.replies[parsedUserValue], Extra.inReplyTo(ctx.update.message.message_id)); ctx.reply(currentlyAskedQuestionObject.replies[parsedUserValue], Extra.inReplyTo(ctx.update.message.message_id));
} }
insertNewValue(parsedUserValue, ctx, currentlyAskedQuestionObject.key, currentlyAskedQuestionObject.type); insertNewValue(parsedUserValue, ctx, currentlyAskedQuestionObject.key, currentlyAskedQuestionObject.type);
setTimeout(function() { setTimeout(function () {
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
}, 50); // timeout just to make sure the order is right }, 50);
} }
function sendAvailableCommands(ctx) { function sendAvailableCommands(ctx) {
ctx.reply("Available commands:").then(function(_a) { ctx.reply("Available commands:").then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
ctx.reply("\n\n/skip\n/report\n\n/" + Object.keys(config.userConfig).join("\n/")); ctx.reply("\n\n/skip\n/report\n\n/" + Object.keys(config.userConfig).join("\n/"));
}); });
} }
function saveLastRun(command) { function saveLastRun(command) {
postgres.client.query({ postgres.client.query({
text: "insert into last_run (command, last_run) VALUES ($1, $2) on conflict (command) do update set last_run = $2", text: "insert into last_run (command, last_run) VALUES ($1, $2) on conflict (command) do update set last_run = $2",
values: [command, moment().valueOf()] values: [command, moment().valueOf()]
}, function(err, res) { }, function (err, res) {
console.log(res); console.log(res);
if (err) { if (err) {
console.log(err.stack); console.log(err.stack);
} else { }
else {
console.log("Stored timestamp of last run for " + command); console.log("Stored timestamp of last run for " + command);
} }
}); });
} }
function initBot() { function initBot() {
console.log("Launching up Telegram bot..."); console.log("Launching up Telegram bot...");
bot.on(["document"], function(ctx) { bot.on(["document"], function (ctx) {
// This is used to import other historic data
var fileId = ctx.update.message.document.file_id; var fileId = ctx.update.message.document.file_id;
console.log("Received a file of ID " + fileId); console.log("Received a file of ID " + fileId);
// Format: ctx.telegram.getFileLink(fileId).then(function (link) {
//
// Date;withingsFatMass;withingsLeanBodyMass;withingsMuscleMass
// 28.05.2019; 6.9 ; 74.6 , 71.1
// 27.05.2019; 7.5 ; 74.1 , 70.6
// ....
ctx.telegram.getFileLink(fileId).then(function(link) {
console.log(link); console.log(link);
needle.get(link, function(error, response, body) { needle.get(link, function (error, response, body) {
if (error) { if (error) {
console.error(error); console.error(error);
return; return;
} }
body = body.toString(); // needed for some reason body = body.toString();
console.log(body); console.log(body);
var sep = ";"; var sep = ";";
var dateFormat = "DD.MM.YYYY"; var dateFormat = "DD.MM.YYYY";
@@ -389,7 +344,8 @@ function initBot() {
} }
} }
} }
} else { }
else {
ctx.reply("The CSV file must use ; as a separator, must have at least 2 columns, with the first column being the date formatted DD.MM.YYYY, and all other columns using the key as the first row"); ctx.reply("The CSV file must use ; as a separator, must have at least 2 columns, with the first column being the date formatted DD.MM.YYYY, and all other columns using the key as the first row");
} }
} }
@@ -397,33 +353,10 @@ function initBot() {
}); });
}); });
}); });
// parse numeric/text inputs bot.hears(/^([^\/].*)$/, function (ctx) {
// `^([^\/].*)$` matches everything that doens't start with /
// This will enable us to get any user inputs, including longer texts
bot.hears(/^([^\/].*)$/, function(ctx) {
parseUserInput(ctx); parseUserInput(ctx);
}); });
// As we get no benefit of using `bot.command` to add commands, we might as well use bot.hears("/skip", function (ctx) {
// regexes, which then allows us to let the user's JSON define the available commands
//
// parse one-off commands:
//
// Those have to be above the regex match
bot.hears("/report", function(ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
return;
}
console.log("Generating report...");
ctx
.replyWithPhoto({
url: "https://datastudio.google.com/reporting/1a-1rVk-4ZFOg0WTNNGRvJDXMTNXpl5Uy/page/MpTm/thumbnail?sz=s3000"
})
.then(function(_a) {
var message_id = _a.message_id;
ctx.reply("Full report: https://datastudio.google.com/s/uwV1-Pv9dk4");
});
});
bot.hears("/skip", function(ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
console.error("Invalid user " + ctx.update.message.from.username); console.error("Invalid user " + ctx.update.message.from.username);
return; return;
@@ -432,7 +365,7 @@ function initBot() {
ctx.reply("Okay, skipping question. If you see yourself skipping a question too often, maybe it's time to rephrase or remove it"); ctx.reply("Okay, skipping question. If you see yourself skipping a question too often, maybe it's time to rephrase or remove it");
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
}); });
bot.hears("/skip_all", function(ctx) { bot.hears("/skip_all", function (ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
return; return;
} }
@@ -440,7 +373,7 @@ function initBot() {
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
ctx.reply("Okay, removing all questions that are currently in the queue"); ctx.reply("Okay, removing all questions that are currently in the queue");
}); });
bot.hears(/\/track (\w+)/, function(ctx) { bot.hears(/\/track (\w+)/, function (ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
console.error("Invalid user " + ctx.update.message.from.username); console.error("Invalid user " + ctx.update.message.from.username);
return; return;
@@ -449,7 +382,7 @@ function initBot() {
console.log("User wants to track a specific value, without the whole survey: " + console.log("User wants to track a specific value, without the whole survey: " +
toTrack); toTrack);
var questionToAsk = null; var questionToAsk = null;
Object.keys(config.userConfig).forEach(function(key) { Object.keys(config.userConfig).forEach(function (key) {
var survey = config.userConfig[key]; var survey = config.userConfig[key];
for (var i = 0; i < survey.questions.length; i++) { for (var i = 0; i < survey.questions.length; i++) {
var currentQuestion = survey.questions[i]; var currentQuestion = survey.questions[i];
@@ -462,13 +395,14 @@ function initBot() {
if (questionToAsk) { if (questionToAsk) {
currentlyAskedQuestionQueue = currentlyAskedQuestionQueue.concat(questionToAsk); currentlyAskedQuestionQueue = currentlyAskedQuestionQueue.concat(questionToAsk);
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
} else { }
else {
ctx.reply("Sorry, I couldn't find the key `" + ctx.reply("Sorry, I couldn't find the key `" +
toTrack + toTrack +
"`, please make sure it's not mispelled"); "`, please make sure it's not mispelled");
} }
}); });
bot.hears(/\/graph (\w+)/, function(ctx) { bot.hears(/\/graph (\w+)/, function (ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
return; return;
} }
@@ -476,17 +410,17 @@ function initBot() {
console.log("User wants to graph a specific value " + key); console.log("User wants to graph a specific value " + key);
printGraph(key, ctx, 100, null, false); printGraph(key, ctx, 100, null, false);
}); });
bot.on("location", function(ctx) { bot.on("location", function (ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
return; return;
} }
if (currentlyAskedQuestionMessageId == null) { if (currentlyAskedQuestionMessageId == null) {
ctx ctx
.reply("Sorry, I forgot the question I asked, this usually means it took too long for you to respond, please trigger the question again by running the `/` command") .reply("Sorry, I forgot the question I asked, this usually means it took too long for you to respond, please trigger the question again by running the `/` command")
.then(function(_a) { .then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
sendAvailableCommands(ctx); sendAvailableCommands(ctx);
}); });
return; return;
} }
var location = ctx.update.message.location; var location = ctx.update.message.location;
@@ -495,107 +429,43 @@ function initBot() {
insertNewValue(lat, ctx, "locationLat", "number"); insertNewValue(lat, ctx, "locationLat", "number");
insertNewValue(lng, ctx, "locationLng", "number"); insertNewValue(lng, ctx, "locationLng", "number");
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
return;
return; // since the rest doens't currently work
var url = "https://api.opencagedata.com/geocode/v1/json?q=" + var url = "https://api.opencagedata.com/geocode/v1/json?q=" +
lat + lat +
"+" + "+" +
lng + lng +
"&key=" + "&key=" +
process.env.OPEN_CAGE_API_KEY; process.env.OPEN_CAGE_API_KEY;
needle.get(url, function(error, response, body) { needle.get(url, function (error, response, body) {
if (error) { if (error) {
console.error(error); console.error(error);
return; return;
} }
var result = body["results"][0]; var result = body["results"][0];
// we have some custom handling of the data here, as we get
// so much useful data, that we want to insert more rows here
insertNewValue(result["components"]["country"], ctx, "locationCountry", "text"); insertNewValue(result["components"]["country"], ctx, "locationCountry", "text");
insertNewValue(result["components"]["country_code"], ctx, "locationCountryCode", "text"); insertNewValue(result["components"]["country_code"], ctx, "locationCountryCode", "text");
insertNewValue(result["formatted"], ctx, "locationAddress", "text"); insertNewValue(result["formatted"], ctx, "locationAddress", "text");
insertNewValue(result["components"]["continent"], ctx, "locationContinent", "text"); insertNewValue(result["components"]["continent"], ctx, "locationContinent", "text");
insertNewValue(result["annotations"]["currency"]["name"], ctx, "locationCurrency", "text"); insertNewValue(result["annotations"]["currency"]["name"], ctx, "locationCurrency", "text");
insertNewValue(result["annotations"]["timezone"]["short_name"], ctx, "timezone", "text"); insertNewValue(result["annotations"]["timezone"]["short_name"], ctx, "timezone", "text");
var city = result["components"]["city"] || result["components"]["state"]; // vienna is not a city according to their API var city = result["components"]["city"] || result["components"]["state"];
insertNewValue(city, ctx, "locationCity", "text"); insertNewValue(city, ctx, "locationCity", "text");
}); });
var today; var today;
var fromDate; var fromDate;
if (moment().hours() < 18) { if (moment().hours() < 18) {
// this is being run after midnight,
// as I have the tendency to stay up until later
// we will fetch the weather from yesterday
today = moment().subtract("1", "day"); today = moment().subtract("1", "day");
fromDate = moment().subtract("2", "day"); fromDate = moment().subtract("2", "day");
} else { }
else {
today = moment(); today = moment();
fromDate = moment().subtract("1", "day"); fromDate = moment().subtract("1", "day");
} }
// let weatherURL =
// "http://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/weatherdata/history";
// let query = {
// location: lat + "," + lng,
// aggregateHours: "24",
// unitGroup: "metric",
// shortColumnNames: "false",
// key: process.env.WEATHER_API_KEY,
// contentType: "json",
// startDateTime: fromDate.format("YYYY-MM-DD") + "T00:00:00",
// endDateTime: today.format("YYYY-MM-DD") + "T00:00:00"
// };
// console.log(query);
// needle.request("get", weatherURL, query, function(error, response, body) {
// if (error) {
// console.error(error);
// return;
// }
// console.log(body);
// let result = Object.values(body["locations"])[0]["values"];
// console.log(result);
// if (result.length != 2) {
// console.error(
// "Something is wrong here... should only have today and the day before"
// );
// }
// let currentDay = result[1];
// let y = result[0];
// // https://www.visualcrossing.com/weather-data-documentation
// // Today
// insertNewValue(currentDay["temp"], ctx, "weatherCelsius", "number");
// insertNewValue(currentDay["maxt"], ctx, "weatherCelsiusMax", "number");
// insertNewValue(currentDay["mint"], ctx, "weatherCelsiusMin", "number");
// insertNewValue(currentDay["precip"], ctx, "weatherRain", "number");
// insertNewValue(
// currentDay["precipcover"],
// ctx,
// "weatherRainPercentageOfDay",
// "number"
// );
// insertNewValue(currentDay["humidity"], ctx, "weatherHumidity", "number");
// insertNewValue(currentDay["snowdepth"], ctx, "weatherSnow", "number");
// // Yesterday
// insertNewValue(y["temp"], ctx, "weatherYesterdayCelsius", "number");
// insertNewValue(y["maxt"], ctx, "weatherYesterdayCelsiusMax", "number");
// insertNewValue(y["mint"], ctx, "weatherYesterdayCelsiusMin", "number");
// insertNewValue(y["precip"], ctx, "weatherYesterdayRain", "number");
// insertNewValue(
// y["precipcover"],
// ctx,
// "weatherYesterdayRainPercentageOfDay",
// "number"
// );
// insertNewValue(y["humidity"], ctx, "weatherYesterdayHumidity", "number");
// insertNewValue(y["snowdepth"], ctx, "weatherYesterdaySnow", "number");
// triggerNextQuestionFromQueue(ctx);
// });
}); });
// parse commands to start a survey bot.hears(/\/(\w+)/, function (ctx) {
bot.hears(/\/(\w+)/, function(ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
return; return;
} }
// user entered a command to start the survey
var command = ctx.match[1]; var command = ctx.match[1];
var matchingCommandObject = config.userConfig[command]; var matchingCommandObject = config.userConfig[command];
if (matchingCommandObject && matchingCommandObject.questions) { if (matchingCommandObject && matchingCommandObject.questions) {
@@ -603,24 +473,24 @@ function initBot() {
saveLastRun(command); saveLastRun(command);
if (currentlyAskedQuestionQueue.length > 0 && if (currentlyAskedQuestionQueue.length > 0 &&
currentlyAskedQuestionMessageId) { currentlyAskedQuestionMessageId) {
// Happens when the user triggers another survey, without having completed the first one yet
ctx.reply("^ Okay, but please answer my previous question also, thanks ^", Extra.inReplyTo(currentlyAskedQuestionMessageId)); ctx.reply("^ Okay, but please answer my previous question also, thanks ^", Extra.inReplyTo(currentlyAskedQuestionMessageId));
} }
currentlyAskedQuestionQueue = currentlyAskedQuestionQueue.concat(matchingCommandObject.questions.slice(0)); // slice is a poor human's .clone basically currentlyAskedQuestionQueue = currentlyAskedQuestionQueue.concat(matchingCommandObject.questions.slice(0));
if (currentlyAskedQuestionObject == null) { if (currentlyAskedQuestionObject == null) {
triggerNextQuestionFromQueue(ctx); triggerNextQuestionFromQueue(ctx);
} }
} else { }
else {
ctx ctx
.reply("Sorry, I don't know how to run `/" + command) .reply("Sorry, I don't know how to run `/" + command)
.then(function(_a) { .then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
sendAvailableCommands(ctx); sendAvailableCommands(ctx);
}); });
} }
}); });
bot.start(function(ctx) { return ctx.reply("Welcome to FxLifeSheet"); }); bot.start(function (ctx) { return ctx.reply("Welcome to FxLifeSheet"); });
bot.on(["voice", "video_note"], function(ctx) { bot.on(["voice", "video_note"], function (ctx) {
if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) { if (ctx.update.message.from.username != process.env.TELEGRAM_USER_ID) {
return; return;
} }
@@ -631,15 +501,15 @@ function initBot() {
console.log("Received voice with file ID '" + fileId + "'"); console.log("Received voice with file ID '" + fileId + "'");
ctx ctx
.reply("🦄 Received message, transcribing now...", Extra.inReplyTo(ctx.message.message_id)) .reply("🦄 Received message, transcribing now...", Extra.inReplyTo(ctx.message.message_id))
.then(function(_a) { .then(function (_a) {
var message_id = _a.message_id; var message_id = _a.message_id;
transcribingMessageId = message_id; transcribingMessageId = message_id;
}); });
var transcribeURL = "https://bubbles-transcribe.herokuapp.com/transcribe"; var transcribeURL = "https://bubbles-transcribe.herokuapp.com/transcribe";
transcribeURL += "?file_id=" + fileId; transcribeURL += "?file_id=" + fileId;
transcribeURL += "&language=en-US"; transcribeURL += "&language=en-US";
transcribeURL += "&telegram_token=" + process.env.TELEGRAM_BOT_TOKEN; transcribeURL += "&telegram_token=" + process.env.TELEGRAM_BOT_TOKEN;
needle.get(transcribeURL, function(error, response, body) { needle.get(transcribeURL, function (error, response, body) {
if (error) { if (error) {
console.error(error); console.error(error);
ctx.reply("Error: " + error, Extra.inReplyTo(ctx.message.message_id)); ctx.reply("Error: " + error, Extra.inReplyTo(ctx.message.message_id));
@@ -651,11 +521,11 @@ function initBot() {
} }
}); });
}); });
bot.help(function(ctx) { bot.help(function (ctx) {
return ctx.reply("No in-bot help right now, for now please visit https://github.com/KrauseFx/FxLifeSheet"); return ctx.reply("No in-bot help right now, for now please visit https://github.com/KrauseFx/FxLifeSheet");
}); });
bot.on("sticker", function(ctx) { return ctx.reply("Sorry, I don't support stickers"); }); bot.on("sticker", function (ctx) { return ctx.reply("Sorry, I don't support stickers"); });
bot.hears("hi", function(ctx) { return ctx.reply("Hey there"); }); bot.hears("hi", function (ctx) { return ctx.reply("Hey there"); });
// has to be last
bot.launch(); bot.launch();
} }
//# sourceMappingURL=worker.js.map

View File

@@ -1,5 +1,3 @@
declare var require: any;
// Third party dependencies // Third party dependencies
const moment = require("moment"); const moment = require("moment");
var needle = require("needle"); var needle = require("needle");