2020.04.10

RubyとGoogleドライブの連携してみる

Pocket

こんにちは。次世代システム研究室のB.Mです。

はじめに

RubyとGoogleドライブの連携について触れましたので、今回はRubyとGoogleドライブの連携方法と、その使い方について紹介します。

チームドライブについて

現在、Googleドライブを使用している方も多いと思います。
  • 個人の場合は「マイドライブ」という名前です。
  • 企業で「G Suite」を使っていると「チームドライブ」という機能が使えるようになります。
チームドライブとマイドライブの比較は:
  • 同じ:同様にファイルのアップロードやスプレッドシートの作成、メンバーとのファイル共有などできることは一緒です。
  • 違い:ファイルの所属が個人からチームに変わるので、マイドライブの場合はメンバーが退社したときにファイルを引き継ぐ必要がありましたが、チームドライブの場合はファイルを引き継ぐ必要はありません。
今回は ruby でチームドライブを扱ったので共有します。

Google API Client ライブラリーを使用してファイルとフォルダーとの操作

設定

Rubyでライブラリーを使用したい時、Gemfileにgemを追加します。Google-api-clientの場合は以下のように追加します。
gem 'google-api-client', '~> 0.34'
Ruby用のGemであるgoogle-api-clientを使います。
Google APIのバージョンはv3になります。

認証

Google APIを使用してプライベートデータにアクセスする前に、そのAPIへのアクセスを許可するアクセストークンを取得する必要があります。 1つのアクセストークンで、さまざまな程度のアクセスを複数のAPIに付与できます。

ですので、以下のように認証して初期化の方法です。
SERVICE_ACCOUNT_CREDENTIAL_FILE_PATH =  "サービスアカウントの認証用ファイル.json";
def initialize
  authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
    json_key_io: File.open(SERVICE_ACCOUNT_CREDENTIAL_FILE_PATH),
    scope: %w(
      https://www.googleapis.com/auth/drive
      https://www.googleapis.com/auth/drive.file
    )
  authorizer.fetch_access_token!
  @drive = Google::Apis::DriveV3::DriveService.new
  @drive.authorization = authorizer
end
ここでサービスアカウントとスコープは二つ概念がわかりづらいと思います。
  •  サービスアカウントは簡単にいうと以下の二行からわかると思います。
    • サービスアカウントにはパスワードがなく、ブラウザやCookieを介してログインできません。
    • サービスアカウントは、Googleへの認証に使用されるプライベート/パブリックRSAキーペアに関連付けられています。
  • Scopeと呼ばれる変数パラメーターは、アクセストークンが許可するリソースと操作のセットを制御します。 アクセストークンリクエスト中に、アプリケーションはスコープパラメータで1つ以上の値を送信します。
    • https://www.googleapis.com/auth/drive  Googleドライブファイルを表示、編集、作成、削除します。
    • https://www.googleapis.com/auth/drive.file アプリで開いた、または作成したGoogleドライブのファイルとフォルダーの表示と管理。

ファイルとの操作

アップロード

アップロードの方法です。
create_fileの関数を使用します。
  • file_object: ファイル名等を指定します。parentsキーにチームドライブのIDです。
  • supports_team_drives: リクエストするアプリケーションがチームドライブをサポートしているか指定するのでtrueにします。(警告:このアイテムは非推奨です。ですが、コードを実装した時点はまだ必要です。)
GoogleドライブのフォルダーIDとファイルIDは例えば以下のリンクの例でしたら、”ABCDE”はIDです。
https://drive.google.com/drive/u/1/folders/ABCDE
https://docs.google.com/document/d/ABCDE/edit

ファイルコピー

ファイルコピーする方法です。
copy_fileを使用します。
  def copy src_file_id, des_file_name, parent
    file_object = {
      name: des_file_name,
      parents: [parent]
    }    
    result = @drive.copy_file(src_file_id, file_object, supports_team_drives: true, supports_all_drives: true)
    result.id
  end
  • parent: 親フォルダーのIDです。
  • 返却値:コピーで生成されたファイルのIDです。

ファイル取得

ファイル取得する方法です。
get_fileを使用します。
def get_file file_id
  result = @drive.get_file(
    file_id, 
    include_team_drive_items: true, 
    supports_team_drives: true, supports_all_drives: true
  )
end
  • file_id: ファイルのIDです。
  • 返却値:ファイルオブジェクトです。

ファイル一覧

list_filesを使用して一覧取得します。
def list team_drive_id
  @service.list_files(
    corpora: 'teamDrive',
    team_drive_id: team_drive_id,
    q: "name='欲しいファイル名'",
    spaces: 'drive',
    fields: 'files(id,trashed)',
    include_team_drive_items: true,
    supports_team_drives: true)
end
  • team_drive_id: 検索するチームドライブのIDです。
  • 返却値:ファイルオブジェクトです。
  • q: クエリです。クエリの内容により取得内容が調整できます。例:q: “name=’欲しいファイル名’ and ‘folder_id’ in parents “。

ファイル削除

ファイル削除の方法です。
delete_fileを使用しなくupdate_fileを使用します。
  • file_object: ゴミ箱に移動するのでtrashedにtrueを指定します。
ファイルを完全に削除したい際、delete_fileを使用します。
ですが、注意点があります:ファイルがチームドライブに属している場合、ユーザーは親フォルダーの主催者の権限が必要です。
通常はあまり強い権限を付与しないと思いますので、完全削除ではなくゴミ箱へ移動しても良い方法と思います。

フォルダーとの操作

注:フォルダはファイルの一種として扱われます。 フォルダの詳細については、ファイルタイプをご覧ください。

ですのでフォルダーとファイルの扱うのは同じです。

例:

フォルダー作成

  def mkdirp dir_name, parent
      file_object = {
        name: dir_name,
        parents: [parent],
        mime_type: 'application/vnd.google-apps.folder'
      }
      result= @drive.create_file(
        file_object,
        supports_team_drives: true, supports_all_drives: true)
      result.id
    end
  • mime_type: ‘application/vnd.google-apps.folder’と指定したら、フォルダーが作成されます。
  • parent: 親フォルダーです。

Google-api-ruby-clientのマイグレーション

マイグレーションする時、ここが参考になります。

おまけ

Slackへ通知機能を紹介したいと思います。

例えばあるファイルをアップロードして、Slackへ通知したいなら、以下のように実装できます。

最初はSlackのgemをインストールします。


gem "slack-incoming-webhooks", "0.3.0"

実装コード:


file_id = upload(file_path)    
url = "https://docs.google.com/spreadsheets/d/#{file_id}"
message = "#新しいファイルをアップロードしました\n#{url}" 

web_hook_url = 'https://hooks.slack.com/services/AAAA/BBBB/CCCCCCCC'
slack_username = 'Slackのユーザー名'
channel = 'Slackのチャネル'
slack = Slack::Incoming::Webhooks.new web_hook_url, username: slack_username, channel: channel
slack.post message
  • slack.postを実行したら指定されたチャネルに設定したmessageを通知します。

最後に

今回はRubyとGoogleドライブの連携について紹介しました。
RubyでGoogle APIを使い、チームドライブの操作を行って、Slackへ通知するようにしました。

初めてRubyでGoogle APIを使用するのは困難だと思いますので、初心者向けの記事ですが、もしお役に立てれば幸いです。

参考リンク

最後に、次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。アプリケーション開発の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。

皆さんのご応募をお待ちしています。