Youtube上にカフェを作った話

こんにちは、趣味でプログラミングに勤しむ大学生です。

今回の記事では僕が作成したYoutube上のカフェ、「バーチャル勉強喫茶 Virtual Study Cafe」について述べていきます。

少しでもいいなと思ったらLGTMよろしくお願いします〜

# つくったもの
まず、Youtube上のカフェってなんやねん。。。説明しろや( *｀ω´)

ひー、すんません！！とりあえず「百聞は一見にしかず」、まずは下の動画を見てください。
※なんか画面ちっさくなっちゃった。とりあえず画面の真ん中あたりをジーーっと見ると変化してる様子がよくわかりますorz

![StudyCafe_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/04006c8d-9cba-4c10-667c-5b2ba03cee45.gif)

上記動画は、Youtubeの配信画面です。

配信画面にカフェが映ってますね。このカフェにチャットを打ち込むことでアクションを起こすことができます！

例えば、カフェに入店したり、コーヒーを注文したり、勉強科目を設定したり、休憩したりなど様々なことができます。基本的には、勉強など何か集中して作業したい人に向けたサービスです。作業用BGMの進化版みたいなイメージですね。よりカフェにいるというコンセプトを強めて、勉強している人が本当にカフェで勉強してるのでは！？と思えるようにしたかったんですよね（なに言ってんだ）。

まあ、とにかく「カフェに入店→勉強などの作業→カフェから退出」、というのがこのサービスの利用の流れです。

どんなものかもっと知りたい人は下からどうぞ〜

https://www.youtube.com/channel/UCVzUJG1KudbgjAbC_eaNiQg

# 使用技術
利用したものは以下の通り。

### フロントエンド
+ HTML
+ CSS
+ JavaScript(vue)
+ Canva（画面デザイン）

### バックエンド / Bot 
+ Python
+ Youtube Data API
+ Google Sheets API
+ CloudFireStore

# 紹介
### デザイン
カフェらしいおしゃれでかわいいデザインにしようと頑張った。筆者にはこれが限界です…笑　オシャレナニそれオイシイノ...? byおしゃれとは無縁な大学生

![background3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/7cb70e36-2933-30a6-eae7-70270fed4f14.png)
※無断転載厳禁

こういうデザインを今までしたことなかったからすごく大変でした...
デザインには、Canvaを使用しました！ネコちゃんがかーいい:relaxed:

### BGM
カフェにいるような気分を味わえるオサレなBGMがかかっています。勉強が進むは進む。いい曲だから死ぬまでに一回は聞いとかないとねえ。ねえ〜？（同調圧力）

### 機能
どんな機能を作ったか大まかに説明します。詳しい使い方は、Youtube配信の概要欄を見てみてください！

+ 1〜75のいずれかの席に入室することができます。空いている席が他にもあれば、好きな席に移動することもできます。ちなみにこの席の場所のCSSはseat1〜75のクラスで一個一個指定しています。何気に大変。何かいい方法あったのかな...教えてクレメンス
+ 勉強疲れたな〜ってときは、休憩することができます。休憩するとアイコン右上の丸の色が変わります。
勉強中：緑色
![a2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/a2715e42-ebdb-b3ba-8772-ae54e1d2ed55.png)


休憩中：オレンジ色
![a1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/f9751916-3dcc-c7d6-cc6c-aa458e35d0ba.png)

+ 個人的にお気に入りはこのトースター。複数のトースターが表示される時の動きをうまく設定できずに無限にエラー吐いてたなあ。懐かしい。こだわりポイントは下のプログレスバーで残り何秒間表示されるのかってことをわかりやすくした。下のバーはCSSで動きをつけてるんだけど、確かinline-sizeを変えることで実現した。ほんまよく思いついたで工藤。まあ、もっといい方法ありそうだけどな〜:innocent:
![a2 2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/87743e63-cdef-0d21-ae96-b79a53984b7a.png)

+ タイマー機能
勉強する人が、集中しやすいように25分-5分のタイマーを設定してある。タイマーの終了時に音を出したいって考えて調べたら、Audio()ってのがあって、簡単に実装できた。JavaScriptすげ〜〜〜
![IMG_D0058614E823-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/ce9ac64b-54b8-d856-83ba-52dcd79a340e.jpeg)


+ いいね機能
勉強する人同士で応援しあえるような環境を作りたかった。なんか頑張ってて偉いね、とか、来てくれてありがとうって伝えたい時にそれをチャットで打ち込むって勇気いるよなって思って、この機能をつくった。いいねされると、でかいハートが表示され、アイコン右上の縁の中にいいねされた回数が表示されるようになる。この機能でカフェにいるみんながお互いに応援し互いに高めあえるようになって欲しいな、と元浪人生は思いにけり。支え合いって大事。

![RPReplay_Final1653401859_AdobeCreativeCloudExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/4acaddd9-e3f7-693e-2b11-1ff02bc9a79c.gif)


![IMG_6219.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/112cfae1-9498-6a8c-183c-c1254b0bf244.png)



+ 注文機能
コンセプトとして勉強するカフェなので、やっぱり商品がほしいと思った。現在提供している商品は、コーヒー、カフェオレ、ドーナッツ（皿なしw）、クリームパン（なぜw）。みんなもぜってー注文してくれよな！
![IMG_6221.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1912865/1c9bff05-45bc-c86d-5a22-e86072649fcf.png)

などなど。
我ながら全て独学でよくできたと思うぜ:sunglasses:

# どう作ったのか
だいたい今回のサービスについて理解してもらえたと思います。
続いて、今回のサービスの肝であるYoutubeのチャット欄から情報を取得する方法を説明します。

参考：
https://developers.google.com/youtube/v3/live/getting-started

### 準備
+ [Google Cloud Console ](https://console.cloud.google.com/apis/library?hl=ja)に移動し、プロジェクトの作成をします。プロジェクト名はお好きなものを入力してください。
+ 「Youtube Data API」と検索し、有効にするを押します。
+ 「OAuth同意画面」で同意画面の設定をします。外部→テストモード→メアドなどの入力→2番目の画面は特になにもしない→3番目の画面の「Add User」からYoutubeのチャット欄の取得に利用するメアドを追加する→設定完了
+ 「認証情報」で認証情報の設定をします。「認証情報を作成」→「OAuthクライアントID」→「デスクトップアプリ」を作成し、JSONファイルを保存
+ Pythonファイルを作成する。

### コード
+ ライブラリをインポートする
```bot.py
import os
import google_auth_oauthlib.flow
import googleapiclient.discovery
import googleapiclient.errors
from importlib_metadata import collections
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
```

+ 認証設定などの前準備
CLIENT_SECRET_FILEには、先ほど保存したJSONファイルを設定してください！
```bot.py
scopes = ["https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/youtube.force-ssl"]
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
api_service_name = 'youtube'
api_version = 'v3'
client_secrets_file = CLIENT_SECRET_FILE
flow = google_auth_oauthlib.flow.InstalledAppFlow.from_client_secrets_file(
    client_secrets_file, scopes
)
credentials = flow.run_console()
youtube = googleapiclient.discovery.build(
    api_service_name, api_version, credentials=credentials
)
```

+ liveIDを取得する関数の定義
Youtube LIive Streaming APIを利用するためには、そのライブのliveIDを取得する必要がある。liveIDの取得には、そのライブのURL末尾（v= 以降の太字）の文字列が必要で、以下の関数ではvideo_idとして引数で指定してある。

https: //www.youtube.com/watch?v= **3mqgI-t_V8k**

```bot.py
def _get_live_id(youtube, video_id):
    res = youtube.videos().list(part='liveStreamingDetails', id=video_id).execute()
    live_id = res['items'][0]['liveStreamingDetails']['activeLiveChatId']
    return live_id
```

+ チャット欄を取得する関数の定義
```bot.py
def main(pageToken, video_id):
    youtube = _get_authenticated_service()
    # 初期変数の設定
    LIVE_CHAT_ID = _get_live_id(youtube, video_id) #ここのIDをLiveに応じて変える
    while True:
        # チャット欄の取得
        request = youtube.liveChatMessages().list(
            liveChatId = LIVE_CHAT_ID,
            part = 'snippet, authorDetails',
            pageToken = pageToken,
        )
        response = request.execute()

        # itemsが空でない場合（チャットが打ち込まれた場合）
        if response['items'] != []:
            # 取得したチャットから情報を抜き出す
            for i in range(len(response['items'])):
                snippet_data = response['items'][i]['snippet']
                author_data = response['items'][i]['authorDetails']
                
                # チャット内容
                message = snippet_data['displayMessage']
                
                # 投稿者
                name = author_data['displayName']
                owner_role = author_data['isChatOwner'] #bool
                moderator_role = author_data['isChatModerator'] #bool
                
                # チャンネルURL
                channel_url = author_data['channelUrl']


        #新規チャットのページトークンを取る
        pageToken = response['nextPageToken']
        #連続で何度も行うとyoutubeに怒られるので時間をおく
        time.sleep(10)
```

+ 実行する
```bot.py
   if __name__ == '__main__':
    video_id = input('IDを入力してください。')
    pagetoken_id = input('pageTokenを入力してください。')#はじめは空でOK
    main(pagetoken_id, video_id)
```

これで、好きなライブ配信からチャット内容などの情報を取ることができます！みなさんもやってみてはいかが？


# 今後の課題
なんといってもマーケティング！
つくったら終わり、じゃなくてやっぱり多くの人に知って使ってほしいという欲望がでてきてしまう。どうやって多くの人に周知しようかな〜って考えてます。75席じゃ足りない、増やさなきゃ！となりたい。。。

有識者コメントで教えてクレメンスザウルス🦖

Youtubeチャンネル↓↓↓
https://www.youtube.com/channel/UCVzUJG1KudbgjAbC_eaNiQg

2022.05.24現在
チャンネル登録者：32人
同時接続数：ほとんど0〜3人
総利用者数：58人

なぜじゃ。。。
こっから成長してくれると嬉しいな。そんな期待を込めながらこの記事を書いていやす。読んでくれてありがとね。

# 終わりに
コメント、LGTM、ストック色々してくれるとほんとに嬉しいです！たのんます！
あとは、チャンネル登録もよr。。ぶふぉっ_:(´ཀ`」 ∠):