Perl日記

PerlとかRubyとかPHPとかPythonとか

ZoomのAPIを使ってミーティングを作成する

Zoomメモ。

会社ではリモートワークしてるみんな(自分含む)とミーティングするのに、Zoomが使われている。

zoom.us


ZoomにはAPIがあるので、ミーティング用のURL作成処理をGo言語で作ってみた。

今回は60日トライアルでデベロッパー登録をした。

https://developer.zoom.us/
https://zoom.github.io/api/#create-a-meeting

API KEYとAPI Secret(とAccess Token)を作って控えておく。

ちなみにバージョンはv2を使う。

JWTを使う

import jwt "github.com/dgrijalva/jwt-go"

const ZOOM_API_KEY = "xxx"
const ZOOM_API_SECRET = "xxx"

token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
	"iss": ZOOM_API_KEY,
	"exp": fmt.Sprintf("%d", time.Now().Add(1*time.Minute).Unix()),
})

tokenString, err := token.SignedString([]byte(ZOOM_API_SECRET))

fmt.Println(tokenString)

1分間だけ有効なJWTができた。

自分のuser_idを知る

JWTをcurlコマンドでusersのAPIを叩いてみる。

$ curl -H 'Authorization: Bearer xxxxxx' https://api.zoom.us/v2/users | jq .
{
  "page_count": 1,
  "page_number": 1,
  "page_size": 30,
  "total_records": 1,
  "users": [
    {
      "id": "xxx",
      "first_name": "太郎",
      "last_name": "山田",
      "email": "taro.yamada@example.com",
      "type": 1,
      "pmi": 000,
      "timezone": "Asia/Tokyo",
      "dept": "",
      "created_at": "xxx",
      "last_login_time": "xxx",
      "last_client_version": "xxx"
    }
  ]
}

自分のuser_idが分かった。

ミーティングを作る

package main

import (
	"encoding/json"
	"log"
	"net/http"
	"strings"
)

const USER_ID = "xxx"
const CREATE_MEETING_URL = "https://api.zoom.us/v2/users/" + USER_ID + "/meetings"
const JWT = "xxx"

type Meeting struct {
	UUID      string    `json:"uuid"`
	ID        int       `json:"id"`
	HostID    string    `json:"host_id"`
	Topic     string    `json:"topic"`
	Type      int       `json:"type"`
	Duration  int       `json:"duration"`
	Timezone  string    `json:"timezone"`
	CreatedAt time.Time `json:"created_at"`
	StartURL  string    `json:"start_url"`
	JoinURL   string    `json:"join_url"`
	Settings  struct {
		HostVideo           bool   `json:"host_video"`
		ParticipantVideo    bool   `json:"participant_video"`
		CnMeeting           bool   `json:"cn_meeting"`
		InMeeting           bool   `json:"in_meeting"`
		JoinBeforeHost      bool   `json:"join_before_host"`
		MuteUponEntry       bool   `json:"mute_upon_entry"`
		Watermark           bool   `json:"watermark"`
		UsePmi              bool   `json:"use_pmi"`
		ApprovalType        int    `json:"approval_type"`
		Audio               string `json:"audio"`
		AutoRecording       string `json:"auto_recording"`
		EnforceLogin        bool   `json:"enforce_login"`
		EnforceLoginDomains string `json:"enforce_login_domains"`
		AlternativeHosts    string `json:"alternative_hosts"`
	} `json:"settings"`
}

func main() {
	payload := strings.NewReader(`{"type":1}`) // 1は通常の簡易ミーティング

	req, err := http.NewRequest("POST", CREATE_MEETING_URL, payload)
	if err != nil {
		panic(err)
	}

	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+JWT) // ヘッダに設定

	client := http.DefaultClient
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}

	if res.StatusCode != 201 {
		log.Fatal("status code is not 201!", res.Status)
	}

	defer res.Body.Close()
	var meeting Meeting
	err = json.NewDecoder(res.Body).Decode(&meeting)
	if err != nil {
		log.Fatal("json parse error!", err)
	}
	log.Println(meeting.JoinURL)
}

start_urlとjoin_urlの違いがいまひとつよくわからなかった(ドキュメントにも記載なし?)が、join_urlにアクセスしてmacのzoom.usアプリが立ち上がると、普通にミーティングができて開始時刻もそこからだったので、これで問題ないのかな、という感じ。

AWS S3から全部ではないけど大量に何個か取ってきたい

困ったのでメモ

背景

  • aws cliコマンドではS3から手元のローカルにコピーができる
  • バケットの中にはめちゃくちゃファイルがあるが、その中からいくつかコピーしたい
  • 「いくつか」とはいうものの、3000個ぐらいある…
  • バケット内にあるファイルは、すべて同じ拡張子なので、includeオプション(例 --include '*.png') が使えない…
  • 手元に全部同期(sync)して選別するにしても、1個1個のファイルサイズがそこそこあるので、全部ダウンロードしたら手元のディスクが死ぬ…

2つの解決策

aws s3 cp s3://my-bucket/mydir/foo/001.png .
aws s3 cp s3://my-bucket/mydir/foo/002.png .
aws s3 cp s3://my-bucket/mydir/foo/003.png .
...
  • --includeオプションを複数連ねて大量に作って、1つのコマンドとして実行する
aws s3 cp s3://my-bucket/mydir/foo/ . --recursive \
    --exclude '*' \
    --include 001.png \
    --include 002.png \
    --include 003.png \
    ...

--includeで頑張るほうが良さそう

  • awsコマンドを打つ度に認証なんやらが発生して、3000回awsコマンドを打つよりはincludeで頑張るほうが速い気がした(体感)
  • ただ、バケット内のファイル一覧を最初にスキャンしているのか、ダウンロードが始まるまで多少時間がかかった
  • --includeは100個くらいでないとだめそう。200個つけたら、ダウンロードが始まらなかった
    • なので、結局awsコマンドは何回か叩くことにはなる
  • ちなみにaws s3 cpはデフォルトが全部ダウンロード対象なので、--include は --exclude '*' とセットで使わないと意味がなかったので注意

予算は使い切らないと損であるという呪い

なんかメモ。



朝にオフィスに来るとすでに暖房がものすごく効いていて、机に手を付けてみると熱を感じられるほどである(机だぞ!?)。
オフィスは賃貸で、電気代は賃貸料金に含まれていると聞いたことがある(違うかもしれないけど)。
それを知ってか知らずか、冷気滅ぶべしという勢いで暖房がついている。
どれだけ電気を使っても払う金額が同じなら、使わなければ損だという理屈のように思える。
(いやまあそんなの関係なくみんな室温が25℃が好きという可能性が高いけど)
あと、トイレに冷暖房はなく外気温と同じなので、トイレに行くと寒くて、戻ってくると暑いという、寒暖差がすごいことになっている。



上の例はとは逆かもしれないが、
使える予算があって、それを使い切らないと損、という考えは、この時代にはおおよそ筋の悪いもののように思える。
余ったら返せばいいのではないか。
何か変なものを余計に購入するよりもずっと良いはず。
そうすると、次の予算から減額されて困る、ということだろうか。
減額されて、減額できた分を評価軸に組み込めればいいのではないか。




限りがあると、なぜかそれをぴったり使いたがる。
会社のお金であって自分のお金ではないから、使わないと損、という感じになるのだろうか。
「もったいない精神」はそこに発揮するところではないように思う。