Skip to content
23 changes: 19 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ match the key words and the tags in any way you like!

## Commands

E621Bot comes with a number of commands. These commands must be used in a direct chat with the bot. As this bot is mostly an inline bot, you mostly interact with it by typing `@e621bot your query here` while in another chat to interact with it. To use commands open a direct message chat with the bot, and from there you can use slash commands (`/command`). e621Bot currently has 6 commands.
E621Bot comes with a number of commands. These commands must be used in a direct
chat with the bot. As this bot is mostly an inline bot, you mostly interact with
it by typing `@e621bot your query here` while in another chat to interact with
it. To use commands open a direct message chat with the bot, and from there you
can use slash commands (`/command`). e621Bot currently has 6 commands.

- `/start` Starts the bot
- `/help` Show a help message
Expand All @@ -56,11 +60,19 @@ E621Bot comes with a number of commands. These commands must be used in a direc

## Blacklist

e621 has a **LOT** of tags, you may not be comfortable with all of them. That's where your blacklist comes in! You can use the blacklist to filter posts out with tags that you don't want to see. e621 itself [has default blacklist settings](https://e621.net/help/blacklist) in place for all guest users, this is the same default blacklist the bot will start you out with when you first use the bot.
e621 has a **LOT** of tags, you may not be comfortable with all of them. That's
where your blacklist comes in! You can use the blacklist to filter posts out
with tags that you don't want to see. e621 itself
[has default blacklist settings](https://e621.net/help/blacklist) in place for
all guest users, this is the same default blacklist the bot will start you out
with when you first use the bot.

## Editing your blacklist

You can edit this default list by using `/edit_blacklist`, you will be sent your current blacklist which you can copy and paste into the chat. From there you can edit it, and send it back to the bot. The bot will save your blacklist, and display the updated blacklist so you can verify the changes.
You can edit this default list by using `/edit_blacklist`, you will be sent your
current blacklist which you can copy and paste into the chat. From there you can
edit it, and send it back to the bot. The bot will save your blacklist, and
display the updated blacklist so you can verify the changes.

## How do I setup the bot?

Expand All @@ -69,10 +81,13 @@ If you want to run you own version of the bot you can download the source code.
### Make sure you have all dependencies

#### Dependencies:

- Deno 2.X
- Sqlite3

Once you download the source code and you have [Deno](https://deno.com/) installed you should get sqlite3
Once you download the source code and you have [Deno](https://deno.com/)
installed you should get sqlite3

- Ubuntu: `sudo apt install sqlite3`
- Arch: ``

Expand Down
7 changes: 1 addition & 6 deletions classes/E621Bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,6 @@ export class E621Bot extends Bot<e621BotContext> {
continue;
}

if (/(safe|questionable|explicit)/.test(queryTags[tag])) {
urlBuilder.rating = encodeURIComponent(`rating:${queryTags[tag]}`);
continue;
}

if (/(score|favcount|random|hot)/.test(queryTags[tag])) {
urlBuilder.order = encodeURIComponent(`order:${queryTags[tag]}`);
continue;
Expand Down Expand Up @@ -245,7 +240,7 @@ export class E621Bot extends Bot<e621BotContext> {
});
const tags = tagMatrix.flat();

console.log(this.buildBlacklistRegex(blacklistedTags));
// console.log(this.buildBlacklistRegex(blacklistedTags));

// Check for blacklisted tags
for (const tag in tags) {
Expand Down
4 changes: 2 additions & 2 deletions classes/E621UrlBuilderPosts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ export class E621UrlBuilderPosts implements E621UrlBuilder {
* Returns a URL built fromt he current state of the builder itself and a base URL
* @returns string URL built from the current state of the builder
*/
buildUrl() {
return `${this.baseUrl}${this.endpoint}${this.tagString()}&page=${this.page}&limit=${this.limit}`;
buildUrl(rating: string) {
return `${this.baseUrl}${this.endpoint}${this.tagString()}+${rating}&page=${this.page}&limit=${this.limit}`;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions db/migration.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { PathLike } from "node:fs";
import { DatabaseSync } from "node:sqlite";

export function createBlacklistDb(dbFile: PathLike) {
export function createUserDb(dbFile: PathLike) {
try {
const db = new DatabaseSync(dbFile);

db.prepare(`
CREATE TABLE IF NOT EXISTS user_db (
id INTEGER PRIMARY KEY AUTOINCREMENT,
telegram_id BIGINT NOT NULL UNIQUE,
rating TEXT DEFAULT 's', -- Default rating for the bot for now will be s (safe)
blacklist TEXT DEFAULT 'gore,scat,watersports,young,loli,shota' -- Default blacklist for every user on e621
);
`).run();
Expand Down
4 changes: 2 additions & 2 deletions db/utils/createDb.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { PathLike } from "node:fs";
import { createBlacklistDb } from "../migration.ts";
import { createUserDb } from "../migration.ts";

export function createDatabase(dbFile: PathLike): boolean {
try {
createBlacklistDb(dbFile);
createUserDb(dbFile);
return true;
} catch (err) {
console.error(`Failed to create Database: ${dbFile}: ${err}`);
Expand Down
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.0",
"tasks": {
"dev": "deno run --allow-write --allow-net --allow-env --allow-read --watch main.ts",
"test": "deno test --allow-write --allow-net --allow-env --allow-read ./tests/*",
Expand Down
5 changes: 3 additions & 2 deletions handlers/edit_blacklist.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Conversation } from "@grammyjs/conversations";
import { Context } from "grammy";
import { User } from "../types/Blacklist.ts";
import { getUserByTelegramId, updateUser } from "../models/user.ts";
import { getUserByTelegramId, updateBlacklist } from "../models/user.ts";
import { DB_FILE } from "../constants/strings.ts";

/**
Expand Down Expand Up @@ -30,11 +30,12 @@ export async function edit_blacklist(conversation: Conversation, ctx: Context) {

const newUserData: User = {
telegramId: ctx.from?.id!,
rating: "",
blacklist: blacklist,
};

try {
updateUser(newUserData, DB_FILE);
updateBlacklist(newUserData, DB_FILE);
} catch (err) {
console.error(
`Failed to save blacklist for ${ctx.from?.first_name} id ${ctx.from?.id}: ${err}`,
Expand Down
2 changes: 1 addition & 1 deletion interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export interface E621UrlBuilder {
limit?: number;
page?: number;
endpoint: string;
buildUrl(): string;
buildUrl(rating?: string): string;
}

export interface Pool {
Expand Down
48 changes: 45 additions & 3 deletions main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import { createDatabase } from "./db/utils/createDb.ts";
import {
getUserByTelegramId as getUserByTelegramId,
insertUser as insertUser,
updateRating,
userExists as userExists,
} from "./models/user.ts";
import { DB_FILE } from "./constants/strings.ts";

if (import.meta.main) {
try {
Expand Down Expand Up @@ -73,6 +75,41 @@ if (import.meta.main) {
await ctx.conversation.enter("edit_blacklist");
});

yiffBot.command("rating", async (ctx) => {
switch (ctx.match) {
case "s":
case "q":
case "e":
case "safe":
case "questionable":
case "explicit": {
try {
updateRating(
ctx.from?.id!,
encodeURIComponent(`rating:${ctx.match}`),
DB_FILE,
);
await ctx.reply(`Updated your rating to <b>${ctx.match}</b>.`, {
parse_mode: "HTML",
});
} catch (err) {
console.error(
`Failed to update rating setting for user ${ctx.from?.id}: ${err}`,
);
}

break;
}
default: {
await ctx.reply(
`Invalid rating: <b>${ctx.match}</b>! The rating must be s (safe), q (questionable), or e (explicit).`,
{ parse_mode: "HTML" },
);
break;
}
}
});

yiffBot.command("help", async (ctx) => {
await ctx.reply(strings.helpString, { parse_mode: "HTML" });
});
Expand Down Expand Up @@ -188,7 +225,10 @@ if (import.meta.main) {
yiffBot.on("inline_query", async (ctx) => {
// Create new user if not exists
if (!userExists(ctx.from.id, strings.DB_FILE)) {
insertUser({ telegramId: ctx.from.id, blacklist: [] }, strings.DB_FILE);
insertUser(
{ telegramId: ctx.from.id, blacklist: [], rating: "" },
strings.DB_FILE,
);
}
const user = getUserByTelegramId(ctx.from.id, strings.DB_FILE);

Expand Down Expand Up @@ -219,10 +259,12 @@ if (import.meta.main) {

urlBuilder.page = page;

console.log(`Current URL: ${urlBuilder.buildUrl()}`);
console.log(`Current URL: ${urlBuilder.buildUrl(user?.rating!)}`);

// Grab our data
const request = await yiffBot.sendRequest(urlBuilder.buildUrl());
const request = await yiffBot.sendRequest(
urlBuilder.buildUrl(user?.rating!),
);
const requestJson = await request.json();
const postsJson = requestJson.posts; // An array of 50 posts

Expand Down
28 changes: 27 additions & 1 deletion models/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function insertUser(user: User, dbFile: PathLike) {
* @param dbFile
* @returns StatementResultingChanges
*/
export function updateUser(user: User, dbFile: PathLike) {
export function updateBlacklist(user: User, dbFile: PathLike) {
try {
const db = new DatabaseSync(dbFile);
const queryResult = db.prepare(
Expand All @@ -47,6 +47,31 @@ export function updateUser(user: User, dbFile: PathLike) {
}
}

/**
* @param rating Rating the user picked
* @param id Telegram Id of user
* @param dbFile Path to DB file
* @returns StatementResultingChanges
*/
export function updateRating(id: number, rating: string, dbFile: PathLike) {
try {
const db = new DatabaseSync(dbFile);
const queryResult = db.prepare(
`UPDATE OR FAIL user_db SET rating = ? WHERE telegram_id = ?;`,
).run(
rating,
id,
);
db.close();
return queryResult;
} catch (err) {
console.error(
`Failed to update rating for user ${id}: ${err}`,
);
throw err;
}
}

/**
* Delete a user from the db
* @param telegramId Id attatched to blacklist
Expand Down Expand Up @@ -90,6 +115,7 @@ export function getUserByTelegramId(
return {
id: Number(queryResult.id),
telegramId: Number(queryResult.telegram_id),
rating: String(queryResult.rating),
blacklist: String(queryResult.blacklist).split(",") ||
defaultBlacklist.split(","),
};
Expand Down
4 changes: 2 additions & 2 deletions tests/migration_tests.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { assertEquals } from "@std/assert/equals";
import { DatabaseSync } from "node:sqlite";
import { createBlacklistDb } from "../db/migration.ts";
import { createUserDb } from "../db/migration.ts";
import { assertNotEquals } from "@std/assert/not-equals";
import { TEST_DB_FILE } from "../constants/strings.ts";
import { existsSync } from "node:fs";
Expand All @@ -10,7 +10,7 @@ if (!existsSync("db/test_db")) {
}

Deno.test(function testCreateBlacklistDb() {
createBlacklistDb(TEST_DB_FILE);
createUserDb(TEST_DB_FILE);

// Get table
const db = new DatabaseSync(TEST_DB_FILE);
Expand Down
Loading