Skip to content

Commit 76d8c15

Browse files
authored
Merge pull request #69 from MobiFlight/copilot/enable-markdown-bot-messages
Replace rigid wiki message template with markdown content arrays
2 parents ed864d2 + b4135ba commit 76d8c15

File tree

5 files changed

+206
-49
lines changed

5 files changed

+206
-49
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,5 @@ dist
129129
.yarn/install-state.gz
130130
.pnp.*
131131

132-
.env
132+
.env
133+
Docker/.env.prod

Docker/docker-compose.yml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
version: '3.8'
1+
version: "3.8"
22

33
name: mobiflight-discord
44

55
services:
66
bot:
7-
image: ghcr.io/neilenns/mobiflight-discord-bot:latest
8-
restart: always
7+
image: ghcr.io/mobiflight/mobiflight-discord-bot:latest
8+
restart: always
9+
env_file:
10+
- .env.prod
911
environment:
10-
- DISCORD_TOKEN=x # Application token
11-
- DISCORD_CLIENT_ID=x # Application ID
12-
- DISCORD_GUILD_ID=x # Server ID
13-
- SOLVED_TAG_NAME=Solved
14-
- ENABLE_COMMANDS=true
15-
- WIKI_ITEMS_PATH=/config/wikiMenuItems.json
16-
- YT_ITEMS_PATH=/config/ytMenuItems.json
12+
- DISCORD_TOKEN=${DISCORD_TOKEN-}
13+
- DISCORD_CLIENT_ID=${DISCORD_CLIENT_ID-}
14+
# Mobiflight server
15+
- DISCORD_GUILD_ID=${DISCORD_GUILD_ID-}
16+
- SOLVED_TAG_NAME=${SOLVED_TAG:-Solved}
17+
- ENABLE_COMMANDS=${ENABLE_COMMANDS:-true}
18+
- WIKI_ITEMS_PATH=${WIKI_ITEMS_PATH:-/config/wikiMenuItems.json}
19+
- OLD_THREAD_AGE_IN_DAYS=${OLD_THREAD_AGE_IN_DAYS:-360}
20+
- LOG_LEVEL=${LOG_LEVEL:-info}
21+
- LOGTAIL_TOKEN=${LOGTAIL_TOKEN-}
22+
- BOT_LOG_WEBHOOK=${BOT_LOG_WEBHOOK-}
1723
volumes:
18-
- ./config:/config
24+
- ./config:/config

src/commands/general/wiki.js

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ const {
44
StringSelectMenuOptionBuilder,
55
SlashCommandBuilder,
66
DiscordjsError,
7-
hyperlink,
8-
hideLinkEmbed,
97
} = require("discord.js");
108
const { replyOrEditReply } = require("../../utilities");
11-
const chokidar = require("chokidar");
129
const fs = require("fs");
1310

1411
const mainLogger = require("../../logger");
@@ -17,6 +14,22 @@ const logger = mainLogger.child({ service: "wiki" });
1714
let selectMenu;
1815
let menuItems;
1916

17+
// Creates a description from the first line of content by stripping markdown formatting
18+
function createDescription(contentFirstLine) {
19+
let description = contentFirstLine;
20+
21+
// Remove markdown links [text](url) -> text
22+
description = description.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
23+
24+
// Remove markdown formatting characters
25+
description = description.replace(/[*_~`#]/g, "");
26+
27+
// Remove leading emojis (using common emoji ranges) and whitespace
28+
description = description.replace(/^[\u{1F300}-\u{1F64F}\u{1F680}-\u{1F6FF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}]+/ug, "");
29+
30+
return description.trim().substring(0, 100);
31+
}
32+
2033
function loadMenuItems() {
2134
logger.debug(`Loading menu items from ${process.env.WIKI_ITEMS_PATH}`);
2235
try {
@@ -30,12 +43,18 @@ function loadMenuItems() {
3043
.setPlaceholder("Select a wiki topic");
3144

3245
menuItems.forEach((item) => {
33-
selectMenu.addOptions(
34-
new StringSelectMenuOptionBuilder()
35-
.setLabel(item.label)
36-
.setDescription(item.description)
37-
.setValue(item.value)
38-
);
46+
const option = new StringSelectMenuOptionBuilder()
47+
.setLabel(item.label)
48+
.setValue(item.value);
49+
50+
// Use description field if present, otherwise generate from first line of content
51+
if (item.description) {
52+
option.setDescription(item.description);
53+
} else if (item.content && item.content.length > 0) {
54+
option.setDescription(createDescription(item.content[0]));
55+
}
56+
57+
selectMenu.addOptions(option);
3958
});
4059
} catch (err) {
4160
logger.error(
@@ -45,9 +64,10 @@ function loadMenuItems() {
4564
}
4665
}
4766

48-
function watchForMenuChanges() {
67+
async function watchForMenuChanges() {
4968
// Start watching for file changes
5069
try {
70+
const chokidar = (await import("chokidar")).default;
5171
chokidar
5272
.watch(process.env.WIKI_ITEMS_PATH, {
5373
awaitWriteFinish: true,
@@ -85,9 +105,9 @@ async function promptForTopic(interaction) {
85105
}
86106

87107
module.exports = {
88-
init: () => {
108+
init: async () => {
89109
loadMenuItems();
90-
watchForMenuChanges();
110+
await watchForMenuChanges();
91111
},
92112
cooldown: 5,
93113
data: new SlashCommandBuilder()
@@ -120,19 +140,35 @@ module.exports = {
120140
return;
121141
}
122142

123-
const link = hyperlink(selectedItem.description, selectedItem.href);
124-
const preamble =
125-
selectedItem.preamble ??
126-
"Check out the following link for more information:";
143+
// Validate that the selected item has a non-empty content array
144+
const isEmptyContent =
145+
!selectedItem.content ||
146+
!Array.isArray(selectedItem.content) ||
147+
selectedItem.content.length === 0;
148+
149+
if (isEmptyContent) {
150+
logger.error(
151+
`Selected wiki item "${topic}" has invalid or empty content`,
152+
{ selectedItem }
153+
);
154+
await replyOrEditReply(interaction, {
155+
content: `No wiki content available for ${topic}`,
156+
ephemeral: true,
157+
});
158+
return;
159+
}
160+
161+
// Build the message content from content array
162+
const messageContent = selectedItem.content.join("\n");
127163

128164
await replyOrEditReply(interaction, {
129-
content: `Link sent!`,
165+
content: 'Link sent!',
130166
components: [],
131167
ephemeral: true,
132168
});
133169

134170
await interaction.channel.send({
135-
content: `${preamble} ${link}`,
171+
content: messageContent,
136172
});
137173
} catch (error) {
138174
// Errors from the user not responding to the dropdown in time don't log,

src/index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function loadEvents() {
3737
}
3838
}
3939

40-
function loadCommands() {
40+
async function loadCommands() {
4141
try {
4242
const foldersPath = path.join(__dirname, "commands");
4343
const commandFolders = fs.readdirSync(foldersPath);
@@ -55,7 +55,7 @@ function loadCommands() {
5555
// Initialize the command if it has an initializer
5656
if ("init" in command) {
5757
logger.debug(`Initializing ${filePath}`, { file: filePath });
58-
command.init();
58+
await command.init();
5959
}
6060

6161
// Set a new item in the Collection with the key as the command name and the value as the exported module
@@ -75,7 +75,9 @@ function loadCommands() {
7575
}
7676

7777
if (process.env.ENABLE_COMMANDS === "true") {
78-
loadCommands();
78+
loadCommands().catch((err) => {
79+
logger.error(`Failed to load commands: ${err.message}`, err);
80+
});
7981
} else {
8082
logger.info(`Commands disabled, skipping creating them.`);
8183
}

wikiMenuItems.json

Lines changed: 128 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,56 +3,168 @@
33
"label": "Honeycomb Bravo",
44
"description": "Using the selector knob on a Honeycomb Bravo",
55
"value": "honeycombbravo",
6-
"href": "https://github.com/MobiFlight/MobiFlight-Connector/wiki/Using-the-selector-knob-on-a-Honeycomb-Bravo",
7-
"preamble": "Check out this wiki page for information on using the selector knob with the Honeycomb Bravo:"
6+
"content": [
7+
"👉 **Check out this wiki page** for information on using the selector knob with the Honeycomb Bravo:",
8+
"[Using the selector knob on a Honeycomb Bravo](<https://github.com/MobiFlight/MobiFlight-Connector/wiki/Using-the-selector-knob-on-a-Honeycomb-Bravo>)"
9+
]
810
},
911
{
1012
"label": "Multiplexers",
1113
"description": "Beginner's guide to input multiplexers",
1214
"value": "multiplexers",
13-
"href": "https://github.com/MobiFlight/MobiFlight-Connector/wiki/Beginner%27s-guide-to-input-multiplexers",
14-
"preamble": "Check out this wiki page for information on using multiplexers with MobiFlight:"
15+
"content": [
16+
"👉 **Check out this wiki page** for information on using multiplexers with MobiFlight:",
17+
"[Beginner's guide to input multiplexers](<https://github.com/MobiFlight/MobiFlight-Connector/wiki/Beginner%27s-guide-to-input-multiplexers>)"
18+
]
1519
},
1620
{
1721
"label": "Input shifters",
1822
"description": "Adding lots of buttons with an input shift register",
1923
"value": "inputshifters",
20-
"href": "https://github.com/MobiFlight/MobiFlight-Connector/wiki/Adding-lots-of-buttons-with-an-input-shift-register",
21-
"preamble": "Check out this wiki page for information on using input shifters with MobiFlight:"
24+
"content": [
25+
"👉 **Check out this wiki page** for information on using input shifters with MobiFlight:",
26+
"[Adding lots of buttons with an input shift register](<https://github.com/MobiFlight/MobiFlight-Connector/wiki/Adding-lots-of-buttons-with-an-input-shift-register>)"
27+
]
2228
},
2329
{
2430
"label": "Output shifters",
2531
"description": "Controlling LEDs with an output shift register",
2632
"value": "outputshifters",
27-
"href": "https://github.com/MobiFlight/MobiFlight-Connector/wiki/Controlling-LEDs-with-an-output-shift-register",
28-
"preamble": "Check out this wiki page for information on using output shifters with MobiFlight:"
33+
"content": [
34+
"👉 **Check out this wiki page** for information on using output shifters with MobiFlight:",
35+
"[Controlling LEDs with an output shift register](<https://github.com/MobiFlight/MobiFlight-Connector/wiki/Controlling-LEDs-with-an-output-shift-register>)"
36+
]
2937
},
3038
{
3139
"label": "Logs",
3240
"description": "Providing logs from MobiFlight",
3341
"value": "logs",
34-
"href": "https://github.com/MobiFlight/MobiFlight-Connector/wiki/Providing-logs-from-MobiFlight",
35-
"preamble": "To help diagnose your problem we need to see your MobiFlight logs. Follow the steps in this wiki to get them:"
42+
"content": [
43+
"To help diagnose your problem we need to see your MobiFlight logs. Follow the steps in this wiki to get them:",
44+
"[Providing logs from MobiFlight](<https://github.com/MobiFlight/MobiFlight-Connector/wiki/Providing-logs-from-MobiFlight>)"
45+
]
3646
},
3747
{
3848
"label": "7 Segments",
3949
"description": "Setting up 7 segment LED modules with SimConnect Events",
4050
"value": "7segments",
41-
"href": "https://github.com/MobiFlight/MobiFlight-Connector/wiki/Tutorial-Setting-up-7-segment-LED-modules-with-SimConnect-Events",
42-
"preamble": "Check out this wiki page for information on using 7-segment LED modules with MobiFlight:"
51+
"content": [
52+
"👉 **Check out this wiki page** for information on using 7-segment LED modules with MobiFlight:",
53+
"[Setting up 7 segment LED modules with SimConnect Events](<https://github.com/MobiFlight/MobiFlight-Connector/wiki/Tutorial-Setting-up-7-segment-LED-modules-with-SimConnect-Events>)"
54+
]
4355
},
4456
{
4557
"label": "CH340",
4658
"description": "Arduino Nano and Mega with CH340 chips connection issues",
4759
"value": "ch340",
48-
"href": "https://www.badcasserole.com/arduino-nano-with-ch340-chips-connection-issues/",
49-
"preamble": "It sounds like your Arduino uses a counterfeit CH340 chip. You can find more information about this problem and how to fix it by visiting this blog post:"
60+
"content": [
61+
"It sounds like your Arduino uses a counterfeit CH340 chip. You can find more information about this problem and how to fix it by visiting this blog post:",
62+
"[Arduino Nano and Mega with CH340 chips connection issues](<https://www.badcasserole.com/arduino-nano-with-ch340-chips-connection-issues/>)"
63+
]
5064
},
5165
{
5266
"label": "Getting started 2023",
5367
"description": "Getting Started 2023 - MobiFlight Tutorial",
5468
"value": "gettingstarted",
55-
"href": "https://www.youtube.com/watch?v=pS8KGfYRNrY",
56-
"preamble": "Check out this YouTube video for a good introduction on getting started with MobiFlight:"
69+
"content": [
70+
"👉 **Check out this YouTube video** for a good introduction on getting started with MobiFlight:",
71+
"[Getting Started 2023 - MobiFlight Tutorial](<https://www.youtube.com/watch?v=pS8KGfYRNrY>)"
72+
]
73+
},
74+
{
75+
"label": "Using potentiometers with MobiFlight",
76+
"description": "Using potentiometers with MobiFlight",
77+
"value": "pots",
78+
"content": [
79+
"👉 **Check out the documentation** for a step-by-step guide to using potentiometers with MobiFlight:",
80+
"[Using potentiometers with MobiFlight](<https://docs.mobiflight.com/devices/potentiometer/>)"
81+
]
82+
},
83+
{
84+
"label": "Finding input events (2020)",
85+
"description": "Uncovering input events using the MSFS2020 behavior dialog",
86+
"value": "inputevents",
87+
"content": [
88+
"You can use the developer tools in MSFS2020 to find the code for the input events.",
89+
"See this blog post for details on how to do it:",
90+
"[Uncovering input events using the MSFS2020 model behavior dialog](<https://www.badcasserole.com/uncovering-input-events-using-the-msfs2020-model-behavior-dialog/>)"
91+
]
92+
},
93+
{
94+
"label": "Finding input events (2024)",
95+
"description": "Finding input events in Microsoft Flight Simulator 2024",
96+
"value": "inputevents2024",
97+
"content": [
98+
"👉 **Check out the documentation** for a step-by-step guide to finding input events in Microsoft Flight Simulator 2024:",
99+
"[Finding input events in Microsoft Flight Simulator 2024](<https://docs.mobiflight.com/guides/input-events-2024/>)"
100+
]
101+
},
102+
{
103+
"label": "Using three-position switches with MobiFlight",
104+
"description": "Using three-position switches with MobiFlight",
105+
"value": "threeposition",
106+
"content": [
107+
"👉 **Check out the documentation** for a step-by-step guide to using three-position switches with MobiFlight:",
108+
"[Using three-position switches with MobiFlight](<https://docs.mobiflight.com/devices/button-switch/>)"
109+
]
110+
},
111+
{
112+
"label": "Verifying the WASM module",
113+
"description": "Verifying the WASM module installation",
114+
"value": "wasm",
115+
"content": [
116+
"👉 **Check out the documentation** for a step-by-step guide to resolving WASM installation issues:",
117+
"[Verifying the WASM module](<https://docs.mobiflight.com/guides/wasm-module/>)"
118+
]
119+
},
120+
{
121+
"label": "Using WINWING devices with MobiFlight",
122+
"description": "Using WINWING devices with MobiFlight",
123+
"value": "ww",
124+
"content": [
125+
"👉 **Check out the documentation** for information on using your WINWING device with MobiFlight:",
126+
"[Using WINWING devices with MobiFlight](<https://docs.mobiflight.com/game-controllers/winwing/>)"
127+
]
128+
},
129+
{
130+
"label": "Using the WINWING PFP 3N with MobiFlight",
131+
"description": "Using the WINWING PFP 3N with MobiFlight",
132+
"value": "cdu",
133+
"content": [
134+
"👉 **Follow the step-by-step guide** to set up your PFP 3N with MobiFlight:",
135+
"[Using the WINWING PFP 3N with MobiFlight](<https://docs.mobiflight.com/game-controllers/winwing/winwing-cdu>)"
136+
]
137+
},
138+
{
139+
"label": "Solving flashing errors",
140+
"description": "Solving flashing errors",
141+
"value": "flashing",
142+
"content": [
143+
"👉 **See the following guide** to troubleshoot ⚡flashing errors:",
144+
"[Solving flashing errors](<https://docs.mobiflight.com/guides/solving-flashing-errors/>)"
145+
]
146+
},
147+
{
148+
"label": "Taking screenshots",
149+
"description": "Taking screenshots using the Windows snipping tool",
150+
"value": "screenshots",
151+
"content": [
152+
"👉 **To take a screenshot**, you can use the ✂️ **Windows snipping tool**.",
153+
"",
154+
"**Here's how:**",
155+
"* `Win` + `Shift` + `S` to open the snipping tool, then select the area you want to capture.",
156+
"* The screenshot will be copied to your clipboard, and you can paste it into your message with `Ctrl` + `V`.",
157+
"",
158+
"🔍 Check out the full tutorial for [Taking screenshots](<https://docs.mobiflight.com/guides/taking-screenshots/>)"
159+
]
160+
},
161+
{
162+
"label": "MobiFlight Installation Path",
163+
"description": "Finding the MobiFlight installation",
164+
"value": "installpath",
165+
"content": [
166+
"👉 **MobiFlight installs to** 📂`%LocalAppData%\\MobiFlight\\MobiFlight Connector`",
167+
"[MobiFlight Installation Path](<https://docs.mobiflight.com/guides/installation-path/>)"
168+
]
57169
}
58170
]

0 commit comments

Comments
 (0)