0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Slackの絵文字をGoogle Chatに一括移行するツールを作った

0
Last updated at Posted at 2026-01-21

はじめに

SlackからGoogle Chatへの移行を検討している方、Slackで長年蓄積したカスタム絵文字をGoogle Chatでも使いたいと思ったことはありませんか?

弊社でもGoogle Chatを利用することが増えてきたのでSlackのようにカスタム絵文字を使いたい!というニーズが高まってきました。

今回、Slackからエクスポートした絵文字をGoogle Chat APIを使って一括登録するPythonツールを作成しました。約3,800件の絵文字を一括登録した実践記録とともに紹介します。

ただし、組織外のメンバーがいるスペースでは使えないみたいです、残念...

完成したツール

GitHub: google-chat-emoji-bulk-uploader

主な機能

  • Slackエクスポートの絵文字画像を自動検出
  • Google Chat APIの制約に基づく自動バリデーション
  • エラーファイルをカテゴリ別にフォルダ分け
  • 既存の絵文字はスキップ(重複防止)

Google Chat 絵文字の制約

Google Chatのカスタム絵文字には以下の制約があります:

項目 制約
ファイルサイズ 256KB以下
寸法 64px〜500pxの正方形
形式 PNG, JPG, GIF
命名規則 小文字英数字、ハイフン、アンダースコアのみ

セットアップ手順

1. Google Cloud Console での設定

プロジェクト作成とAPI有効化

  1. Google Cloud Console にアクセス
  2. 新しいプロジェクトを作成(例: emoji-bulk-uploader
  3. 「APIとサービス」→「ライブラリ」で Google Chat API を検索して有効化

OAuth同意画面の設定

  1. 「APIとサービス」→「OAuth同意画面」
  2. ユーザータイプ: 内部(組織内のみ)または外部
  3. スコープを追加: https://www.googleapis.com/auth/chat.customemojis

OAuth認証情報の作成

  1. 「APIとサービス」→「認証情報」→「認証情報を作成」
  2. 「OAuthクライアントID」を選択
  3. アプリケーションの種類: デスクトップアプリ
  4. 作成後、JSONをダウンロードして credentials.json として保存

Chat アプリの設定(重要!)

これが最初のハマりポイントでした。OAuth認証情報だけでは不十分で、Chat APIの構成設定が必要です。

  1. Google Cloud Console → 「Google Chat API」→「構成」タブ
  2. 以下を設定(アバターURLと説明は必須):
    • アプリ名
    • アバターURL(任意の画像URLでOK)
    • 説明

これを設定しないと Google Chat app not found エラーが発生します。

2. 依存関係のインストール

pip install -r requirements.txt

必要なパッケージ:

  • google-auth-oauthlib
  • google-api-python-client
  • Pillow

使い方

基本的な使い方

# emojis/ ディレクトリの絵文字をアップロード
python main.py emojis/

初回実行時にブラウザが開き、Googleアカウントでの認証を求められます。

ドライラン(検証のみ)

python main.py emojis/ --dry-run

アップロード前にバリデーションエラーを確認できます。

エラーファイルの分類

python main.py emojis/ --organize-errors errors/

エラーファイルがカテゴリ別にフォルダ分けされます:

errors/
├── invalid_dimension/     # サイズが64-500px範囲外
├── invalid_format/        # PNG/JPEG/GIF以外の形式
├── not_square/            # 正方形でない画像
└── upload_errors/         # アップロード時のAPIエラー
    ├── invalid_payload/   # GIFエンコード問題
    ├── reserved_name/     # 予約語・禁止ワード
    └── invalid_name_api/  # APIが拒否した無効な名前

実践:3,800件の絵文字を一括登録

結果サマリー

項目 件数
総ファイル数 3,818
バリデーション通過 3,643
アップロード成功 3,574
アップロード失敗 42

成功率: 約99%

バリデーションエラーの内訳(175件)

カテゴリ 件数 説明
not_square 113 正方形でない画像
invalid_dimension 55 サイズが64-500px範囲外
invalid_format 7 PNG/JPEG/GIF以外の形式

アップロードエラーの内訳(42件)

カテゴリ 件数 説明
invalid_payload 14 GIFエンコード問題
reserved_name 10 予約語・禁止ワード
invalid_name_api 10 末尾特殊文字、1文字の名前
name_too_long 1 名前が長すぎる

開発中にハマったポイント

1. Chat アプリの設定が必要

OAuth認証情報を作成しただけでは動きません。Google Chat APIの「構成」タブでアプリ設定(アバターURL、説明)が必須です。

エラー:

Google Chat app not found

解決: Cloud Console → Chat API → 構成 でアプリ設定を完了する

2. 絵文字名にはコロンが必要

APIに送信する絵文字名は :emoji-name: の形式(前後にコロン)が必要です。

エラー:

Duplicate or malformed custom emoji name

解決:

emoji_name_with_colons = f':{emoji_name}:'

3. APIリクエストボディの形式

Google Chat API v1の形式に従う必要があります。

body = {
    'emojiName': ':emoji-name:',
    'payload': {
        'fileContent': base64_encoded_image,
        'filename': 'emoji.png',
    }
}

4. 予約語・禁止ワード

以下のような名前はAPIで拒否されます:

  • 予約語: atom, biohazard, skip, jojo, korona など
  • 1文字の名前: e, n, p, s, w, y
  • 末尾特殊文字: are-_, kaneda-_
  • 長すぎる名前

これらはバリデーション時点では検出できず、API呼び出し時に初めてエラーになります。

5. 一部のGIFが処理できない

アニメーションGIFの一部はAPIで Invalid payload エラーになります。おそらくGIFのエンコード形式やフレーム数の問題です。

回避策:

  • PNGに変換する
  • ffmpegで再エンコードする

コードのポイント

バリデーション

def validate_emoji(file_path: str) -> ValidationResult:
    # 名前のバリデーション
    if not re.match(r'^[a-z0-9_-]+$', emoji_name):
        errors.append("Invalid name")

    # 画像のバリデーション
    with Image.open(file_path) as img:
        if img.format not in {'PNG', 'JPEG', 'GIF'}:
            errors.append("Invalid format")
        if img.size[0] != img.size[1]:
            errors.append("Not square")

アップロード

def upload_emoji(self, file_path: str, emoji_name: str) -> UploadResult:
    image_data = base64.standard_b64encode(open(file_path, 'rb').read()).decode('utf-8')

    body = {
        'emojiName': f':{emoji_name}:',
        'payload': {
            'fileContent': image_data,
            'filename': Path(file_path).name,
        }
    }

    result = self.service.customEmojis().create(body=body).execute()

既存絵文字のスキップ

def list_existing_emojis(self) -> set[str]:
    existing = set()
    page_token = None

    while True:
        response = self.service.customEmojis().list(
            pageSize=100, pageToken=page_token
        ).execute()

        for emoji in response.get('customEmojis', []):
            name = emoji.get('emojiName', '').strip(':')
            existing.add(name)

        if not response.get('nextPageToken'):
            break

    return existing

まとめ

Google Chat APIを使ってSlackの絵文字を一括移行するツールを作成しました。約3,800件中3,574件(99%)の移行に成功しました。

主なハマりポイント:

  1. Chat アプリの設定が必須(アバターURL、説明)
  2. 絵文字名はコロンで囲む
  3. 予約語や特殊な名前はAPIで拒否される
  4. 一部のGIFは処理できない

このツールを使えば、大量の絵文字も効率的に移行できます。SlackからGoogle Chatへの移行を検討している方の参考になれば幸いです。

Google Chatが少しSlackぽくなります。
image.png
image.png

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?