Discordの通知を棒読みちゃんに読み上げてもらおう!~Discord.Netを添えて~
この記事はSLP KBIT Advent Calendar 2017 - Adventarの19日目の記事となります。
いい感じの導入
生粋のゲーマーである私は、「壁を隔てたお友達」と遊ぶ時に
Discordというナウいゲーマーに熱いアプリを公開当初から通話に使っています。
そこで通話するとき、聞き専(「リビングゲーマー」、「ママが怖い」等の理由で、
ボイスチャットに声で参加できない人)のチャットを見るために、
ゲーム画面から目を離せないときがあります。そこで棒読みちゃんに読んでもらおうと思いました。
(Discord自体に標準で読み上げ機能はあるけどもゆっくりボイスがいい)
そこで爆誕したDiscordと棒読みちゃんの仲介人である「Yomisen」を紹介したいと思います。
用意したもの
- C#の環境
- Discord(https://discordapp.com/)
- Discord.Net(NuGetからインストール可)
- 棒読みちゃん(http://www.vector.co.jp/soft/winnt/art/se475579.html)
アプローチの手順
- Discordにログイン
- チャットの通知を受け取る
- 棒読みちゃんに指示を送る
- ゆっくりしていってね!
実は超簡単な棒読みちゃんへの指示出し
棒読みちゃんのサブフォルダ「SampleSrc\IpcClientChannelで読み上げ指示を送る(ローカル専用・.NET専用)\Src\BouyomiChanSample」にあるBouyomiChanClient.csをプロジェクトにそのまま追加します。
これは作者様が開発用に提供してくださっているものです。
BouyomiChanClientクラスを使用すると
var bc = new BouyomiChanClient(); bc.AddTalkTask("読み上げたい内容"); bc.Dispose();
または、
using (var bc = new BouyomiChanClient()) { bc.AddTalkTask("読み上げたい内容"); }
のように簡単に棒読みちゃんに読み上げたい内容を送信できます。(棒読みちゃんを事前に起動しておく)
また、using構文はリソース解放の記述をしなくてもブロックを抜けると自動的にリソースを開放してくれます。
なので、下のほうがリソース解放の書き忘れの心配がないので安心できると思います。
ソースコード
概要
Program.cs
一部省略
using Discord; using Discord.WebSocket; using FNF.Utility; using System; using System.Threading.Tasks; namespace Yomisen { class Program { static void Main(string[] args) => MainAsync().GetAwaiter().GetResult(); /// <summary> /// 非同期Mainメソッド /// </summary> static async Task MainAsync() { // トークンのチェック await CheckTokenAsync(); // ログイン処理 Console.WriteLine("ログイン中…"); var client = new DiscordSocketClient(); await client.LoginAsync(TokenType.User, Properties.Settings.Default.Token); await client.StartAsync(); Console.WriteLine("ログイン完了"); // 始めのあいさつ(大事) var task = Task.Run(() => { using (var start = new BouyomiChanClient()) { start.AddTalkTask("棒読みちゃん起動~!"); } }); // メッセージ受信時のイベントを追加 client.MessageReceived += Talk; // 各種コマンド InputCommand(); // 終わりのあいさつ(大事) task = Task.Run(() => { using (var end = new BouyomiChanClient()) { end.AddTalkTask("棒読みちゃん終了~!"); } }); Console.WriteLine("キー入力で終了"); Console.ReadLine(); } /// <summary> /// メッセージを受け取った時の処理 /// </summary> static async Task Talk(SocketMessage arg) { await Task.Run(() => { // チャンネル一覧にあるなら if (Properties.Settings.Default.TextChannels.IndexOf(arg.Channel.Id.ToString()) >= 0) { // 読み上げ using (var bc = new BouyomiChanClient()) { bc.AddTalkTask(arg.Content); } } }); } ~以下省略~ } }
メッセージの通知を受信したときのイベントで、棒読みちゃんへの指示を行っています。
受信したメッセージのチャンネルIDが読み上げたいチャンネルIDとして登録されていれば読み上げが行われるようにします。
~省略~ // メッセージ受信時のイベントを追加 client.MessageReceived += Talk; ~省略~ // 読み上げ static async Task Talk(SocketMessage arg) { await Task.Run(() => { // チャンネル一覧にあるなら if (Properties.Settings.Default.TextChannels.IndexOf(arg.Channel.Id.ToString()) >= 0) { // 読み上げ using (var bc = new BouyomiChanClient()) { bc.AddTalkTask(arg.Content); } } }); }
Properties.Settings.Default.~~はアプリの設定ファイルで、設定値等を保存しておくことができるものです。
今回は、チャンネルIDの配列を保存しています。
機能として、コマンド入力によって読み上げたいテキストチャンネルのIDを登録・削除・列挙することができます。
トークンのリセットをした場合は一度終了となり、再度ログイン作業が必要となります。
テキストチャンネルのIDを調べる方法
- 設定>テーマ>開発者モード をオン
- テキストチャンネルの名前の上で右クリック
- IDをコピー でクリップボードにコピーされる
例
> add 012345678901234567
のように18桁のIDを正しく入力することでテキストチャンネルのIDを登録できます。
(適当に登録しても、自身のアカウントの知れる範囲のものでないと通知は来ません)
DiscordApiHelper.cs
Discord.Netではサポートされていないメールアドレスとパスワードによる
トークンの取得を実現するためのヘルパークラスです。
using Newtonsoft.Json; using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; namespace Yomisen { public static class DiscordApiHelper { /// <summary> /// EmailとPasswordでトークンを取得します /// </summary> public static async Task<string> LogInAsync(string mail, string password) { var baseUrl = "https://discordapp.com/api/"; var appName = "Yomisen"; var discordAccount = new { email = mail, password = password }; var json = JsonConvert.SerializeObject(discordAccount); var content = new StringContent(json, Encoding.UTF8, "application/json"); var res = await GetClient(appName).PostAsync(new Uri($@"{baseUrl}/auth/login"), content); if (res.IsSuccessStatusCode == true) { var resJson = await res.Content.ReadAsStringAsync(); var deserializedJson = JsonConvert.DeserializeAnonymousType(resJson, new { token = "" }); return deserializedJson.token; } else { return null; } } /// <summary> /// ヘッダーの追加 /// </summary> public static HttpClient GetClient(string appName) { var client = new HttpClient(); client.DefaultRequestHeaders.Add("User-Agent", appName); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); return client; } } }
discordapp.com
このあたりの書式に沿ってヘッダーの編集などをしてJSON形式でトークンを貰います。
このトークンは、
Discord上で「ctrl+shift+i」>Appliacationタブ>Local Storage>https://discordapp.com>token
の値と同値になると思います。
使い方
- 棒読みちゃんを起動(音量・速度等はこちらで設定)
- Yomisenを起動
- Discordのメールアドレスとパスワードを入力(初回・リセット時のみ)
- テキストチャンネルIDの登録
- ゆっくりしていってね!
GitHub
この記事では、ソースコードは一部省略していましたが、以下に公開しています。
github.com