コンテンツにスキップ

外部ツールとの連携

ご利用の外部ツールがAPI経由などでプロフィール画像を更新できる場合、外部ツール側のプロフィールもアバターを利用し、Webhook を利用して同期できます。プロフィール画像を更新できる外部ツールとしては、例えば以下のサービスが挙げられます。

Info

Avatar Play では外部ツール側の動作を保証することはできません。外部ツール側の挙動については、各ベンダーにお問い合わせください。

外部ツールから認証情報を取得する

通常、OAuth などのプロトコルに従って外部ツールからAPI利用に必要となる認証情報(アクセストークンなど)を取得します。手順等は各ツールのマニュアルを参照してください。

外部ツールのプロフィールを更新する

以下の手順で外部ツールのプロフィールを更新します。

  1. エンドユーザが着せ替えしたことを Webhook で受信する
  2. ペイロードからアバター画像URLを取得し、アバター画像をダウンロードする
  3. 外部ツールのプロフィール画像更新APIへ画像をアップロードする

プロフィール画像の更新APIについては、各ツールのマニュアルを参照してください。

Slack での実装例

// Go言語での実装

import (
    "bytes"
    "io"
    "mime/multipart"
    "net/http"
)

// OnAvatarChanged は、Webhook 経由で着せ替え通知を受け取り、Slack のアバターを更新します。
func OnAvatarChanged(w http.ResponseWriter, r *http.Request) {
    // Webhook の認証処理
    // ... (略) ...

    // アバター画像のダウンロード
    var avatarImage []byte // アバター画像データ
    if res, err := http.Get(r.FormValue("avatarImageUrl")); err != nil {
        http.Error(w, "failed to get avatar image", http.StatusInternalServerError)
        return
    } else {
        defer res.Body.Close()

        avatarImage, err = io.ReadAll(res.Body)
        if err != nil {
            http.Error(w, "failed to read avatar image", http.StatusInternalServerError)
            return
        }
    }

    // Slack のプロフィール画像を更新

    // 画像データ付きのマルチパート対応ボディを作成する
    body := &bytes.Buffer{}
    mw := multipart.NewWriter(body)

    // 認可トークンを設定
    if err := mw.WriteField("token", "{アクセストークン}"); err != nil {
        http.Error(w, "failed to write token field", http.StatusInternalServerError)
        return
    }

    // アバター画像を設定
    if ff, err := mw.CreateFormFile("image", "avatar.gif"); err != nil {
        http.Error(w, "failed to create form file", http.StatusInternalServerError)
        return
    } else if _, err := io.Copy(ff, bytes.NewReader(avatarImage)); err != nil {
        http.Error(w, "failed to write avatar image", http.StatusInternalServerError)
        return
    }

    // 書き込み
    if err := mw.Close(); err != nil {
        http.Error(w, "failed to close multipart writer", http.StatusInternalServerError)
        return
    }

    // Content-Type の設定
    req, err := http.NewRequest(http.MethodPost, "https://slack.com/api/users.setPhoto", body)
    if err != nil {
        http.Error(w, "failed to new request", http.StatusInternalServerError)
        return
    }
    req.Header.Set("Content-Type", mw.FormDataContentType())

    // APIへアバター画像を送信
    if res, err := http.DefaultClient.Do(req); err != nil {
        http.Error(w, "failed to request", http.StatusInternalServerError)
        return
    } else {
        defer res.Body.Close()

        // 以下のレスポンスが返れば成功
        // { "ok": true }
    }

    // ...
}


最終更新日: 2022-01-05