Skip to content

Commit

Permalink
feat: feedback and dismissable alert decorators
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyko committed May 22, 2024
1 parent fac8d43 commit c8d3f6f
Show file tree
Hide file tree
Showing 30 changed files with 739 additions and 425 deletions.
35 changes: 18 additions & 17 deletions .github/workflows/cd_commands.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
name: Continuous Deployment (commands)

# todo: move this to a kube pre-deploy step
on:
push:
branches: [main]
paths:
- 'commands.lock.json'
- '.github/workflows/cd_commands.yml'
workflow_dispatch:
# push:
# branches: [main]
# paths:
# - 'commands.lock.json'
# - '.github/workflows/cd_commands.yml'
workflow_dispatch:

jobs:
deploy:
name: Deploy Updated Global Commands
runs-on: ubuntu-latest
deploy:
name: Deploy Updated Global Commands
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
steps:
- uses: actions/checkout@v3

- name: PUT Global Commands
run: |
curl -X PUT https://discord.com/api/v10/applications/${{ secrets.DISCORD_APPLICATION_ID }}/commands \
-H "Authorization: Bot ${{ secrets.DISCORD_TOKEN }}" \
-H "Content-Type: application/json" \
-d @./commands.lock.json | jq
- name: PUT Global Commands
run: |
curl -X PUT https://discord.com/api/v10/applications/${{ secrets.DISCORD_APPLICATION_ID }}/commands \
-H "Authorization: Bot ${{ secrets.DISCORD_TOKEN }}" \
-H "Content-Type: application/json" \
-d @./commands.lock.json | jq
8 changes: 2 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@

Help us translate Thoth in the top 30 languages over at our [Crowdin Project](https://crowdin.com/project/thoth)

## Terms of Service
## Self Hosting

Moved to [TERMS_OF_SERVICE.md](./legal/TERMS_OF_SERVICE.md)

## Privacy Policy

Moved to [PRIVACY_POLICY.md](./legal/PRIVACY_POLICY.md)
Self hosting is currently unsupported.
34 changes: 7 additions & 27 deletions apps/bot/src/commands/general/adjective.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,31 @@ import { Command } from '@yuudachi/framework';
import type { ArgsParam, InteractionParam, LocaleParam } from '@yuudachi/framework/types';
import i18n from 'i18next';
import { inject, injectable } from 'tsyringe';
import { BlockedUserModule, BlockedWordModule, ShowByDefaultAlerterModule } from '#structures';
import { BlockedUserModule, BlockedWordModule, DismissableAlertModule } from '#structures';
import { parseLimit } from '#util/args.js';
import { DatamuseQuery, fetchDatamuse } from '#util/datamuse.js';
import { CommandError } from '#util/error.js';
import { firstUpperCase, pickRandom, trimArray } from '#util/index.js';
import { firstUpperCase, trimArray } from '#util/index.js';
import { UseModeration } from '../../hooks/contentModeration.js';
import { UseFeedbackAlert } from '../../hooks/dismissableAlert.js';

@injectable()
export default class<Cmd extends typeof AdjectiveCommand> extends Command<Cmd> {
public constructor(
@inject(BlockedWordModule) public readonly blockedWord: BlockedWordModule,
@inject(BlockedUserModule) public readonly blockedUser: BlockedUserModule,
@inject(ShowByDefaultAlerterModule) public readonly showByDefaultAlerter: ShowByDefaultAlerterModule,
@inject(DismissableAlertModule) public readonly dismissableAlertService: DismissableAlertModule,
) {
super();
}

private async moderation(interaction: InteractionParam, args: ArgsParam<Cmd>, lng: LocaleParam): Promise<void> {
if (this.blockedWord.check(args.word)) {
throw new CommandError(
pickRandom(i18n.t('common.errors.blocked_word', { lng, returnObjects: true }) as string[]),
);
}

const ban = this.blockedUser.check(interaction.user.id);
if (ban) {
throw new CommandError(i18n.t('common.errors.banned', { lng, reason: ban }));
}
}

@UseModeration<Cmd>()
@UseFeedbackAlert()
public override async chatInput(
interaction: InteractionParam,
args: ArgsParam<Cmd>,
lng: LocaleParam,
): Promise<void> {
await this.moderation(interaction, args, lng);

await interaction.deferReply({ ephemeral: args.hide ?? false });

const limit = parseLimit(args.limit, lng);
Expand All @@ -55,14 +44,5 @@ export default class<Cmd extends typeof AdjectiveCommand> extends Command<Cmd> {
lng,
}),
);

if (!(await this.showByDefaultAlerter.beenAlerted(interaction.user.id))) {
await this.showByDefaultAlerter.add(interaction.user.id);
await interaction.followUp({
content:
'As of <t:1714509120:D>, various Thoth commands will no longer automatically hide their response. Set the `hide` option to `True` to hide command responses from other users.',
ephemeral: true,
});
}
}
}
29 changes: 9 additions & 20 deletions apps/bot/src/commands/general/close-rhyme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import { Command } from '@yuudachi/framework';
import type { ArgsParam, InteractionParam, LocaleParam } from '@yuudachi/framework/types';
import i18n from 'i18next';
import { inject, injectable } from 'tsyringe';
import { BlockedUserModule, BlockedWordModule, ShowByDefaultAlerterModule } from '#structures';
import { BlockedUserModule, BlockedWordModule, DismissableAlertModule } from '#structures';
import { parseLimit } from '#util/args.js';
import { DatamuseQuery, fetchDatamuse } from '#util/datamuse.js';
import { CommandError } from '#util/error.js';
import { firstUpperCase, pickRandom, trimArray } from '#util/index.js';
import { firstUpperCase, trimArray } from '#util/index.js';
import { UseModeration } from '../../hooks/contentModeration.js';
import { UseFeedbackAlert } from '../../hooks/dismissableAlert.js';

@injectable()
export default class<Cmd extends typeof CloseRhymeCommand> extends Command<Cmd> {
Expand All @@ -16,31 +18,18 @@ export default class<Cmd extends typeof CloseRhymeCommand> extends Command<Cmd>
public constructor(
@inject(BlockedWordModule) public readonly blockedWord: BlockedWordModule,
@inject(BlockedUserModule) public readonly blockedUser: BlockedUserModule,
@inject(ShowByDefaultAlerterModule) public readonly showByDefaultAlerter: ShowByDefaultAlerterModule,
@inject(DismissableAlertModule) public readonly dismissableAlertService: DismissableAlertModule,
) {
super();
}

private async moderation(interaction: InteractionParam, args: ArgsParam<Cmd>, lng: LocaleParam): Promise<void> {
if (this.blockedWord.check(args.word)) {
throw new CommandError(
pickRandom(i18n.t('common.errors.blocked_word', { lng, returnObjects: true }) as string[]),
);
}

const ban = this.blockedUser.check(interaction.user.id);
if (ban) {
throw new CommandError(i18n.t('common.errors.banned', { lng, reason: ban }));
}
}

@UseModeration<Cmd>()
@UseFeedbackAlert()
public override async chatInput(
interaction: InteractionParam,
args: ArgsParam<Cmd>,
lng: LocaleParam,
): Promise<void> {
await this.moderation(interaction, args, lng);

await interaction.deferReply({ ephemeral: args.hide ?? false });

const limit = parseLimit(args.limit, lng);
Expand All @@ -60,8 +49,8 @@ export default class<Cmd extends typeof CloseRhymeCommand> extends Command<Cmd>
.slice(0, 2_000),
);

if (!(await this.showByDefaultAlerter.beenAlerted(interaction.user.id))) {
await this.showByDefaultAlerter.add(interaction.user.id);
if (!(await this.dismissableAlertService.beenAlerted(interaction.user.id, 'show_by_default_alert'))) {
await this.dismissableAlertService.add(interaction.user.id, 'show_by_default_alert');
await interaction.followUp({
content:
'As of <t:1714509120:D>, various Thoth commands will no longer automatically hide their response. Set the `hide` option to `True` to hide command responses from other users.',
Expand Down
36 changes: 8 additions & 28 deletions apps/bot/src/commands/general/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,37 @@ import type { ArgsParam, InteractionParam, LocaleParam } from '@yuudachi/framewo
import { stripIndents } from 'common-tags';
import { ButtonStyle } from 'discord-api-types/v10';
import { AttachmentBuilder, ComponentType } from 'discord.js';
import i18n, { t } from 'i18next';
import { t } from 'i18next';
import type { Entry, Sense, Senses, VerbalIllustration } from 'mw-collegiate';
import { inject, injectable } from 'tsyringe';
import { logger } from '#logger';
import { createPronunciationURL, fetchDefinition } from '#mw';
import { formatText } from '#mw/format.js';
import { BlockedUserModule, BlockedWordModule, RedisManager, ShowByDefaultAlerterModule } from '#structures';
import { BlockedUserModule, BlockedWordModule, RedisManager, DismissableAlertModule } from '#structures';
import { Characters, Emojis } from '#util/constants.js';
import { CommandError } from '#util/error.js';
import { kRedis, pickRandom, trimArray } from '#util/index.js';
import { kRedis, trimArray } from '#util/index.js';
import { UseModeration } from '../../hooks/contentModeration.js';
import { UseFeedbackAlert } from '../../hooks/dismissableAlert.js';

@injectable()
export default class<Cmd extends typeof DefinitionCommand> extends Command<Cmd> {
public constructor(
@inject(kRedis) public readonly redis: RedisManager,
@inject(BlockedWordModule) public readonly blockedWord: BlockedWordModule,
@inject(BlockedUserModule) public readonly blockedUser: BlockedUserModule,
@inject(ShowByDefaultAlerterModule) public readonly showByDefaultAlerter: ShowByDefaultAlerterModule,
@inject(DismissableAlertModule) public readonly dismissableAlertService: DismissableAlertModule,
) {
super();
}

private async moderation(interaction: InteractionParam, args: ArgsParam<Cmd>, lng: LocaleParam): Promise<void> {
if (this.blockedWord.check(args.word)) {
throw new CommandError(
pickRandom(i18n.t('common.errors.blocked_word', { lng, returnObjects: true }) as string[]),
);
}

const ban = this.blockedUser.check(interaction.user.id);
if (ban) {
throw new CommandError(i18n.t('common.errors.banned', { lng, reason: ban }));
}
}

@UseModeration<Cmd>()
@UseFeedbackAlert()
public override async chatInput(
interaction: InteractionParam,
args: ArgsParam<Cmd>,
lng: LocaleParam,
): Promise<void> {
await this.moderation(interaction, args, lng);

const reply = await interaction.deferReply({
ephemeral: args.hide ?? false,
});
Expand Down Expand Up @@ -194,14 +183,5 @@ export default class<Cmd extends typeof DefinitionCommand> extends Command<Cmd>
files: soundAttachment ? [soundAttachment] : [],
components: [],
});

if (!(await this.showByDefaultAlerter.beenAlerted(interaction.user.id))) {
await this.showByDefaultAlerter.add(interaction.user.id);
await interaction.followUp({
content:
'As of <t:1714509120:D>, various Thoth commands will no longer automatically hide their response. Set the `hide` option to `True` to hide command responses from other users.',
ephemeral: true,
});
}
}
}
34 changes: 7 additions & 27 deletions apps/bot/src/commands/general/holonyms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,31 @@ import { Command } from '@yuudachi/framework';
import type { ArgsParam, InteractionParam, LocaleParam } from '@yuudachi/framework/types';
import i18n from 'i18next';
import { inject, injectable } from 'tsyringe';
import { BlockedUserModule, BlockedWordModule, ShowByDefaultAlerterModule } from '#structures';
import { BlockedUserModule, BlockedWordModule, DismissableAlertModule } from '#structures';
import { parseLimit } from '#util/args.js';
import { DatamuseQuery, fetchDatamuse } from '#util/datamuse.js';
import { CommandError } from '#util/error.js';
import { firstUpperCase, pickRandom, trimArray } from '#util/index.js';
import { firstUpperCase, trimArray } from '#util/index.js';
import { UseModeration } from '../../hooks/contentModeration.js';
import { UseFeedbackAlert } from '../../hooks/dismissableAlert.js';

@injectable()
export default class<Cmd extends typeof HolonymsCommand> extends Command<Cmd> {
public constructor(
@inject(BlockedWordModule) public readonly blockedWord: BlockedWordModule,
@inject(BlockedUserModule) public readonly blockedUser: BlockedUserModule,
@inject(ShowByDefaultAlerterModule) public readonly showByDefaultAlerter: ShowByDefaultAlerterModule,
@inject(DismissableAlertModule) public readonly dismissableAlertService: DismissableAlertModule,
) {
super();
}

private async moderation(interaction: InteractionParam, args: ArgsParam<Cmd>, lng: LocaleParam): Promise<void> {
if (this.blockedWord.check(args.word)) {
throw new CommandError(
pickRandom(i18n.t('common.errors.blocked_word', { lng, returnObjects: true }) as string[]),
);
}

const ban = this.blockedUser.check(interaction.user.id);
if (ban) {
throw new CommandError(i18n.t('common.errors.banned', { lng, reason: ban }));
}
}

@UseModeration<Cmd>()
@UseFeedbackAlert()
public override async chatInput(
interaction: InteractionParam,
args: ArgsParam<Cmd>,
lng: LocaleParam,
): Promise<void> {
await this.moderation(interaction, args, lng);

await interaction.deferReply({ ephemeral: args.hide ?? false });

const limit = parseLimit(args.limit, lng);
Expand All @@ -55,14 +44,5 @@ export default class<Cmd extends typeof HolonymsCommand> extends Command<Cmd> {
lng,
}),
);

if (!(await this.showByDefaultAlerter.beenAlerted(interaction.user.id))) {
await this.showByDefaultAlerter.add(interaction.user.id);
await interaction.followUp({
content:
'As of <t:1714509120:D>, various Thoth commands will no longer hide their response. To hide the response from other users as previous, set the `hide` option to `True`.',
ephemeral: true,
});
}
}
}
34 changes: 7 additions & 27 deletions apps/bot/src/commands/general/homophones.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,31 @@ import { Command } from '@yuudachi/framework';
import type { ArgsParam, InteractionParam, LocaleParam } from '@yuudachi/framework/types';
import i18n from 'i18next';
import { inject, injectable } from 'tsyringe';
import { BlockedUserModule, BlockedWordModule, ShowByDefaultAlerterModule } from '#structures';
import { BlockedUserModule, BlockedWordModule, DismissableAlertModule } from '#structures';
import { parseLimit } from '#util/args.js';
import { DatamuseQuery, fetchDatamuse } from '#util/datamuse.js';
import { CommandError } from '#util/error.js';
import { firstUpperCase, pickRandom, trimArray } from '#util/index.js';
import { firstUpperCase, trimArray } from '#util/index.js';
import { UseModeration } from '../../hooks/contentModeration.js';
import { UseFeedbackAlert } from '../../hooks/dismissableAlert.js';

@injectable()
export default class<Cmd extends typeof HomophonesCommand> extends Command<Cmd> {
public constructor(
@inject(BlockedWordModule) public readonly blockedWord: BlockedWordModule,
@inject(BlockedUserModule) public readonly blockedUser: BlockedUserModule,
@inject(ShowByDefaultAlerterModule) public readonly showByDefaultAlerter: ShowByDefaultAlerterModule,
@inject(DismissableAlertModule) public readonly dismissableAlertService: DismissableAlertModule,
) {
super();
}

private async moderation(interaction: InteractionParam, args: ArgsParam<Cmd>, lng: LocaleParam): Promise<void> {
if (this.blockedWord.check(args.word)) {
throw new CommandError(
pickRandom(i18n.t('common.errors.blocked_word', { lng, returnObjects: true }) as string[]),
);
}

const ban = this.blockedUser.check(interaction.user.id);
if (ban) {
throw new CommandError(i18n.t('common.errors.banned', { lng, reason: ban }));
}
}

@UseModeration<Cmd>()
@UseFeedbackAlert()
public override async chatInput(
interaction: InteractionParam,
args: ArgsParam<Cmd>,
lng: LocaleParam,
): Promise<void> {
await this.moderation(interaction, args, lng);

await interaction.deferReply({ ephemeral: args.hide ?? false });

const limit = parseLimit(args.limit, lng);
Expand All @@ -55,14 +44,5 @@ export default class<Cmd extends typeof HomophonesCommand> extends Command<Cmd>
lng,
}),
);

if (!(await this.showByDefaultAlerter.beenAlerted(interaction.user.id))) {
await this.showByDefaultAlerter.add(interaction.user.id);
await interaction.followUp({
content:
'As of <t:1714509120:D>, various Thoth commands will no longer automatically hide their response. Set the `hide` option to `True` to hide command responses from other users.',
ephemeral: true,
});
}
}
}

0 comments on commit c8d3f6f

Please sign in to comment.