【メモ】obsのシーン切替をLINEBotで操作できるようになるまで

##### 注意　個人的な備忘録です。記事のクオリティには期待しないでください

## 成果物

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">はい優勝🎉<br><br>linebotからwebsocketを用いてobsのシーンを切り替える<br><br>思った通りに実装できて楽しい😊<a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a> <a href="https://twitter.com/hashtag/linedc?src=hash&amp;ref_src=twsrc%5Etfw">#linedc</a> <a href="https://t.co/SvoqgwyEwV">https://t.co/SvoqgwyEwV</a> <a href="https://t.co/eAFjQ6TJGM">pic.twitter.com/eAFjQ6TJGM</a></p>&mdash; ようかん / Yosuke Inoue (@inoue2002) <a href="https://twitter.com/inoue2002/status/1321474473992753153?ref_src=twsrc%5Etfw">October 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##環境

```
MacOS Catalina 10.15.6
OBS Studio 25.0.8(64bit)
obs-websocket 4.8
"@line/bot-sdk": "^7.1.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"obs-websocket-js": "^4.0.2"
```

##　これを実現するまでの過程

###OBSをインストール
この記事をご覧のみなさんにOBSのインストールはそれほど重要ではないと思うので省略。
→　[OBS公式サイトからダウンロードする](https://obsproject.com/ja/download)

### obs-websocketをインストール
[obs-websocketのリポジトリ](https://github.com/Palakis/obs-websocket/releases)から最新版をダウンロードする。

![スクリーンショット 2020-10-29 17.02.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/6a8b0244-b48a-525f-23f0-6beb50904104.png)

![スクリーンショット 2020-10-29 17.02.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/a76f0dab-995e-f9e9-a561-257e9d321d5a.png)

上記の画像やobs-websocketに書かれたことを読み、各環境に応じてダウンロードを行う

###インストールできたか確認する
![スクリーンショット 2020-10-29 17.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/a06db43f-9346-7b2c-ba51-84bc50f4747b.png)

"WebSockets Server Settings"の項目があれば成功

###WebSocketServerの有効化
![スクリーンショット 2020-10-29 17.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/e6af5190-b0bb-a7b7-181c-807ac9b46eec.png)
デフォルトのサーバーポートは `4444`になっている。すでにポートを利用している場合は自由に変更することができる。
パスワードの設定もお忘れなく。

### ngrokのインストール
[ngrokのダウンロードページ](https://ngrok.com/)からダウンロードしておく。

``` 
Windowsな方でパスが通らない時

①Winキー＋Pause/Break　を同時押し
②システムの詳細設定へと進む
③詳細設定のタブから環境変数というボタンをクリックする
④システム環境変数欄からPathの項目を探し、編集を行う
⑤参照をクリックし、ngrokがインストールされているディレクトリを追加する
⑥コマンドプロント立ち上げ直し、再びバージョン確認ができるか行う
```

### linebotの作成

```
cd desktop 
mkdir obsBot
cd obsBot
touch index.js $$ .env
npm init -y 
npm install @line/bot-sdk
npm install express 
npm install dotenv --save
npm install obs-websocket-js 
```

``` index.js

"use strict";

const express = require("express");
const line = require("@line/bot-sdk");
const PORT = process.env.PORT || 3000;
const dotenv = require("dotenv");
dotenv.config();

const config = {
  channelAccessToken: process.env.CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.CHANNEL_SECRET,
};

const app = express();

app.get("/", (req, res) => res.send("Hello（GET)"));
app.post("/webhook", line.middleware(config), (req, res) => {
  console.log(req.body.events);

  if (
    req.body.events[0].replyToken === "00000000000000000000000000000000" &&
    req.body.events[1].replyToken === "ffffffffffffffffffffffffffffffff"
  ) {
    res.send("Hello!(POST)");
    console.log("疎通確認用");
    return;
  }

  Promise.all(req.body.events.map(handleEvent)).then((result) =>
    res.json(result)
  );
});

const client = new line.Client(config);

 async function handleEvent(event) {
  if (event.type !== "message" || event.message.type !== "text") {
    return Promise.resolve(null);
  }

  // ライブラリのimport
  const OBSWebSocket = require("obs-websocket-js");
  // インスタンス初期化
  const obs = new OBSWebSocket();
  // OBSに接続してPromiseを受け取る
  obs
    .connect({
      address: "localhost:4000",  //先ほどOBSで設定したポート番号を記入
      password: "xxxxxxxxxxxxxxx",  //先ほどOBSで登録したパスワードを記入
    })
    // 接続成功
    .then(() => {
      console.log(`Success! We're connected & authenticated.`);
      // シーンの一覧を取得するリクエスト
      return obs.send("GetSceneList");
    })
    .then((data) => {
        console.log(data)
      console.log(`${data.scenes.length} Available Scenes!`);
      // シーンの一覧から現在のシーンを探す
      data.scenes.forEach((scene) => {
        if (scene.name !== data.currentScene) {
          console.log(
            `Found a different scene! Switching to Scene: ${scene.name}`
          );
          // 現在のシーンを切り替えるリクエスト
          obs.send("SetCurrentScene", {
            "scene-name": scene.name,
          });
        }
      });
    })
    .catch((err) => {
      // Promise convention dicates you have a catch on every chain.
      console.log(err);
    });
  // シーンが切り替わったイベントをObserveする
  obs.on("SwitchScenes", (data) => {
    console.log(`New Active Scene: ${data.sceneName}`);
  });
  // エラーをObserveする
  obs.on("error", (err) => {
    console.error("socket error:", err);
  });

  return client.replyMessage(event.replyToken, {
    type: "text",
    text: event.message.text,
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

[LINEBotコンソール](https://developers.line.biz/ja/)からLINEBotを作る
チャンネルアクセストークンとチャンネルシークレットを取得し、先ほどの`.env`の`'xxx'`の部分に書き換える。↓

``` ..env
CHANNEL_ACCESS_TOKEN = "xxxxxxxxxxxxxxxxxxx"
CHANNEL_SECRET = "xxxxxxxxxxxxxx"
```

書き換える↓

```
.connect({
      address: "localhost:4000",  //先ほどOBSで設定したポート番号を記入
      password: "xxxxxxxxxxxxxxx",  //先ほどOBSで登録したパスワードを記入
    })
```



```
node index.js  　//コードを起動する
```

```
ngrok http 3000
```

ngrokから発行されたURLに `/webhook`を末尾につけてLINWEBotのWebhookURLに設定する

### シーンを適当に何個か作る

### LINEBotにリッチメニューとか作ってそれっぽくする


### LINEBotにメッセージを送る

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">はい優勝🎉<br><br>linebotからwebsocketを用いてobsのシーンを切り替える<br><br>思った通りに実装できて楽しい😊<a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a> <a href="https://twitter.com/hashtag/linedc?src=hash&amp;ref_src=twsrc%5Etfw">#linedc</a> <a href="https://t.co/SvoqgwyEwV">https://t.co/SvoqgwyEwV</a> <a href="https://t.co/eAFjQ6TJGM">pic.twitter.com/eAFjQ6TJGM</a></p>&mdash; ようかん / Yosuke Inoue (@inoue2002) <a href="https://twitter.com/inoue2002/status/1321474473992753153?ref_src=twsrc%5Etfw">October 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### まとめ

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/youtoy?ref_src=twsrc%5Etfw">@youtoy</a> さんの影響を受けて今からobsをLINEbotから操作できるか挑戦してみる<br><br>全ては明日のため</p>&mdash; ようかん / Yosuke Inoue (@inoue2002) <a href="https://twitter.com/inoue2002/status/1321448351322136576?ref_src=twsrc%5Etfw">October 28, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 後日使ってみた
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">OBSコントローラー / LINEbot<br>変えたいシーンの名前をBotに送るとその画面に変わります<br>割と直接OBS触らなくていいので便利かも!!<a href="https://twitter.com/hashtag/%E3%81%99%E3%81%94%E3%81%8F%E3%81%AA%E3%82%8A%E3%81%9F%E3%81%84%E3%81%8C%E3%81%8F%E3%81%9B%E3%81%84%E3%81%90%E3%82%8B%E3%83%BC%E3%81%B7?src=hash&amp;ref_src=twsrc%5Etfw">#すごくなりたいがくせいぐるーぷ</a> <a href="https://t.co/gWSGUtxrQO">pic.twitter.com/gWSGUtxrQO</a></p>&mdash; ようかん / Yosuke Inoue (@inoue2002) <a href="https://twitter.com/inoue2002/status/1344546507370815488?ref_src=twsrc%5Etfw">December 31, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

開発の宣言ツイートしてからわずか一時間ぐらいで成功しました。もう少し色々できるみたいなので勉強していきたいです。
いつの間にかWebSocketにも入門してしまった。。。。

参考にした記事
https://qiita.com/youtoy/items/23fb0e16f1a4428b5c9b
https://note.com/kirimin_chan/n/ne0f039f17289