LoginSignup
0
0

GASからDropbox APIでGmailの文面をアップロード

Last updated at Posted at 2024-05-28

この記事ではGmailに届いたメールの本文をDropboxフォルダにテキストファイルとして保存する方法をご紹介します。Google APP Script(GAS)からDropboxにアップロードする方法の情報があまり出てこなかったので、忘備録を兼ねて書くことにしました。

必要なこと

  • Google App Script(GAS)のセットアップ
  • Dropboxアプリの作成
  • PostmanからDropbox APIの「リフレッシュトークン」の取得
  • GASからDropbox APIリクエストを送る

順番に詳しく説明していきます。

Google App Script(GAS)のセットアップ

まず最初にGoogle Sheetを開きます。
Screenshot 2024-05-28 at 12.15.50 PM.png
そして、エクステンションメニューから「Apps Script」を選択します。
すると、以下の画面になりますのでプロジェクト名を「Untitled Project」から何か適当なものに変更します。
Screenshot 2024-05-28 at 12.19.31 PM.png

次に、Gmailを取得する関数を書きます。

function myFunction() {
  // Gmailからメールを取得
  const threads = GmailApp.search('in:inbox newer_than:1d');
  // 取得したメールを処理
  threads.forEach(thread => {
    const messages = thread.getMessages();
    messages.forEach(message => {
      const subject = message.getSubject(); //メール題名
      const body = message.getPlainBody(); //メール本文
      const date = Utilities.formatDate(message.getDate(), "Tokyo/Japan", "yyyy-MM-dd") //メールの送信時間

    console.log(subject, body, date) //実行ログを出力
    
    });
  });
}

Gmailの取得には「GmailApp.search」関数を使います。関数についての詳しい説明は公式ドキュメントを参照してください。この関数の引数はGmailアプリ共通のクエリ文法が使えます。(例:in:inbox label:my-label is:unread

ではここで一旦確認のために実行してみます。
右上の「Deploy(デプロイ)」ボタンを押し、「New Deployment(新規デプロイ)」を選択します。
タイプから「Web app(ウェブアプリ)」を選択し名前を適当につけて「Deploy(デプロイ)」ボタンをクリックします。
Screenshot_2024-05-28_at_12_26_08 PM.png
続いて「Authorize Access(アクセス許可する)」ボタンをクリックします。
Screenshot 2024-05-28 at 12.29.49 PM.png
画面のプロンプトに従って自分のGoogleアカウントを選択すると以下のワーニングメッセージが表示されます。
ここでは青いボタンでなく、「Advanced」オプションをクリックします。
Screenshot_2024-05-28_at_12_30_11 PM.png
さらに「Go to <アプリ名> (unsafe)」のオプションを選択します。
Screenshot_2024-05-28_at_12_30_43 PM.png
すると以下の確認画面が表示されるので「Allow(許可する)」をクリックします。
Screenshot_2024-05-28_at_12_36_51 PM.png
すると無事デプロイが行われ以下の画面が表示されるので、「Done(終了)」で画面を閉じます。
Screenshot_2024-05-28_at_12_39_04 PM.png

それでは、画面上部の「Run(実行)」ボタンをクリックしてコードを実行してみましょう。
Screenshot_2024-05-28_at_12_43_19 PM.png
画面下部のExecution Log(実行ログ)にログが表示され、メールを取得できていることが確認できます。

Dropboxアプリの作成

Dropboxの開発者ページにログインします。
アプリの作成メニューから新しくアプリの作成を行います。
Screenshot 2024-05-28 at 1.23.28 PM.png
画面に従って進むと以下のページが表示されます。

今回はPostmanを使ってリフレッシュトークン(詳しくは後述)を取得していくので、Redirect URIsにはhttps://oauth.pstmn.io/v1/browser-callbackと入力します。
あとはデフォルトのままでOKです。App keyとApp secretは後で使います。
Screenshot_2024-05-28_at_1_27_42 PM.png

数年前からDropbox APIのアクセストークンは"short-lived"(短時間でアクセス期限切れとなるトークン)のみのサポートとなりました。詳しくはこちらのページを参照してください。

このページを見ると、

We offer a long-lived refresh_token that can be used to request a new, short-lived access token.

と書かれています。つまり、長期利用可能なリフレッシュトークンを発行し、そのリフレッシュトークンを使って短時間アクセストークンを発行する流れのようです。またtoken_access_typeofflineオプションとすることで、ユーザーが再承認しなくても期限切れしないリフレッシュトークンを発行できるようです(参考)。

ちなみに上記アプリページの"Generate access token"では"Generate"ボタンから短時間アクセストークン(短時間アクセストークンはsl.から始まります)を発行可能ですが、今回は以下のステップでリフレッシュトークンを使ってAPI経由でアクセストークンを自動発行するので使いません。

  1. Postmanアプリから認証リクエスト(https://www.dropbox.com/oauth2/authorize)を送ってリフレッシュトークン(長期利用可能)を取得
  2. リフレッシュトークンを使ってトークンリクエスト(https://api.dropboxapi.com/oauth2/token)を送ってアクセストークン(short-lived)を取得
  3. アクセストークンを使ってアップロードリクエストによりファイルアップロードする。

参照:https://developers.dropbox.com/ja-jp/oauth-guide

PostmanからDropbox APIの「リフレッシュトークン」の取得

Postmanの新規リクエストを開いて「認可」タブに以下のように入力します。
クライアントIDとクライアントシークレットにはそれぞれApp keyとApp secretをDropboxのアプリコンソールからコピーします。Scopeにはアプリコンソールで追加したScopeを入力します。
Screenshot_2024-05-28_at_2_14_51 PM.png
これで、画面下の「新しいアクセストークンを取得」をクリックするとDropboxのアカウント認証画面が表示され、リフレッシュトークンを取得できます。
Screenshot 2024-05-28 at 2.18.12 PM.png
Screenshot_2024-05-28_at_2_19_28 PM.png

注意:APIキーやトークンのセキュリティは非常に重要です。PostmanのVault機能やシークレットマネージャーを利用し管理することをお勧めします。

GASからDropbox APIリクエストを送る

ここでは以下のタスクを行います。

  1. リフレッシュトークンを使ってアクセストークンを発行する
  2. メールの文面をファイルアップロードする

まず1の関数をGASに追加します。

// Dropboxのアクセストークンを発行する関数
function getDropboxAccessToken(refresh, app_id, app_secret) {

  const options = {
    "method": "post",
    "headers": {
      "Content-Type" : "application/x-www-form-urlencoded"
    },
    "payload": {
      "refresh_token": refresh,
      "grant_type": "refresh_token" ,
      "client_id": app_id,
      "client_secret": app_secret,
    },
    "muteHttpExceptions" : true
  }
  
  const response = UrlFetchApp.fetch('https://api.dropbox.com/oauth2/token', options)
  console.log(response.getResponseCode())
  console.log(response.getContentText())
  const access_token = JSON.parse(response.getContentText()).access_token

  return access_token
}

APIリクエストはUrlFetchApp.fetch関数を使います。詳しくは公式ドキュメントを参照してください。
次にファイルをアップロードする関数です。

// Dropboxにtxtファイルを保存する関数
function saveToDropbox(dest, content, access_token) {
  const uploadEndpoint = 'https://content.dropboxapi.com/2/files/upload'
  
  const dropbox_headers = {
    "Authorization" :"Bearer " + access_token,
    "Content-Type" : "application/octet-stream",
    "Dropbox-API-Arg" : "{\"path\":\"" + dest + "\",\"mode\":{\".tag\":\"overwrite\"}}"
  }
  
  const options =  {
      "method" : "post",
      "headers" : dropbox_headers,
      'payload' : content,
      "muteHttpExceptions" : true
    }
  
  const response = UrlFetchApp.fetch(uploadEndpoint, options)
  console.log(response.getResponseCode())
  console.log(response.getContentText())
  return response
}

完成したGASがこちら。

function myFunction() {
  // Gmailからメールを取得
  const threads = GmailApp.search('in:inbox newer_than:1d');

  // Dropbox アクセストークン取得
  const refresh_token = 'your_refresh_token'
  const app_id = 'your_app_id'
  const app_secret = 'your_app_secret'
  const access_token = getDropboxAccessToken(refresh_token, app_id, app_secret)

  // 取得したメールを処理
  threads.forEach(thread => {
    const messages = thread.getMessages();
    messages.forEach(message => {
      const subject = message.getSubject(); //メール題名
      const body = message.getPlainBody(); //メール本文
      const date = Utilities.formatDate(message.getDate(), "Tokyo/Japan", "yyyy-MM-dd") //メールの送信時間

      console.log(subject, body, date) //実行ログを出力

      // Dropbox APIでtxtファイルに保存
      const dest = "/" + subject + ".txt"
      const upload = saveToDropbox(dest, body, access_token)
    
    });
  });
}


// Dropboxにtxtファイルを保存する関数
function saveToDropbox(dest, content, access_token) {
  const uploadEndpoint = 'https://content.dropboxapi.com/2/files/upload'
  
  const dropbox_headers = {
    "Authorization" :"Bearer " + access_token,
    "Content-Type" : "application/octet-stream",
    "Dropbox-API-Arg" : "{\"path\":\"" + dest + "\",\"mode\":{\".tag\":\"overwrite\"}}"
  }
  
  const options =  {
      "method" : "post",
      "headers" : dropbox_headers,
      'payload' : content,
      "muteHttpExceptions" : true
    }
  
  const response = UrlFetchApp.fetch(uploadEndpoint, options)
  
  console.log(response.getResponseCode())
  console.log(response.getContentText())
  return response
}

// Dropboxのアクセストークンを再発行する関数
function getDropboxAccessToken(refresh, app_id, app_secret) {

  const options = {
    "method": "post",
    "headers": {
      "Content-Type" : "application/x-www-form-urlencoded"
    },
    "payload": {
      "refresh_token": refresh,
      "grant_type": "refresh_token" ,
      "client_id": app_id,
      "client_secret": app_secret,
    },
    "muteHttpExceptions" : true
  }
  
  const response = UrlFetchApp.fetch('https://api.dropbox.com/oauth2/token', options)
  
  console.log(response.getResponseCode())
  console.log(response.getContentText())
  
  const access_token = JSON.parse(response.getContentText()).access_token

  return access_token
}

このスクリプトを実行すると、Dropboxアプリコンソールで指定したフォルダにtxtファイルが保存されます。

おまけ

GASではトリガーを設定することで、スクリプトをスケジュール実行することができます。
詳しくはこの記事がわかりやすいです。

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