Skip to content

Commit

Permalink
VoiceDiffの追加 (#20)
Browse files Browse the repository at this point in the history
* add: VoiceDiffを送信するチャンネルを指定する環境変数の追加

* change: CodeStylesの設定変更

* add: 継承の追加

* add: 継承のインポート

* change: Genericsの追加

* add: Embedのモデルを追加

* add: VoiceDiff機能の追加

* add: エンドポイントへのVoiceDiff実装

* Update src/server/index.ts

Co-authored-by: Mikuroさいな <ryosukadnak@gmail.com>

* fix: VoiceRoomResponseRunnerが関数の外で破棄されてしまっている問題の修正

* Fix with StandardOutput

* Remove log

* Update lock

* Remove .idea

* change: .idea/ディレクトリの除外

* add: VoiceDiffのテストを追加

* rename: EmbedMessage -> embed-message

* fix: 二重命名の修正

Co-authored-by: Mikuroさいな <ryosukadnak@gmail.com>
  • Loading branch information
meru and MikuroXina authored Feb 26, 2022
1 parent 20c154b commit 8cc0fe0
Show file tree
Hide file tree
Showing 22 changed files with 208 additions and 182 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
DISCORD_TOKEN=
MAIN_CHANNEL_ID=
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,6 @@ dist

# ts
build/

# WebStorm
.idea/
5 changes: 0 additions & 5 deletions .idea/.gitignore

This file was deleted.

83 changes: 0 additions & 83 deletions .idea/codeStyles/Project.xml

This file was deleted.

5 changes: 0 additions & 5 deletions .idea/codeStyles/codeStyleConfig.xml

This file was deleted.

7 changes: 0 additions & 7 deletions .idea/discord.xml

This file was deleted.

15 changes: 0 additions & 15 deletions .idea/git_toolbox_prj.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/inspectionProfiles/Project_Default.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/jsLibraryMappings.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/jsLinters/eslint.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

12 changes: 0 additions & 12 deletions .idea/oreorebot2.iml

This file was deleted.

7 changes: 0 additions & 7 deletions .idea/prettier.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

53 changes: 53 additions & 0 deletions src/adaptor/discord-output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Client, MessageEmbed } from 'discord.js';
import type { EmbedMessage } from '../model/embed-message';
import type { StandardOutput } from '../service/voice-diff';

export class DiscordOutput implements StandardOutput {
constructor(
private readonly client: Client,
private readonly channelId: string
) {}

async sendEmbed(embed: EmbedMessage): Promise<void> {
const channel = await this.client.channels.fetch(this.channelId);
if (!channel || !channel.isText()) {
throw new Error(`the channel (${this.channelId}) is not text channel`);
}

const made = buildEmbed(embed);
await channel.send({
embeds: [made]
});
}
}

function buildEmbed(embed: EmbedMessage) {
const makeEmbed = new MessageEmbed();
const { title, color, description, fields, url, footer, thumbnail, author } =
embed;
if (author) {
makeEmbed.setAuthor({ name: author.name, iconURL: author.iconUrl });
}
if (color) {
makeEmbed.setColor(color);
}
if (description) {
makeEmbed.setDescription(description);
}
if (fields) {
makeEmbed.setFields(fields);
}
if (footer) {
makeEmbed.setFooter({ text: footer });
}
if (title) {
makeEmbed.setTitle(title);
}
if (url) {
makeEmbed.setURL(url);
}
if (thumbnail) {
makeEmbed.setThumbnail(thumbnail.url);
}
return makeEmbed;
}
22 changes: 22 additions & 0 deletions src/adaptor/discord-participant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { VoiceChannelParticipant } from '../service/voice-diff';
import type { VoiceState } from 'discord.js';

export class DiscordParticipant implements VoiceChannelParticipant {
constructor(private voiceState: VoiceState) {}

get userName(): string {
return this.voiceState.member?.displayName ?? '名無し';
}

get userAvatar(): string {
const avatarURL = this.voiceState.member?.displayAvatarURL();
if (!avatarURL) {
throw new Error('アバターが取得できませんでした。');
}
return avatarURL;
}

get channelName(): string {
return this.voiceState.channel?.name ?? '名無し';
}
}
2 changes: 2 additions & 0 deletions src/adaptor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ export * from './mock-voice';
export * from './random';
export * from './transformer';
export * from './voice-room-proxy';
export * from './discord-participant';
export * from './discord-output';
23 changes: 13 additions & 10 deletions src/adaptor/voice-room-proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ type ObserveExpectation = 'ChangingIntoFalsy' | 'ChangingIntoTruthy' | 'All';
* @class VoiceRoomProxy
* @implements {VoiceRoomEventProvider<VoiceState>}
*/
export class VoiceRoomProxy implements VoiceRoomEventProvider<VoiceState> {
constructor(private readonly client: Client) {}
export class VoiceRoomProxy<V> implements VoiceRoomEventProvider<V> {
constructor(
private readonly client: Client,
private readonly map: (voiceState: VoiceState) => V
) {}

private registerHandler(
handler: (v: VoiceState) => Promise<void>,
handler: (v: V) => Promise<void>,
toObserve: keyof VoiceState,
expected: ObserveExpectation
): void {
Expand All @@ -28,32 +31,32 @@ export class VoiceRoomProxy implements VoiceRoomEventProvider<VoiceState> {
(expected === 'ChangingIntoTruthy' && !!newState[toObserve]) ||
expected === 'All')
) {
await handler(newState);
await handler(this.map(newState));
}
});
}

onJoin(handler: (voiceState: VoiceState) => Promise<void>): void {
onJoin(handler: (voiceState: V) => Promise<void>): void {
this.registerHandler(handler, 'channelId', 'ChangingIntoTruthy');
}

onLeave(handler: (voiceState: VoiceState) => Promise<void>): void {
onLeave(handler: (voiceState: V) => Promise<void>): void {
this.registerHandler(handler, 'channelId', 'ChangingIntoFalsy');
}

onMute(handler: (voiceState: VoiceState) => Promise<void>): void {
onMute(handler: (voiceState: V) => Promise<void>): void {
this.registerHandler(handler, 'mute', 'ChangingIntoTruthy');
}

onDeafen(handler: (voiceState: VoiceState) => Promise<void>): void {
onDeafen(handler: (voiceState: V) => Promise<void>): void {
this.registerHandler(handler, 'deaf', 'ChangingIntoTruthy');
}

onUnmute(handler: (voiceState: VoiceState) => Promise<void>): void {
onUnmute(handler: (voiceState: V) => Promise<void>): void {
this.registerHandler(handler, 'mute', 'ChangingIntoFalsy');
}

onUndeafen(handler: (voiceState: VoiceState) => Promise<void>): void {
onUndeafen(handler: (voiceState: V) => Promise<void>): void {
this.registerHandler(handler, 'deaf', 'ChangingIntoFalsy');
}
}
21 changes: 18 additions & 3 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
ActualClock,
DiscordOutput,
DiscordParticipant,
DiscordVoiceConnectionFactory,
InMemoryReservationRepository,
InMemoryTypoRepository,
Expand All @@ -9,14 +11,17 @@ import {
MathRandomGenerator,
MessageProxy,
MessageUpdateProxy,
DiscordVoiceRoomController
DiscordVoiceRoomController,
VoiceRoomProxy
} from '../adaptor';
import { Client, Intents, version } from 'discord.js';
import {
MessageResponseRunner,
MessageUpdateResponseRunner,
ScheduleRunner
ScheduleRunner,
VoiceRoomResponseRunner
} from '../runner';
import { VoiceChannelParticipant, VoiceDiff } from '../service/voice-diff';
import {
allCommandResponder,
allMessageEventResponder,
Expand All @@ -30,7 +35,8 @@ import { join } from 'path';

dotenv.config();
const token = process.env.DISCORD_TOKEN;
if (!token) {
const mainChannelId = process.env.MAIN_CHANNEL_ID;
if (!token || !mainChannelId) {
throw new Error(
'Error> Failed to start. You did not specify any environment variables.'
);
Expand Down Expand Up @@ -101,6 +107,15 @@ commandRunner.addResponder(
)
);

const provider = new VoiceRoomProxy<VoiceChannelParticipant>(
client,
(voiceState) => new DiscordParticipant(voiceState)
);
const voiceRunner = new VoiceRoomResponseRunner(provider);
voiceRunner.addResponder(
new VoiceDiff(new DiscordOutput(client, mainChannelId))
);

client.once('ready', () => {
readyLog(client);
});
Expand Down
Loading

0 comments on commit 8cc0fe0

Please sign in to comment.