Skip to content

Commit

Permalink
Add MessageCommand command to Discord bot
Browse files Browse the repository at this point in the history
  • Loading branch information
ludeeus committed Sep 23, 2022
1 parent a6bb619 commit 9281eb9
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 1 deletion.
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ jobs:
- name: Run JQ lint
uses: home-assistant/actions/helpers/jq@master

- name: Setup YQ
uses: chrisdickinson/setup-yq@latest
with:
yq-version: v4.25.3

- name: Use Node.js ${{ env.node-NODE_VERSION }}
uses: actions/setup-node@v3.4.1
with:
Expand All @@ -40,6 +45,9 @@ jobs:
restore-keys: |
${{ runner.os }}-yarn-
- name: Lint YAML files
run: yq '.' ./data/discord_messages.yaml

- name: Install dependencies
run: yarn install --immutable

Expand Down
3 changes: 3 additions & 0 deletions data/discord_messages.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
hello_world:
description: "Print hello world message"
content: "Hello world :wave:"
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"discord.js": "^14.3.0",
"find-up": "^4.0.0",
"graphql": "^16.6.0",
"js-yaml": "^4.1.0",
"nestjs-pino": "^2.5.2",
"node-fetch": "2",
"pino": "^8.4.2",
Expand All @@ -64,6 +65,7 @@
"@nestjs/cli": "^8.2.5",
"@nestjs/schematics": "^8.0.10",
"@nestjs/testing": "^8.4.4",
"@types/js-yaml": "^4",
"@typescript-eslint/eslint-plugin": "5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"eslint": "8.14.0",
Expand Down
124 changes: 124 additions & 0 deletions services/bots/src/discord/commands/message.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import fetch from 'node-fetch';
import yaml from 'js-yaml';

import { TransformPipe } from '@discord-nestjs/common';
import {
DiscordTransformedCommand,
Payload,
TransformedCommandExecutionContext,
Param,
UsePipes,
On,
} from '@discord-nestjs/core';
import { CommandHandler, DiscordCommandClass } from '../discord.decorator';
import { AutocompleteInteraction, EmbedBuilder } from 'discord.js';
import { reportException } from '@lib/sentry/reporting';

const DATA_FILE_URL =
'https://raw.githubusercontent.com/home-assistant/service-hub/main/data/discord_messages.yaml';

interface MessageData {
[key: string]: { description: string; content: string };
}

class MessageDto {
@Param({
name: 'message',
description: 'What message do you want to post?',
required: true,
autocomplete: true,
})
messageKey: string;
}

@DiscordCommandClass({
name: 'message',
description: 'Returns a predefined message',
})
@UsePipes(TransformPipe)
export class MessageCommand implements DiscordTransformedCommand<MessageDto> {
private messageData: MessageData;

async reloadMessageData(force?: boolean): Promise<void> {
if (force || !this.messageData) {
this.messageData = yaml.load(await (await fetch(DATA_FILE_URL)).text(), {
json: true,
}) as MessageData;
}
}
@CommandHandler()
async handler(
@Payload() handlerDto: MessageDto,
context: TransformedCommandExecutionContext,
): Promise<void> {
const { messageKey } = handlerDto;
const { interaction } = context;
if (messageKey === 'reload') {
await this.reloadMessageData(true);

await interaction.reply({
content: 'Message list reloaded',
ephemeral: true,
});
return;
}

if (!this.messageData[messageKey]) {
await interaction.reply({
content: 'Could not find information',
ephemeral: true,
});
return;
}

await this.reloadMessageData();

await interaction.reply({
embeds: [
new EmbedBuilder({
description: this.messageData[messageKey].content,
}),
],
});
}

// This is the autocomplete handler for the /message command
@On('interactionCreate')
async onInteractionCreate(interaction: AutocompleteInteraction): Promise<void> {
if (!interaction.isAutocomplete() || interaction.commandName !== 'message') {
return;
}
try {
await this.reloadMessageData();
const focusedValue = interaction.options.getFocused()?.toLowerCase();

await interaction.respond(
focusedValue.length !== 0
? Object.entries(this.messageData)
.map(([key, data]) => ({
name: data.description,
value: key,
}))
.filter(
(choice) =>
choice.value.toLowerCase().includes(focusedValue) ||
choice.name.toLowerCase().includes(focusedValue),
)
// The API only allow max 25 sugestions
.slice(0, 25)
: [],
);
} catch (err) {
reportException(err, {
cause: err,
data: {
interaction: interaction.toJSON(),
user: interaction.user.toJSON(),
channel: interaction.channel.toJSON(),
command: interaction.command.toJSON(),
},
});
await interaction.respond([]);
}
}
}
3 changes: 2 additions & 1 deletion services/bots/src/discord/discord.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { DiscordModule } from '@discord-nestjs/core';
import { PingCommand } from './commands/ping';
import { VersionsCommand } from './commands/versions';
import { IntegrationCommand } from './commands/integration';
import { MessageCommand } from './commands/message';

@Module({
imports: [DiscordModule.forFeature()],
providers: [PingCommand, VersionsCommand, IntegrationCommand],
providers: [PingCommand, VersionsCommand, IntegrationCommand, MessageCommand],
})
export class DiscordBotModule {}
9 changes: 9 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1475,6 +1475,13 @@ __metadata:
languageName: node
linkType: hard

"@types/js-yaml@npm:^4":
version: 4.0.5
resolution: "@types/js-yaml@npm:4.0.5"
checksum: 7dcac8c50fec31643cc9d6444b5503239a861414cdfaa7ae9a38bc22597c4d850c4b8cec3d82d73b3fbca408348ce223b0408d598b32e094470dfffc6d486b4d
languageName: node
linkType: hard

"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9":
version: 7.0.11
resolution: "@types/json-schema@npm:7.0.11"
Expand Down Expand Up @@ -6511,6 +6518,7 @@ __metadata:
"@octokit/webhooks-types": ^6.3.6
"@sentry/integrations": ^6.19.7
"@sentry/node": ^6.19.7
"@types/js-yaml": ^4
"@typescript-eslint/eslint-plugin": 5.21.0
"@typescript-eslint/parser": ^5.21.0
apollo-server-express: ^3.6.7
Expand All @@ -6523,6 +6531,7 @@ __metadata:
eslint-plugin-import: ^2.26.0
find-up: ^4.0.0
graphql: ^16.6.0
js-yaml: ^4.1.0
mocha: ^10.0.0
nestjs-pino: ^2.5.2
node-fetch: 2
Expand Down

0 comments on commit 9281eb9

Please sign in to comment.