# U.chat() と room オブジェクト

> ページスクリプトの入り口であるU.chat() と、イベントコールバックが受け取るroomオブジェクトの値・関数の一覧です。

ページスクリプトは `U.chat()` でチャットルームを選び、イベントコールバックの第1引数として `room` オブジェクトを受け取ります。このページは、その両方の正式な一覧です。イベント名と `data` は[イベント](/ja/doc/3.3)、チャンネル（`room.plugin`）は[チャンネルAPIと上限](/ja/doc/3.5)、スキンUI（`room.skin`）は[スキンUI API](/ja/doc/3.4)を参照してください。

## U.chat() {#u-chat}

| 呼び出し | 戻り値 |
| --- | --- |
| `U.chat('my-room')` — まだ設置されていないルーム | 登録器 `{ on, off }` |
| `U.chat('my-room')` — 設置済みのルーム | そのルームの `room` オブジェクト（`on`、`off` を含む） |
| `U.chat('*')` | すべてのルームに登録する登録器 `{ on, off }` |

どちらの場合も、`.on(名前, コールバック)` でイベントを登録できます。

```js
U.chat('my-room').on('after.join', function (room, data) {
	room.print(data.my.nick + 'さん、ようこそ。');
});
```

- `U` はuchat.jsが作ります。uchat.jsは `async` で読み込まれるため、それより前に呼ぶコードには事前登録コードが必要です。[非同期読み込みと複数のチャットルーム](/ja/doc/2.2)を参照してください。
- 入室確認（ボットチェック）画面が表示されている間は、`U.chat('my-room')` が `undefined` を返すことがあります。ページ読み込み直後に登録するコードは、事前登録コードの中に置いてください。

## on / off {#on-off}

| 関数 | 引数 | 説明 |
| --- | --- | --- |
| `on(name, fn)` | イベント名（`名前#タグ` も可）、`fn(room, data)` | コールバックを登録します。`after.create` は、すでに準備できたルームならすぐに1回呼びます |
| `off(name)` | `'名前'`、`'#タグ'`、`'名前#タグ'` | 一致する登録を削除します |

| `off` の引数 | 削除するもの |
| --- | --- |
| `'after.message'` | そのイベントのすべての登録（タグの有無にかかわらず） |
| `'#stats'` | タグが `stats` のすべての登録 |
| `'after.message#stats'` | その名前で登録したものだけ（完全一致） |

- `U.chat('*').off(...)` は、`U.chat('my-room')` や `room.on` でルームごとに登録したものまで削除します。ほかのスクリプトの登録を消さないよう、固有のタグを使ってください。
- `U.chat('my-room').off(...)` と `room.off(...)` は、そのルームに登録したものだけを削除します。`'*'` の登録は残ります。
- `off()` を引数なしで呼ばないでください。削除する登録があるとエラーになります。
- 同じイベントのコールバックは、登録した順に呼ばれます。コールバック内の例外はコンソールに記録され、次のコールバックは引き続き呼ばれます。

## roomの値 {#properties}

| 名前 | 型 | 説明 |
| --- | --- | --- |
| `room.id` | 文字列 | チャットルームID |
| `room.my` | [ユーザーオブジェクト](#user-object) | 自分の情報。入室（`after.join`）前は空のオブジェクト |
| `room.info` | オブジェクト | チャットルーム情報。入室前は空のオブジェクト。下の [room.info](#room-info) |
| `room.user` | `{ list, get }` | 接続者。下の [room.user](#room-user) |
| `room.setting` | `{ get, set, save, data }` | このブラウザに保存されるユーザー設定。下の [room.setting](#room-setting) |
| `room.plugin` | オブジェクト | チャンネル。[チャンネルAPIと上限](/ja/doc/3.5) |
| `room.action` | オブジェクト | 送信・コマンド。下の [room.action](#room-action) |
| `room.skin` | オブジェクト | スキンUI API。[スキンUI API](/ja/doc/3.4) |
| `room.skin.arguments` | オブジェクト | 管理ページのスキン設定に `skin_arguments` 属性をマージした値 |
| `room.agent` | `{ userAgent, charset, mobile, android, ios, webkit }` | ブラウザ情報。`userAgent` は小文字、`webkit` はバージョン番号または `false` |
| `room.language` | `{ system, error }` | 現在の言語の案内・エラー文言。エラー文言は `room.language.error[コード]` |
| `room.locale` | 文字列 | 決定した画面言語コード（`ko`、`en`、`ja`）。言語パックを受け取る前は空文字列 |

## ユーザーオブジェクト {#user-object}

`room.my`、`room.user.get()`、イベントの `data.user` などは同じ形です。

| キー | 型 | 説明 |
| --- | --- | --- |
| `nick` | 文字列 | ニックネーム |
| `id` | 文字列 | 会員ID（会員連携）。ない場合は空 |
| `level` | 数値/文字列 | レベル（会員連携） |
| `auth` | 数値 | `0` ゲスト、`1` 会員、`2` モデレーター、`3` 管理者、`4` サーバー（REST APIからの送信・チャンネルの保存値。このとき `nick` などは空） |
| `icons` | 文字列 | アイコンURLのリスト（会員連携の `icons` の値） |
| `nickcon` | 文字列 | ニックネームの代わりに表示する画像のURL |
| `connected` | 文字列 | 入室時刻 `'YYYY-MM-DD HH:MM:SS'`（閲覧者のタイムゾーン） |
| `time` | 数値 | 入室時刻（Unix秒） |
| `mute` | `0`/`1` | ミュート中なら `1` |
| `session` | 文字列 | セッション識別値（16進数）。無視・権限付与の基準 |
| `profileimg` | 文字列 | プロフィール画像のURL（ある場合のみ） |

## room.info {#room-info}

| キー | 説明 |
| --- | --- |
| `id`、`name` | チャットルームID、名前 |
| `mode` | `0` 通常、`1` 個人チャンネル、`4` チャンネルチャットルーム |
| `created` | 開設時刻 `'YYYY-MM-DD HH:MM:SS'` |
| `frozen` | 入室時に凍結状態だったら `1`。凍結・凍結解除をしても変わらないため、`system` イベント（`frozen`、`unfrozen`）で確認します |
| `whisper`、`call`、`individual`、`font` | ウィスパー・呼び出し・個人チャンネル・フォント装飾の使用有無（`0`/`1`） |
| `userLinkage` | 会員連携をオンにしていれば `1` |
| `slowSeconds` | スローモードの間隔（秒）。オフなら `0` |

チャットルームの設定が変わると、変わったキーだけが `room.info` にマージされ、`update` イベントが届きます。

## room.user {#room-user}

| 名前 | 説明 |
| --- | --- |
| `room.user.get(nick)` | ニックネームでユーザーオブジェクトを探します。ない場合は `undefined` |
| `room.user.list` | 現在の接続者一覧。配列ではなくオブジェクトで、キーは `escape(ニックネーム)` です |

```js
var user = room.user.get('홍길동');
if (user && user.auth >= 2) room.print('管理者です。');
```

- ニックネームで探すときは `user.get` を使ってください。`user.list` のキーは `escape()` でエンコードされているため、ハングルのニックネームをそのまま入れても見つかりません。
- `user.get` は、メッセージで見かけた人のように、いま接続していないユーザーも返すことがあります。接続しているかどうかは `user.list` で確認します。
- `user.list` は、入室・退室の通知（`user.join`、`user.quit`）を受け取ったときだけ変わります。基本スキンでユーザー一覧を開いているルームや、接続者が100人以上のルームではこの通知が届かないため、`user.list` が入室時の状態のまま止まっていることがあります。→ [イベント](/ja/doc/3.3#users)

## roomの関数 {#functions}

| 関数 | 戻り値 | 説明 |
| --- | --- | --- |
| `room.print(html)` | — | 自分の画面にだけ案内行をHTMLで表示します。スクリプトを実行できる要素だけが取り除かれるため、ユーザー入力を入れるときは自分でエスケープしてください。`system` イベント（`type: 'notice'`）も発生します |
| `room.on(name, fn)` | `room` | このルームにだけイベントを登録します。[on / off](#on-off) と同じです |
| `room.off(name)` | — | このルームの登録を解除します |
| `room.now()` | 数値 | サーバー時計基準の現在時刻（ミリ秒、秒単位に丸められる） |
| `room.getTimeStamp([sec])` | 文字列 | Unix秒を `'YYYY-MM-DD HH:MM:SS'`（閲覧者のタイムゾーン）に変換します。省略すると現在のサーバー時刻 |
| `room.reload()` | — | チャットルームを削除し、同じ場所に設置し直します。このルームに登録したイベント（`U.chat('my-room')`、`room.on`）も削除されるため、登録し直す必要があります。`'*'` の登録は残ります |
| `room.disconnect()` | — | 接続を切ります。ネットワークエラーで切れたのと同じように扱われ、自動的に再接続します |

## room.action {#room-action}

| 関数 | 戻り値 | 説明 |
| --- | --- | --- |
| `send(message, style)` | `true`/`false` | メッセージを送ります。`style` は `{ bold, italic, underline, color }`（すべて任意） |
| `slowRemaining()` | ミリ秒 | スローモードで次に送信できるまでの残り時間。待つ必要がなければ `0` |
| `command(type, ...args)` | `before.command` でキャンセルされると `false`、それ以外はなし | コマンドを実行します。下の[コマンド](#commands) |
| `plugin(type, args)` | `true`/`false` | チャット欄に `!type 引数` と入力したのと同じように、そのチャンネルの `addParser` コールバックを呼びます。詳しい動作は[チャンネルAPIと上限](/ja/doc/3.5#parser) |

```js
room.action.send('こんにちは');
room.action.send('重要!', { bold: true, color: '#e11d48' });
```

- `send` は、接続していない、内容が空、スローモードで待つ必要がある、`before.send` でブロックされた、のいずれかの場合に `false` を返します。`true` はサーバーに送ったという意味で、サーバーが拒否すると `error` イベントが届きます。
- `color` には `#rgb`、`#rrggbb`、`rgb(r, g, b)`、色名を指定できます。
- 管理者・モデレーターでなければ、送信後にスローモードの待機が始まります。

## コマンド {#commands}

`room.action.command(type, ...args)` の `type` は、大文字・小文字と `_` を無視します（`un_ignore` → `unignore`）。接続前は何もしません。権限がない場合や引数が誤っている場合は `error` イベントが届きます。

よく使うコマンド:

| コマンド | 引数 | 権限 | 説明 |
| --- | --- | --- | --- |
| `whisper` | ニックネーム、内容 | — | ウィスパー |
| `call` | ニックネーム | — | 呼び出し |
| `ignore`、`unignore` | ニックネーム | — | 無視・解除（このブラウザに保存） |
| `report` | ニックネーム、理由 | — | 通報 |
| `changeinfo` | `{ nick: '新しいニックネーム' }` | — | ニックネームの変更 |
| `password` | パスワード | — | 入室パスワードを入れて再入室 |
| `chatlist` | 件数（デフォルト15、最大25） | — | 過去の会話と、自分に関係するウィスパー・呼び出し・招待を再取得 |
| `noticelist` | — | — | チャットルームのお知らせを再取得（`system` イベント `notice` で届く） |
| `individual` | — | — | 自分の個人チャンネルを新しいウィンドウで開く |
| `invite` | ニックネーム | — | その人を自分の個人チャンネルに招待。個人チャンネルのウィンドウがなければ先に開きます |
| `popup` | — | — | このチャットルームを新しいウィンドウ（400×600）で開く |
| `io` | `true`/`false` | — | 入室・退室通知の受信をオン・オフ。オフにすると接続者数（`user.count`）だけを受け取ります |
| `login` | 管理者パスワード | — | 管理者になる。会員連携のルームでは使えません |
| `info` | ニックネーム | モデレーター（自分自身については誰でも） | ユーザー情報 |
| `notice` | 内容 | モデレーター | お知らせ |
| `mute` | ニックネーム、分、理由 | モデレーター | ミュート。最大30日（43200分） |
| `unmute` | ニックネーム | モデレーター | ミュート解除 |
| `ban` | ニックネーム、理由、期間（秒） | モデレーター | BAN。期間を空にするか0にすると永久 |
| `ip` | ニックネーム | モデレーター | IPの確認 |
| `freeze`、`unfreeze` | — | モデレーター | チャットルームの凍結・凍結解除 |
| `clearlog` | — | モデレーター | 会話の消去（権限がなければ自分の画面だけ） |
| `op`、`deop` | ニックネーム | 管理者 | モデレーターの指定・解除 |
| `logout` | — | 管理者 | 管理者権限を手放す |
| `adminpage` | — | 管理者 | 管理ページを新しいウィンドウで開く |
| `upload` | コールバック | — | レガシースキン専用。アップロード画面を開き、結果を `コールバック(json)` で受け取ります |

```js
room.action.command('whisper', '홍길동', '少しお話しできますか?');
room.action.command('changeinfo', { nick: '新ニック' });
```

権限チェックはサーバーが改めて行います。画面でボタンを隠すだけでは権限を制限できず、逆に権限のないコマンドは送っても拒否されます。

## room.setting {#room-setting}

このブラウザにだけ保存されるユーザー設定です（localStorage）。基本スキンの設定と同じストレージを使うため、自分で作るキーには接頭辞を付けてください。

| 関数 | 説明 |
| --- | --- |
| `room.setting.get(key)` | 値を読む |
| `room.setting.set(key, value)` | 値を書き込み、すぐに保存 |
| `room.setting.save()` | 現在の値を保存 |
| `room.setting.data` | 設定オブジェクトそのもの |

```js
room.setting.set('myScript.muted', true);
room.setting.get('myScript.muted'); // true
```

ストレージを使えないブラウザ（プライベートブラウジングなど）では、再読み込みすると値が消えることがあります。
