現在ドキュメントは制作段階にあるため、多くの情報が不完全なものになっています

報告は Discord までお願いします

チャット

概要

@omujs/chat
を使うと、YouTubeなどの配信サイトから取得したチャット、投稿者、チャンネル、配信枠などの情報を利用できます。

チャットの各データはテーブル として提供されます。過去のデータを取得できるほか、追加や更新をイベントとして受け取ることもできます。

セットアップ

Chat.create(omu)
でチャットAPIを作成します。

チャットAPIは必要なセッションと権限を登録するため、必ず

omu.start()
より前に作成してください。

1
import { Chat, ChatEvents, Models } from '@omujs/chat';
2
import { Omu } from '@omujs/omu';
3
import { APP } from './app';
4

5
const omu = new Omu(APP);
6
const chat = Chat.create(omu);
7

8
const unlistenMessage = chat.on(ChatEvents.Message.Add, (message) => {
9
    console.log(message.text);
10
});
11

12
omu.start();
13

14
// 画面を閉じるときなど、購読が不要になったら解除します
15
function destroy() {
16
    unlistenMessage();
17
}

チャットを受け取る

chat.on(event, handler)
でチャットデータの追加、更新、削除を受け取ります。戻り値の関数を呼び出すと、登録したハンドラーを解除できます。

chat.on()
が対象テーブルの購読も開始するため、Batchイベントを含めて
table.listen()
を別途呼ぶ必要はありません。

1
const unlisten = chat.on(ChatEvents.Message.Add, async (message) => {
2
    const author = message.authorId
3
        ? await chat.authors.get(message.authorId.key())
4
        : undefined;
5

6
    console.log(`${author?.name ?? '不明'}: ${message.text}`);
7
});
8

9
// 購読が不要になった時点で呼び出します
10
function destroy() {
11
    unlisten();
12
}

イベントはデータの種類ごとに用意されています。

データイベント
メッセージ
ChatEvents.Message
投稿者
ChatEvents.Author
チャンネル
ChatEvents.Channel
プロバイダー
ChatEvents.Provider
配信枠
ChatEvents.Room
投票
ChatEvents.Vote

それぞれのイベントから、次の変更を監視できます。

イベント内容ハンドラーの引数
Add
データが追加された追加されたデータ
Update
データが更新された更新されたデータ
Remove
データが削除された削除されたデータ
AddBatch
複数のデータが追加された
Map<string, T>
UpdateBatch
複数のデータが更新された
Map<string, T>
RemoveBatch
複数のデータが削除された
Map<string, T>
Clear
テーブルが空になったなし
1
chat.on(ChatEvents.Room.Update, (room) => {
2
    console.log(room.metadata.title, room.status);
3
});
4

5
const unlistenMessages = chat.on(ChatEvents.Message.AddBatch, (messages) => {
6
    for (const message of messages.values()) {
7
        console.log(message.text);
8
    }
9
});
10

11
// 画面を閉じるときなど、購読が不要になったら解除します
12
function destroy() {
13
    unlistenMessages();
14
}

過去のメッセージを取得する

chat.messages
は通常のテーブルとして操作できます。

最新のメッセージを取得するには、

fetchItems()
に
backward: true
を指定します。戻り値は、メッセージIDをキーとする
Map
です。

1
const result = await chat.messages.fetchItems({
2
    limit: 50,
3
    backward: true,
4
});
5

6
const messages = [...result.values()].sort(
7
    (a, b) => a.createdAt.getTime() - b.createdAt.getTime(),
8
);

リアルタイムのイベントだけでは接続前のメッセージを取得できません。画面の初期表示では、イベントを先に登録してから

fetchItems()
で履歴を読み込みます。IDをキーにした
Map
へ保存すると、履歴の取得中に届いたメッセージも重複せず保持できます。

1
const messages = new Map<string, Models.Message>();
2

3
chat.on(ChatEvents.Message.Add, (message) => {
4
    messages.set(message.id.key(), message);
5
});
6

7
omu.onReady(async () => {
8
    const history = await chat.messages.fetchItems({
9
        limit: 50,
10
        backward: true,
11
    });
12

13
    for (const [id, message] of history) {
14
        if (!messages.has(id)) {
15
            messages.set(id, message);
16
        }
17
    }
18
});

メッセージ

メッセージは

Models.Message
として取得できます。

プロパティ型内容
id
Identifier
メッセージの識別子
roomId
Identifier
投稿された配信枠
authorId
Identifier | undefined
投稿者の識別子
createdAt
Date
投稿日時
content
Component | undefined
装飾を含むメッセージ内容
text
string
content
から文字列だけを取り出した内容
paid
Paid | undefined
通貨と金額
gifts
Gift[] | undefined
ギフト
deleted
boolean | undefined
削除済みかどうか

message.content
には、テキストだけでなく画像、リンク、アセットなどが含まれる場合があります。文字列だけが必要な場合は
message.text
を使います。

削除済みのメッセージを表示しない場合は、

deleted
を確認してください。

1
const visibleMessages = [...messages.values()]
2
    .filter((message) => !message.deleted);

投稿者を取得する

メッセージには投稿者のIDが保存されています。名前やアイコンが必要な場合は

chat.authors
から取得します。

1
if (message.authorId) {
2
    const author = await chat.authors.get(message.authorId.key());
3

4
    console.log(author?.name);
5
    console.log(author?.avatarUrl);
6
    console.log(author?.roles);
7
}

複数の投稿者をまとめて取得する場合は

getMany()
を使います。

1
const authorIds = [...messages.values()]
2
    .flatMap((message) => message.authorId ? [message.authorId.key()] : []);
3

4
const authors = await chat.authors.getMany(...authorIds);

利用できるテーブル

Chat
は次のテーブルを提供します。取得や監視、キャッシュなどの詳しい操作方法はテーブル を参照してください。

プロパティデータ内容
chat.messages
Models.Message
チャットメッセージ
chat.authors
Models.Author
投稿者
chat.channels
Models.Channel
接続対象のチャンネル
chat.providers
Models.Provider
YouTubeなどのチャットプロバイダー
chat.rooms
Models.Room
配信枠と接続状態
chat.votes
Models.Vote
配信内の投票

チャンネルを追加する

createChannelTree(url)
でURLに対応するチャンネルを検索し、追加候補を取得できます。実際に接続対象へ追加するには、取得したチャンネルを
chat.channels
へ追加します。

1
const channels = await chat.createChannelTree(
2
    'https://www.youtube.com/@example',
3
);
4

5
if (channels.length > 0) {
6
    await chat.channels.add(...channels);
7
}

追加済みか確認する場合は、チャンネルの識別子を使います。

1
for (const channel of channels) {
2
    const added = await chat.channels.has(channel.id.key());
3
    console.log(channel.name, added);
4
}

リアクション

リアクションは

chat.reactionSignal
から送受信できます。

1
import { Models } from '@omujs/chat';
2

3
chat.reactionSignal.listen((reaction) => {
4
    console.log(reaction.roomId, reaction.reactions);
5
});
6

7
await chat.reactionSignal.notify(new Models.Reaction({
8
    roomId,
9
    reactions: {
10
        '👍': 1,
11
    },
12
}));