feat(tags): channel, category specific

This commit is contained in:
Jozef Steinhübl 2023-08-25 08:23:12 +02:00
parent 3d090d850b
commit 6452ec0b6a
9 changed files with 60 additions and 18 deletions

12
data/tags/dev-channel.md Normal file
View file

@ -0,0 +1,12 @@
---
question: This is not a support channel where can i ask for help?
keywords:
- "development"
- "dev-channel"
- "codebase"
- "internals"
category_ids:
- "994349439005237369" # BUN INTERNALS category
---
This channel is for bun development, if you need help, <#1006402902513946735>, <#887787428973281300> and <#1004133980272078938> are here for you <:peekbun:995823659786711082>

View file

@ -7,6 +7,7 @@ keywords:
- "core" - "core"
- "illegal" - "illegal"
--- ---
Update to latest version using: Update to latest version using:
```sh ```sh
curl https://bun.sh/install | bash curl https://bun.sh/install | bash

View file

@ -7,7 +7,8 @@ keywords:
- "update" - "update"
- "linux" - "linux"
--- ---
To fix this error, you need to update Linux kernel.
To fix `io uring is not supported`, you need to update Linux kernel.
If you are using the Windows Subsystem for Linux, do: If you are using the Windows Subsystem for Linux, do:
**1.** Open powershell as administrator **1.** Open powershell as administrator
**2.** Run: **2.** Run:

View file

@ -1,7 +1,8 @@
--- ---
question: "Where can i add new tag to bot?" question: "Where can i add new tag to the bot?"
keywords: keywords:
- "tags" - "tags"
- "contributing" - "contributing"
--- ---
To create or update tag, check [xHyroM/bun-discord-bot#contributing-tags](<https://github.com/xHyroM/bun-discord-bot/#contributing-tags>) To create or update tag, check [xHyroM/bun-discord-bot#contributing-tags](<https://github.com/xHyroM/bun-discord-bot/#contributing-tags>)

View file

@ -4,5 +4,6 @@ keywords:
- "windows" - "windows"
- "windows support" - "windows support"
--- ---
Bun does not currently have support for Windows, so you must use WSL (Windows Subsystem for Linux). Bun does not currently have support for Windows, so you must use WSL (Windows Subsystem for Linux).
To install WSL, check [microsoft documentation](<https://docs.microsoft.com/en-us/windows/wsl/install>) To install WSL, check [microsoft documentation](<https://docs.microsoft.com/en-us/windows/wsl/install>)

View file

@ -1,4 +1,4 @@
import { SlashCommandStringOption, SlashCommandUserOption, User } from "discord.js"; import { GuildTextBasedChannel, SlashCommandStringOption, SlashCommandUserOption, User } from "discord.js";
import { defineCommand } from "../loaders/commands.ts"; import { defineCommand } from "../loaders/commands.ts";
import { AutocompleteContext } from "../structs/context/AutocompleteContext.ts"; import { AutocompleteContext } from "../structs/context/AutocompleteContext.ts";
import { getTags, searchTag } from "../loaders/tags.ts"; import { getTags, searchTag } from "../loaders/tags.ts";
@ -19,14 +19,14 @@ defineCommand({
run: async(context: AutocompleteContext) => { run: async(context: AutocompleteContext) => {
const query = context.options.getString("query"); const query = context.options.getString("query");
if (!query) { if (!query) {
return context.respond(getTags(25)); return context.respond(getTags(context.channel, 25));
} }
const tags = searchTag(query, true); const tags = searchTag(context.channel, query, true);
if (tags.length > 0) if (tags.length > 0)
return context.respond(tags); return context.respond(tags);
return context.respond(getTags(25)); return context.respond(getTags(context.channel, 25));
}, },
}, },
{ {
@ -41,7 +41,7 @@ defineCommand({
const query = ctx.interaction.options.getString("query"); const query = ctx.interaction.options.getString("query");
const target = ctx.interaction.options.getUser("target"); const target = ctx.interaction.options.getUser("target");
const tag = searchTag(query, false); const tag = searchTag(ctx.channel, query, false);
if (!tag) { if (!tag) {
return ctx.reply({ return ctx.reply({
content: `\`\` Could not find a tag \`${query}\``, content: `\`\` Could not find a tag \`${query}\``,
@ -61,12 +61,14 @@ defineCommand({
}); });
}, },
runMessage: (ctx: MessageCommandContext) => { runMessage: (ctx: MessageCommandContext) => {
if (!ctx.message.inGuild()) return;
const keyword = ctx.options?.[0] ?? "what-is-bun"; const keyword = ctx.options?.[0] ?? "what-is-bun";
const target = ctx.options?.[1]?.match(/([0-9]+)/)?.[0]; const target = ctx.options?.[1]?.match(/([0-9]+)/)?.[0];
const resolvedTarget = target ? Bubu.users.cache.get(target) : null; const resolvedTarget = target ? Bubu.users.cache.get(target) : null;
const tag = searchTag(keyword, false); const tag = searchTag(ctx.channel as GuildTextBasedChannel, keyword, false);
if (!keyword || !tag) { if (!keyword || !tag) {
return ctx.reply({ return ctx.reply({
content: `\`\` Could not find a tag \`${keyword}\``, content: `\`\` Could not find a tag \`${keyword}\``,

View file

@ -3,7 +3,7 @@ import { readFileSync } from "node:fs";
import { globSync as glob } from "glob"; import { globSync as glob } from "glob";
import { join } from "node:path"; import { join } from "node:path";
import { Tag } from "../structs/Tag"; import { Tag } from "../structs/Tag";
import { APIApplicationCommandOptionChoice } from "discord.js"; import { APIApplicationCommandOptionChoice, BaseGuildTextChannel, GuildTextBasedChannel, TextBasedChannel } from "discord.js";
import { safeSlice } from "../util"; import { safeSlice } from "../util";
const tags = glob(join(__dirname, "..", "..", "data", "tags", "*.md")); const tags = glob(join(__dirname, "..", "..", "data", "tags", "*.md"));
@ -17,13 +17,30 @@ for (const tag of tags) {
TAGS.push({ TAGS.push({
question: frontMatter.data.question, question: frontMatter.data.question,
keywords: frontMatter.data.keywords, keywords: frontMatter.data.keywords,
answer: frontMatter.content answer: frontMatter.content,
category_ids: frontMatter.data.category_ids ?? null,
channel_ids: frontMatter.data.channel_ids ?? null
}); });
} }
export function getTags(length: number): APIApplicationCommandOptionChoice[] { function getAvailableTags(channel: GuildTextBasedChannel) {
return TAGS.filter(t => {
const channelIds = t.channel_ids;
const categoryIds = t.category_ids;
if (!channelIds && !categoryIds) return true;
if (channelIds && channelIds.includes(channel.id)) return true;
if (categoryIds && categoryIds.includes(channel.parentId)) return true;
return false;
});
}
export function getTags(channel: GuildTextBasedChannel, length: number): APIApplicationCommandOptionChoice[] {
const availableTags = getAvailableTags(channel);
return safeSlice( return safeSlice(
TAGS.map((tag) => ( availableTags.map((tag) => (
{ {
name: `🚀 ${tag.question}`, name: `🚀 ${tag.question}`,
value: tag.question value: tag.question
@ -32,14 +49,15 @@ export function getTags(length: number): APIApplicationCommandOptionChoice[] {
length); length);
} }
export function searchTag<T extends boolean>(providedQuery: string, multiple?: T): T extends true ? APIApplicationCommandOptionChoice[] : Tag { export function searchTag<T extends boolean>(channel: GuildTextBasedChannel, providedQuery: string, multiple?: T): T extends true ? APIApplicationCommandOptionChoice[] : Tag {
const availableTags = getAvailableTags(channel);
const query = providedQuery?.toLowerCase()?.replace(/-/g, " "); const query = providedQuery?.toLowerCase()?.replace(/-/g, " ");
if (!multiple) { if (!multiple) {
const exactKeyword = TAGS.find(tag => tag.keywords.find((k) => k.toLowerCase() === query)); const exactKeyword = availableTags.find(tag => tag.keywords.find((k) => k.toLowerCase() === query));
const keywordMatch = TAGS.find(tag => tag.keywords.find((k) => k.toLowerCase().includes(query))); const keywordMatch = availableTags.find(tag => tag.keywords.find((k) => k.toLowerCase().includes(query)));
const questionMatch = TAGS.find(tag => tag.question.toLowerCase().includes(query)); const questionMatch = availableTags.find(tag => tag.question.toLowerCase().includes(query));
const answerMatch = TAGS.find(tag => tag.answer.toLowerCase().includes(query)); const answerMatch = availableTags.find(tag => tag.answer.toLowerCase().includes(query));
const tag = exactKeyword ?? questionMatch ?? keywordMatch ?? answerMatch; const tag = exactKeyword ?? questionMatch ?? keywordMatch ?? answerMatch;
return tag as T extends true ? APIApplicationCommandOptionChoice[] : Tag; return tag as T extends true ? APIApplicationCommandOptionChoice[] : Tag;
@ -50,7 +68,7 @@ export function searchTag<T extends boolean>(providedQuery: string, multiple?: T
const questionMatches: APIApplicationCommandOptionChoice[] = []; const questionMatches: APIApplicationCommandOptionChoice[] = [];
const answerMatches: APIApplicationCommandOptionChoice[] = []; const answerMatches: APIApplicationCommandOptionChoice[] = [];
for (const tag of TAGS) { for (const tag of availableTags) {
const exactKeyword = tag.keywords.find((t) => t.toLowerCase() === query); const exactKeyword = tag.keywords.find((t) => t.toLowerCase() === query);
const includesKeyword = tag.keywords.find((t) => t.toLowerCase().includes(query)); const includesKeyword = tag.keywords.find((t) => t.toLowerCase().includes(query));
const questionMatch = tag.question.toLowerCase().includes(query); const questionMatch = tag.question.toLowerCase().includes(query);

View file

@ -2,4 +2,6 @@ export interface Tag {
question: string; question: string;
answer: string; answer: string;
keywords: string[]; keywords: string[];
category_ids: string[] | null;
channel_ids: string[] | null;
} }

View file

@ -12,6 +12,10 @@ export class AutocompleteContext {
this.interaction = interaction; this.interaction = interaction;
} }
get channel() {
return this.interaction.channel;
}
get user() { get user() {
return this.interaction.user; return this.interaction.user;
} }