Skip to content

Commit

Permalink
Remarks
Browse files Browse the repository at this point in the history
  • Loading branch information
ojaha065 committed Dec 1, 2024
1 parent bc3cfbf commit 30d05e4
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 106 deletions.
2 changes: 1 addition & 1 deletion config.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
["kotiherkku", "Tarkasta https://www.serviini.fi/kotiherkku-ruokapuoti"]
],
"extraParams": {
"VAIHA_PATTERN": "https://www.vaiha.fi/kaikki-tapahtumat/pormestarin-ja-vaiha-savon-viikon-lounaat-VK${weekNumber}"
"VAIHA_PATTERN": "https://www.vaiha.fi/kaikki-tapahtumat/pormestarin-ja-vaiha-savon-viikon-lounaat-vk${weekNumber}"
},
"gitUrl": "https://github.com/ojaha065/lounasbotti",
"displayVoters": true,
Expand Down
197 changes: 100 additions & 97 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "lounasbotti",
"type": "module",
"version": "1.10.12",
"version": "1.10.13",
"private": true,
"description": "Slack bot for retrieving lunch menus of local restaurants. Very much WIP and not meant for public use.",
"main": "./dist/server.js",
Expand Down
55 changes: 54 additions & 1 deletion src/BotCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { lounasCache } from "./server.js";
import { truncateMessage } from "./BotEvents.js";

const ANNOUNCE_REGEXP = /announce "((?:\w|\d){1,30})"\s"(.{1,2000})"/;
const ADMIN_COMMANDS = ["truncateall", "announce"];
const REMARK_REGEXP = /remark\s+(add|remove)\s+(.{1,1024})<>(.{1,2048})/;
const ADMIN_COMMANDS = ["truncateall", "announce", "remark"];

export default function(app: bolt.App, settings: Settings) {
app.command("/whoami", async args => {
Expand Down Expand Up @@ -187,6 +188,58 @@ export default function(app: bolt.App, settings: Settings) {
}).catch(console.error);
return;
}

if (commandText.startsWith("remark")) {
const match = REMARK_REGEXP.exec(args.command.text);
if (!match) {
args.respond({
response_type: "ephemeral",
text: "Error adding remark: Invalid syntax"
});
return;
}

const operation = match[1];
const message = match[3];

let regExp;
try {
regExp = new RegExp(match[2], "ims");
} catch {
console.debug(`Invalid regular expression: ${match[2]}`);
args.respond({
response_type: "ephemeral",
text: "Error adding remark: Invalid regular expression"
});
return;
}

const mongoOperation = operation === "add"
? {$addToSet: { remarks: { regExp: regExp, message: message} }}
: {$pull: { remarks: { regExp: regExp} }}

SettingsRepository.update({
instanceId: settings.instanceId,
...mongoOperation
}).then(instanceSettings => {
settings.remarks = instanceSettings.remarks;
console.info(`User ${args.body.user_id} (${args.body.user_name}) added a new remark`);
args.respond({
response_type: "ephemeral",
text: operation === "add"
? `Remark added successfully! Use ${Md.codeInline(`/lounasbotti remark remove ${regExp.source}<>confirm`)} to remove.`
: 'Remark removed successfully!'
});
}).catch(error => {
console.error(error);
args.respond({
response_type: "ephemeral",
text: "Error adding remark. Please contact support."
});
});

return;
}
}

args.respond({
Expand Down
20 changes: 20 additions & 0 deletions src/BotEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,28 @@ const initEvents = (app: App, settings: Settings): void => {
vote.userId === args.body.user.id
&& (settings.limitToOneVotePerUser || vote.action === actionValue)
);

if (duplicateVote) {
console.debug("Duplicate vote! Removing vote...");
} else if (settings.remarks?.length) {
try {
const restaurant = actionValue.replace("upvote-", "") as Restaurant;
const allItems = lounasMessage.menu.find(menu => menu.restaurant === restaurant)?.items;
if (allItems) {
for (const remark of settings.remarks) {
if (allItems.some(item => item && remark.regExp.test(item))) {
args.respond({
response_type: "ephemeral",
replace_original: false,
text: remark.message
});
break;
}
}
}
} catch (error) {
console.error(error);
}
}

try {
Expand Down
7 changes: 6 additions & 1 deletion src/model/Settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import RuokapaikkaFiDataProvider from "./dataProviders/RuokapaikkaFiDataProvider
import MockDataProvider from "./dataProviders/MockDataProvider.js";
import * as SettingsRepository from "./SettingsRepository.js";

type Remarks = [{ regExp: RegExp, message: string }];

class Settings {
public instanceId: string;
public latLon: {lat: number, lon: number};
Expand All @@ -31,6 +33,7 @@ class Settings {
// Instance settings
public limitToOneVotePerUser = false;
public subscribedChannels?: string[] | undefined;
public remarks?: Remarks | undefined

public _dataProvider: LounasDataProvider | "self" = "self";

Expand Down Expand Up @@ -142,7 +145,8 @@ class Settings {
type InstanceSettings = {
instanceId: string,
limitToOneVotePerUser?: boolean,
subscribedChannels?: string[] | undefined;
subscribedChannels?: string[] | undefined,
remarks?: [{ regExp: RegExp, message: string }] | undefined
};

enum Restaurant {
Expand Down Expand Up @@ -206,6 +210,7 @@ const readInstanceSettings = (settings: Settings): void => {
SettingsRepository.findOrCreate(settings.instanceId).then(instanceSettings => {
settings.limitToOneVotePerUser = Boolean(instanceSettings.limitToOneVotePerUser);
settings.subscribedChannels = instanceSettings.subscribedChannels;
settings.remarks = instanceSettings.remarks;
}).catch(error => {
console.error(error);
});
Expand Down
16 changes: 12 additions & 4 deletions src/model/SettingsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,15 @@ import mongoose from "mongoose";
import type { InstanceSettings } from "./Settings.js";

const instanceSettingsSchema = new mongoose.Schema<InstanceSettings>({
instanceId: String,
instanceId: {
type: String,
required: true,
immutable: true,
unique: true
},
limitToOneVotePerUser: Boolean,
subscribedChannels: [String]
subscribedChannels: [String],
remarks: Object
});

const InstanceSettingsModel = mongoose.model<InstanceSettings>("InstanceSettings", instanceSettingsSchema);
Expand All @@ -30,7 +36,8 @@ const findOrCreate = async (instanceId: string): Promise<InstanceSettings> => {
return {
instanceId: json.instanceId,
limitToOneVotePerUser: Boolean(json.limitToOneVotePerUser),
subscribedChannels: json.subscribedChannels
subscribedChannels: json.subscribedChannels,
remarks: json.remarks
};
};

Expand All @@ -53,7 +60,8 @@ const update = async (update: InstanceSettings | UpdateQuery<InstanceSettings>):
return {
instanceId: json.instanceId,
limitToOneVotePerUser: Boolean(json.limitToOneVotePerUser),
subscribedChannels: json.subscribedChannels
subscribedChannels: json.subscribedChannels,
remarks: json.remarks
};
};

Expand Down
2 changes: 1 addition & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ dotenv.config();

// Global
global.LOUNASBOTTI_JOBS = {};
global.LOUNASBOTTI_VERSION = process.env["npm_package_version"] ?? "1.10.12";
global.LOUNASBOTTI_VERSION = process.env["npm_package_version"] ?? "1.10.13";
global.LOUNASBOTTI_TO_BE_TRUNCATED = [];

import * as Sentry from "@sentry/node";
Expand Down

0 comments on commit 30d05e4

Please sign in to comment.