ZoomAPIを使ってミーティングを作成しよう 〜Slackに送るまで〜

# コロナの影響でZoomを使うことが増えました
最近猛威を奮っているコロナの影響で弊社でもリモートワークが導入されました。

現在は無料アカウントを使っているのですが、40分ごとにミーティングが切れる　⇨　手動で立て直すという作業が非常にだるいです。

そこで、自動化してみよう！という話になりました（課金しろ）


# この記事で出来ること

・　rubyファイルを実行するとZoomのミーティングが作成され、URLが発行される
・　Slackと連携し、SlackのBotからミーティングURLをチャンネルに送信する



# ZoomAPIのミーティングを作るドキュメント
ここにZoomAPI（ミーティングを作る用）のドキュメントがまとまっています。

https://marketplace.zoom.us/docs/api-reference/webhook-reference/meeting-events/meeting-created

# ミーティングの作成は1日１００リクエスト（POST）まで？
```
This API has a daily rate limit of 100 requests per day. 
Therefore, only 100 Create a Meeting API requests 
are permitted within a 24 hour window for a user
```
ドキュメント内の記載を見てみると、ミーティングを作成する（POSTメソッド）は、1日１００件までだそうです。
これ以上必要な場合、もう１アカウント（１アプリでも良いかも）必要なみたいですね。


# Zoom APIを使用するための準備

まずは会員登録や開発用アプリの作成をよしなにお願いします。

## user_idの取得方法

ZoomのAPIを使用するためには自分のアカウントのuser_idを取得する必要があります。

まず、作成したアプリのページに移動します。

![スクリーンショット 2020-03-05 12.23.05（3）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486805/39f97ab2-a926-8ac8-c56f-d035ca152442.png)

一番下のJWTのTokenをコピーします。

コピーしたものを以下に貼り付けて叩きます。
(APIkeyとかは適当な文字に変えています）

```bash
$ curl -H 'Authorization: Bearer JWTのToken' https://api.zoom.us/v2/users
```

これを叩くと色々な情報が返ってきます。


```json

{
  "page_count": 1,
  "page_number": 1,
  "page_size": 30,
  "total_records": 1,
  "users": [
    {
      "id": "idgakaelltekuruyo",
      "first_name": "inu",
      "last_name": "inuotoko",
      "email": "aaaaaa@gmail.com",
      "type": 1,
      "pmi": 00000000000,
      "timezone": "Asia/Tokyo",
      "verified": 1,
      "created_at": "2020-02-27T23:53:40Z",
      "last_login_time": "2020-03-02T06:53:15Z",
      "language": "jp-JP",
      "phone_number": "000-0000-0000",
      "status": "active"
    }
  ]
}
```


ここに自分のuser_idとかが含まれています。
ミーティングを作る時にuser_idが必要なのでメモしておきましょう。

#Zoom APIを叩く

```ruby:zoom.rb
require 'net/https'
require 'net/http'
require 'uri'
require 'json'

api_key = "適宜"
secret  = "適宜＿"
user_id = "適宜"
jwt = "適宜"
meeting_url = "https://api.zoom.us/v2/users/#{user_id}/meetings"


uri = URI.parse(meeting_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Post.new(uri.path)
req["Authorization"] = "Bearer #{jwt}"
Bearer = "Bearer #{jwt}"

req["Content-Type"] = "application/json"
    req.body = {
        "type":1,
    }.to_json
res = http.request(req)
puts res.class
puts res.code
puts res.body
return res

```

```
$ ruby zoom.rb
```
これを実行すると以下が返ってきます。

```json
{
    "uuid": "",
    "id": 00000000,
    "host_id": "",
    "topic": "Zoom Meeting",
    "type": 1,
    "status": "waiting",
    "timezone": "Asia/Tokyo",
    "created_at": "2020-03-05T07:07:40Z",
    "start_url": "https://zoom.us/s/000000?tekitounaURL",
    "join_url": "https://zoom.us/j/0000000?pwd=tekitou",
    "password": "000000",
    "h323_password": "000000",
    "pstn_password": "000000",
    "encrypted_password": "aaaaaaaaaaaaa",
    "settings": {
        "host_video": false,
        "participant_video": false,
        "cn_meeting": false,
        "in_meeting": false,
        "join_before_host": false,
        "mute_upon_entry": false,
        "watermark": false,
        "use_pmi": false,
        "approval_type": 2,
        "audio": "both",
        "auto_recording": "none",
        "enforce_login": false,
        "enforce_login_domains": "",
        "alternative_hosts": "",
        "close_registration": false,
        "registrants_confirmation_email": true,
        "waiting_room": false,
        "global_dial_in_countries": [
            "JP",
            "US"
        ],
        "global_dial_in_numbers": [
            {
                "country_name": "Japan",
                "number": "gorog000",
                "type": "toll",
                "country": "JP"
            },
            {
                "country_name": "Japan",
                "number": "0gr9g999",
                "type": "toll",
                "country": "JP"
            },
            {
                "country_name": "US",
                "city": "ニューヨーク",
                "number": "+1 r",
                "type": "toll",
                "country": "US"
            },
            {
                "country_name": "US",
                "city": "サンノゼ",
                "number": "+1 4086380968",
                "type": "toll",
                "country": "US"
            }
        ],
        "registrants_email_notification": true,
        "meeting_authentication": false
    }
}
```

# Slackに送る

次に作成したURLをSlack内部のチャンネルに送ります。


Slack側のtokenは、Zoomではなく、SlackAPIのtokenが必要なので適宜入れましょう。
（Slack用のBotが作れていない人は、作ってくださいね！）

```ruby:zoom.rb

require 'net/https'
require 'net/http'
require 'uri'
require 'json'


#zoom
def zoom
    api_key = "eeeeeee"
    secret  = "eeeeeeeeeeeee"
    user_id = "eeeeeeeeee"
    jwt = "eeeeeeeeeee"
    meeting_url = "https://api.zoom.us/v2/users/#{user_id}/meetings"

    uri = URI.parse(meeting_url)
    http = Net::HTTP.new(uri.host, uri.port)

    http.use_ssl = true
    http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    req = Net::HTTP::Post.new(uri.path)
    req["Authorization"] = "Bearer #{jwt}"
    req["Content-Type"] = "application/json"
        req.body = {
            "type":1,
        }.to_json
    res = http.request(req)
    parseURL = JSON.parse(res.body)
    url = parseURL["join_url"]

#urlを引数に入れてslackメソッド呼び出し
    slack(url)
end


# #Slack
def slack(zoom) 
    require "http"
    token        = "eeeeeeeeeeeeee"
    channel_name = "チャンネル名を入れてね"

    response = HTTP.post("https://slack.com/api/chat.postMessage", params: {
        token: token,
        channel: channel_name,
        text: zoom
    })
end

//呼び出し
zoom

```
以上で終わりです。

今後は40分毎にこのスクリプトを実行するなど改良を加えていきたいと思います。


# 開発参考URL
[ZoomのAPIを使ってミーティングを作成する](http://r9.hateblo.jp/entry/2018/01/30/081534)
[RubyでZoomのAPIを使って通話したい](https://teratail.com/questions/148105)

# 現状の問題点

ZoomAPIを使ってミーティングを立ち上げる　⇨　無料アカウントなので40分で切れる　⇨　再度URLを発行するためにAPI実行する

と、`たまに`以下のエラーが出る。


```zsh

Failed to open TCP connection to api.zoom.us:443 (getaddrinfo: Temporary failure in name resolution)
```

443番ポートが開いてる？名前解決がうまくいっていない？らしいです。
2分後くらいに実行するとエラーが出ないのでZoom側から拒否してるのかな？
（即MTGを発行できると40分の制限かけてる意味ないですもんね〜、でも手動では即作れるんですよね〜）


とはいえやりたいことは実現できたので今回はこの問題はスルーします！