カテゴリー: 業務効率化

  • NotionとGASを連携して日報を自動生成する

    NotionのデータベースとGoogle Apps Scriptを組み合わせることで、毎日の日報作成を完全自動化できます。

    「毎日の日報作成に時間がかかる」「書き忘れが多い」という悩みは、多くのビジネスパーソンに共通しています。Notionは情報管理ツールとして優秀ですが、単体では自動化に限界があります。そこでGoogle Apps Script(GAS)と連携させることで、Notionのデータを自動で集計し、日報を自動生成・送信する仕組みを構築できます。

    本記事では、Notion APIとGASを使って「Notionのタスクデータベースから当日の完了タスクを自動収集し、日報メールを自動送信する」システムを一から作る手順を解説します。プログラミング初心者でも手順通りに進めれば実装できるよう、詳しく説明します。

    この記事でできること

    • Notion APIを使ってデータベースのデータをGASで取得する
    • 毎日決まった時刻に日報を自動生成する
    • 完成した日報をメールで自動送信する
    • 日報内容をNotionに自動で記録・保存する

    事前準備

    以下のものが必要です。作業開始前に揃えておきましょう。

    • Notionアカウント(無料プランでOK)
    • Googleアカウント(GASを使用)
    • Notionのタスク管理データベース(プロパティ:タスク名、担当者、完了フラグ、日付)

    STEP1: Notion APIキーを取得する

    まずNotionとGASを連携させるためのAPIキーを取得します。

    1. Notionにログインし、notion.so/my-integrationsにアクセスします
    2. 「新しいインテグレーション」をクリックし、名前(例:GAS日報Bot)を入力します
    3. 「送信」をクリックするとInternal Integration Tokenが発行されます
    4. このトークン(secret_xxxx…形式)をコピーして保存します

    次に、連携したいNotionデータベースを開き、右上の「…」メニューから「接続」→作成したインテグレーションを選択して権限を付与します。データベースのURLに含まれる32文字の英数字がデータベースIDです。このIDも控えておきます。

    STEP2: GASのスクリプトを作成する

    Google Driveにアクセスし、「新規」から「Google Apps Script」を選択してプロジェクトを作成します。スクリプトエディタで以下の内容を入力します。まず設定項目として、NOTIONトークン、データベースID、送信先メール、氏名を定数として定義します。

    メイン関数generateDailyReport()では、今日の日付をyyyy-MM-dd形式で取得し、fetchNotionTasks()でタスク一覧を取得します。タスクがあればcreateReportBody()で日報テキストを作成し、sendReportEmail()でメール送信します。

    fetchNotionTasks()ではNotionのデータベースクエリAPIを呼び出します。filterにより完了フラグがtrueかつ本日の日付のタスクだけを絞り込みます。レスポンスのresults配列からタスク名とカテゴリを抽出して返します。

    createReportBody()では日報のテキストを組み立てます。日付・担当者・完了タスク一覧・所感欄をテンプレートに従って結合します。sendReportEmail()ではGmailAppのsendEmail()を使ってメール送信します。

    STEP3: 設定値を書き換える

    コードの上部にある設定項目を自分の環境に合わせて書き換えます。

    • NOTION_TOKEN: STEP1で取得したIntegration Tokenに置き換え
    • DATABASE_ID: STEP1で控えたデータベースIDに置き換え
    • REPORT_EMAIL: 日報の送信先メールアドレスに変更
    • YOUR_NAME: 自分の名前に変更

    Notionデータベースのプロパティ名がコードと一致しているか確認してください。チェックボックスのプロパティ名が「完了」であれば、コード内の「完了フラグ」を「完了」に変更します。

    STEP4: 動作テストをする

    実際にスクリプトを実行してテストします。

    1. GASエディタの上部にある関数選択プルダウンでgenerateDailyReportを選択します
    2. 「実行」ボタンをクリックします
    3. 初回実行時はGoogleアカウントの権限承認画面が表示されます。「許可」をクリックします
    4. 実行ログに「日報送信完了」が表示されれば成功です
    5. 指定したメールアドレスに日報メールが届いていることを確認します

    うまく動作したら、次のSTEPで毎日自動実行する設定をします。

    STEP5: 毎日自動実行のトリガーを設定する

    GASには「トリガー」という自動実行機能があります。これを設定することで、毎日決まった時刻に日報が自動送信されるようになります。

    1. GASエディタの左メニューから「トリガー」(時計アイコン)をクリックします
    2. 右下の「トリガーを追加」ボタンをクリックします
    3. 実行する関数にgenerateDailyReportを選択、イベントのソースを時間主導型、日付ベースのタイマーで17時〜18時に設定します
    4. 「保存」をクリックして完了です

    これで毎日17〜18時の間に自動で日報が送信されます。

    うまくいかないときのチェックリスト

    • APIトークンエラー: Notionのインテグレーションが正しく作成されているか、トークンをコピーし直してみる
    • タスクが0件になる: Notionデータベースのプロパティ名がコードと一致しているか確認。日付フォーマットがyyyy-MM-dd形式になっているか確認
    • メールが届かない: REPORT_EMAILに正しいアドレスが設定されているか確認
    • 権限エラー: Notionデータベースに対してインテグレーションのアクセス権が付与されているか確認
    • トリガーが動かない: GASプロジェクトがスタンドアロン型になっているか確認

    応用・発展

    基本的な日報自動化ができたら、さらに発展させることができます。

    • Slack通知に変更する: メールの代わりにSlack Incoming Webhookを使い、UrlFetchApp.fetch()でSlackに送信できます
    • 日報をNotionに記録する: Notion APIのpages.createエンドポイントを使い、生成した日報を別のNotionページとして自動保存できます
    • 週次サマリーを作る: トリガーを週ベースに設定し、1週間分のタスクをまとめた週次報告書を自動生成できます
    • ChatGPT APIと組み合わせる: タスクリストをChatGPT APIに送り、振り返りコメントを自動生成して日報に追加できます

    まとめ

    • Notion APIとGASを連携させることで、日報作成を完全自動化できる
    • Notion Integrationを作成してAPIトークンを取得し、GASからデータを取得する
    • GASのトリガー機能で毎日決まった時刻に自動実行できる
    • Slack通知やNotion記録など、応用範囲は広い
    • 日報の書き忘れゼロ・作成時間ゼロを実現し、本来の業務に集中できる
  • Googleフォーム×GASで申込フォームを自動処理する方法

    Googleフォーム×GASで申込フォームを自動処理する方法

    Googleフォームに申込みが届いたら、自動で確認メールを送り、スプレッドシートに整理し、Slackに通知まで届く仕組みをGASで構築する手順を解説します。

    申込フォームへの対応は、多くの企業で手動作業が残っている業務の一つです。「フォームに回答が来たらメールを確認して、スプレッドシートに転記して、担当者にSlackで連絡する」という流れを毎回手動でやっていませんか?

    Google Apps Script(GAS)を使えば、この一連の流れをすべて自動化できます。Googleフォームのトリガー機能とGASを組み合わせることで、回答が届いた瞬間に確認メール送信・データ整理・通知まで完了する仕組みが、無料で作れます。

    この記事でできること

    • Googleフォームへの回答を自動でスプレッドシートに整理する
    • 申込者に自動確認メールを送信する
    • 担当者のSlackチャンネルに申込通知を自動送信する
    • フォーム回答をトリガーにGASを自動実行する

    事前準備

    以下のものを用意してください:

    • Googleアカウント(Gmailが使えるもの)
    • Googleフォーム(申込フォームを作成済みであること)
    • 回答を記録するGoogleスプレッドシート(フォームにリンク済みが望ましい)
    • Slack Incoming WebhookのURL(Slack通知を使う場合)

    SlackのWebhook URLは、Slack APIページでアプリを作成し「Incoming Webhooks」を有効化することで取得できます。取得したURLは後で使います。

    STEP1: GASエディタを開く

    Googleフォームを開き、上部メニューの「その他」(点3つのアイコン)から「スクリプトエディタ」を選択します。これでフォームに紐づいたGASプロジェクトが開きます。

    または、フォームに回答を集めているスプレッドシートを開き、メニューの「拡張機能」→「Apps Script」からエディタを開いても構いません。どちらの方法でも動作します。

    エディタが開いたら、デフォルトで書かれているコードを削除して、次のSTEPで作成するコードを貼り付けます。

    STEP2: フォーム回答処理のメイン関数を書く

    以下のコードをエディタに貼り付けます。

    // 設定値(自分の環境に合わせて変更)
    const SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/XXXX/YYYY/ZZZZ';
    const NOTIFY_EMAIL = 'admin@example.com'; // 管理者通知先
    
    function onFormSubmit(e) {
      const responses = e.response.getItemResponses();
      
      // 回答データを取得
      const data = {};
      responses.forEach(function(item) {
        data[item.getItem().getTitle()] = item.getResponse();
      });
      
      const applicantEmail = data['メールアドレス'] || '';
      const applicantName = data['お名前'] || '申込者';
      
      // 1. 申込者に確認メールを送信
      sendConfirmEmail(applicantEmail, applicantName, data);
      
      // 2. 管理者に通知メールを送信
      sendAdminEmail(applicantName, data);
      
      // 3. Slackに通知
      sendSlackNotification(applicantName, applicantEmail, data);
      
      Logger.log('処理完了: ' + applicantName);
    }
    

    「メールアドレス」「お名前」の部分は、実際のフォームの質問文に合わせて変更してください。フォームの質問タイトルと完全に一致している必要があります。

    STEP3: 確認メール・通知メール送信関数を書く

    メイン関数の下に、以下の関数を追記します。

    function sendConfirmEmail(toEmail, name, data) {
      if (!toEmail) return;
      
      const subject = '【受付完了】お申込みありがとうございます';
      const body = name + ' 様
    
    この度はお申込みいただきありがとうございます。
    以下の内容で受け付けました。
    
    ---
    ' +
        Object.entries(data).map(function(e) { return e[0] + ': ' + e[1]; }).join('
    ') +
        '
    ---
    
    担当者より3営業日以内にご連絡いたします。
    引き続きよろしくお願いいたします。';
      
      GmailApp.sendEmail(toEmail, subject, body);
    }
    
    function sendAdminEmail(name, data) {
      const subject = '【新規申込】' + name + ' 様';
      const body = '新しい申込がありました。
    
    ' +
        Object.entries(data).map(function(e) { return e[0] + ': ' + e[1]; }).join('
    ');
      
      GmailApp.sendEmail(NOTIFY_EMAIL, subject, body);
    }
    

    STEP4: Slack通知関数を書く

    続けて、Slack通知用の関数も追記します。

    function sendSlackNotification(name, email, data) {
      if (!SLACK_WEBHOOK_URL || SLACK_WEBHOOK_URL.includes('XXXX')) return;
      
      const details = Object.entries(data)
        .map(function(e) { return '- ' + e[0] + ': ' + e[1]; })
        .join('
    ');
      
      const message = {
        text: '新規申込がありました',
        attachments: [{
          color: '#36a64f',
          title: '申込者: ' + name + ' (' + email + ')',
          text: details
        }]
      };
      
      const options = {
        method: 'post',
        contentType: 'application/json',
        payload: JSON.stringify(message),
        muteHttpExceptions: true
      };
      
      UrlFetchApp.fetch(SLACK_WEBHOOK_URL, options);
    }
    

    STEP5: トリガーを設定して自動実行にする

    コードを保存したら、GASのトリガーを設定します。

    1. エディタ左側のメニューから「トリガー」(時計アイコン)をクリック
    2. 右下の「トリガーを追加」をクリック
    3. 以下の設定を選択:
      • 実行する関数: onFormSubmit
      • イベントのソース: フォームから
      • イベントの種類: フォーム送信時
    4. 「保存」をクリックし、権限の確認画面でGoogleアカウントを選択して許可する

    これでフォームに回答が届くたびに onFormSubmit 関数が自動実行されます。トリガー設定後、テスト用の回答を送信して動作を確認しましょう。

    うまくいかないときのチェックリスト

    • メールが届かない: フォームの質問タイトルとコード内の文字列が完全に一致しているか確認(全角スペースも含む)
    • 権限エラーが出る: GASのトリガー設定時に出る権限確認でGmailとフォームへのアクセスを許可したか確認
    • Slack通知が来ない: SLACK_WEBHOOK_URLが正しく設定されているか、Slack側でWebhookが有効になっているか確認
    • 1日100件以上の申込がある: GASのGmail送信には1日あたり100件(無料アカウント)の制限があります。Google Workspaceなら1,500件まで対応
    • トリガーが実行されない: スクリプトエディタではなくフォームまたはスプレッドシートのスクリプトとしてトリガーを設定しているか確認

    応用・発展

    基本の自動処理が動いたら、以下の拡張も検討できます:

    • スプレッドシートへの自動転記と色付け: 申込内容をスプレッドシートの特定シートに転記し、新規申込行を黄色にハイライトする
    • Googleカレンダーへの自動登録: セミナー申込などの場合、申込者の名前と日程をカレンダーに自動登録できる
    • 回答内容によって送信先を切り替える: 「問い合わせ種別」の回答に応じて、担当部署ごとに異なるメールアドレスへ通知を分岐させる
    • Notionデータベースへの自動追加: Notion APIと組み合わせて、申込情報をNotionの顧客管理データベースに自動追加する

    まとめ

    • GASのフォーム送信トリガーを使えば、申込フォームの対応を完全自動化できる
    • 申込者への確認メール・管理者通知・Slack通知が1つのスクリプトで同時に実行される
    • フォームの質問タイトルとコードの文字列を一致させることが動作の鍵
    • GASは無料で使えるため、初期コストゼロで業務自動化を始められる
    • 一度設定すれば、以降は完全に自動で動き続け、手動対応の工数をゼロにできる
  • GASでPDFを自動生成してメール送付する仕組みを作る方法

    GASでPDFを自動生成してメール送付する仕組みを作る方法

    Google Apps Script(GAS)を使えば、スプレッドシートのデータからPDFを自動生成し、指定のアドレスへ自動メール送信する仕組みをゼロコストで構築できます。

    「毎月末に請求書を手作業でPDF化してメールしている」「見積書をいちいちダウンロードして添付するのが面倒」といった業務は、GASで完全自動化できます。Googleドライブ上のスプレッドシートやドキュメントをPDF変換して添付メール送信するスクリプトを一度作ってしまえば、ボタン一つ・あるいはスケジュール実行で完結します。

    本記事では、スプレッドシートの内容をPDF化してGmailで送付するまでの具体的な手順をステップ形式で解説します。GASの基本的な操作経験があれば、30〜60分で動くものが作れます。

    この記事でできること

    • GASからスプレッドシートをPDF形式に変換してドライブに保存
    • 生成したPDFをGmailの添付ファイルとして自動送信
    • 送信先・件名・本文をスプレッドシートのセルで管理する構成
    • 月次・週次などのスケジュール実行で完全自動化

    事前準備

    以下のものを用意してください。

    • Googleアカウント(GmailとDriveが使えること)
    • PDF化したい内容を入力したGoogleスプレッドシート(例:請求書テンプレート)
    • GASエディタへのアクセス(スプレッドシートのメニューから「拡張機能」→「Apps Script」で開く)

    スプレッドシートには「送信先メールアドレス」「件名」「本文」をセルに入力しておくと、スクリプト側で参照できて柔軟に使えます。今回は A1:メールアドレス、A2:件名、A3:本文 のシンプルな構成で進めます。

    STEP1: スプレッドシートのIDを確認する

    GASでスプレッドシートをPDF化するには、対象ファイルのIDが必要です。スプレッドシートのURLの /d/ 以降の長い文字列がファイルIDです。GASスクリプトはそのスプレッドシートと紐付いて動くため、SpreadsheetApp.getActiveSpreadsheet().getId() で自動取得できます。

    STEP2: GASでPDF変換とメール送信のスクリプトを書く

    GASエディタを開き、以下のスクリプトを貼り付けてください。DriveApp の getAs メソッドを使うと、スプレッドシートをPDFとして取得できます。

    function generateAndSendPDF() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName('Sheet1');
    
      // 送信情報をシートから取得
      var toEmail = sheet.getRange('A1').getValue();
      var subject = sheet.getRange('A2').getValue();
      var body    = sheet.getRange('A3').getValue();
    
      // DriveAppでPDF形式に変換する
      var ssFile  = DriveApp.getFileById(ss.getId());
      var pdfBlob = ssFile.getAs(MimeType.PDF).setName(subject + '.pdf');
    
      // Gmailで添付送信
      GmailApp.sendEmail(toEmail, subject, body, {
        attachments: [pdfBlob]
      });
      Logger.log('送信完了: ' + toEmail);
    }

    スクリプトを保存したら「実行」ボタンで動作確認します。初回はGmail・DriveへのPermissionが求められるので「許可」してください。

    STEP3: スプレッドシートに送信情報を入力する

    Sheet1 の A1〜A3 に以下のように入力してください。

    A1: recipient@example.com
    A2: 【5月分】請求書送付のご案内
    A3: お世話になっております。5月分の請求書をPDFにてお送りします。ご確認ください。

    スプレッドシートの他の部分(B列以降)に請求書データを入力しておくと、そのシート全体がPDFになります。印刷範囲を設定しておくと余白のない綺麗なPDFになります。

    STEP4: 複数の取引先に一括送信する

    複数取引先に一括送信したい場合は、「送信リスト」シートを別に用意して繰り返し処理にします。「送信リスト」シートには1行目をヘッダー(メール・件名・本文)として、2行目以降に各取引先の情報を入力します。スクリプトはリストを上から読み込み、1件ずつPDFを生成して送信します。連続送信によるレート制限を避けるため、送信間に Utilities.sleep() で待機時間を入れることを推奨します。

    ループ処理の骨格は以下のとおりです。PDF生成とメール送信の部分はSTEP2のコードと同じロジックをそのまま使えます。

    function sendBulkPDF() {
      var ss        = SpreadsheetApp.getActiveSpreadsheet();
      var listSheet = ss.getSheetByName('送信リスト');
      var lastRow   = listSheet.getLastRow();
    
      for (var i = 2; i <= lastRow; i++) {
        var toEmail = listSheet.getRange(i, 1).getValue();
        var subject = listSheet.getRange(i, 2).getValue();
        var body    = listSheet.getRange(i, 3).getValue();
    
        // PDF生成とメール送信はSTEP2と同じロジックを記述
        // ...
    
        Utilities.sleep(1500); // 連続送信間の待機(ミリ秒)
      }
      Logger.log('一括送信完了');
    }

    STEP5: スケジュール実行で月末に自動送信する

    手動実行ではなく月末や特定日時に自動送信するにはトリガーを設定します。GASエディタ左メニューの「トリガー(時計アイコン)」をクリックし、「トリガーを追加」→ 関数を「generateAndSendPDF」に設定→ イベントのソース:「時間主導型」、タイプ:「月タイマー」→ 日と時刻を設定して「保存」します。これで毎月指定日の指定時刻に自動実行されます。

    うまくいかないときのチェックリスト

    • 「Authorization error」→ スクリプトのPermissionを再度許可。GASエディタの「実行」→「権限を確認」から再認証
    • PDFが空白・崩れる → スプレッドシートの印刷範囲を設定しているか確認。「ファイル」→「印刷」でプレビュー確認
    • メールが届かない → toEmailの値が正しいか、A1セルをLogger.logで出力して確認
    • 「Service invoked too many times」→ sleep値を増やすか、処理を分割して実行する
    • PDFサイズが大きい → 画像や未使用シートを削除してからPDF化するとサイズを抑えられる

    応用・発展

    • Googleドキュメント版:DocumentApp.openById()で取得したドキュメントも同様にMimeType.PDFでBlob化できます
    • DriveへのPDF保存:DriveApp.createFile(pdfBlob) で送信前にDriveへバックアップ保存する運用も可能です
    • フォームと組み合わせる:Googleフォーム送信をトリガーにして、回答内容をPDFにして即時返信するシステムも構築できます
    • Slackへの通知:送信完了後にSlackのWebhookでチャンネルに通知を飛ばすと、チーム全体で送信状況を把握できます

    まとめ

    • DriveApp.getFileById(ssId).getAs(MimeType.PDF) でスプレッドシートをPDF化できる
    • GmailApp.sendEmail の attachments オプションで添付ファイル付きメール送信が可能
    • 送信情報(宛先・件名・本文)をシートのセルで管理することで、スクリプト変更なしに運用できる
    • 月末の自動実行はトリガー設定で「月タイマー」を使う
    • 一括送信・Docs対応・Drive保存などに応用すれば、社内の帳票業務を大幅に効率化できる
  • kintoneとGASを連携させる方法【API連携入門】

    kintoneとGASを連携させる方法【API連携入門】

    kintoneに蓄積したデータをGASで自動処理する仕組みを、APIキーの取得から実装まで最短ステップで解説します。

    kintoneはサイボウズが提供するノーコード業務アプリプラットフォームです。カスタマイズ性が高く、多くの中小企業で顧客管理・案件管理・日報管理などに活用されています。しかし「kintoneのデータをスプレッドシートで分析したい」「kintoneに登録があったらSlackに通知したい」といったニーズに対応するには、外部ツールとの連携が必要になります。

    そこで登場するのがGoogle Apps Script(GAS)です。GASはGoogleのサーバーで動作する無料のスクリプト環境で、kintone REST APIを呼び出すことができます。本記事ではkintoneとGASを連携させる基本手順を、初心者でも再現できるようにコード例つきで紹介します。

    この記事でできること

    • kintone REST APIの基本的な仕組みを理解する
    • GASからkintoneのレコードを取得してスプレッドシートに書き出す
    • GASからkintoneにレコードを新規登録する
    • kintoneのWebhookとGASを組み合わせてリアルタイム通知を実現する

    事前準備

    作業を始める前に以下を用意しておいてください。

    • kintoneの環境: サブドメイン(例: yourcompany.cybozu.com)とログイン情報
    • APIトークンの発行: kintoneアプリの設定画面 →「APIトークン」→「生成」でトークンを作成します。レコードの取得には「レコード閲覧」、登録には「レコード追加」の権限が必要です
    • アプリIDの確認: kintoneアプリのURLに含まれる数字(例: /k/123/ なら123がアプリID)
    • Googleアカウント: スプレッドシートとGASを利用するために必要

    STEP1: GASプロジェクトを作成する

    Googleスプレッドシートを新規作成し、メニューから「拡張機能」→「Apps Script」を開きます。エディタが表示されたら、デフォルトの myFunction を削除して、以下のコードを貼り付ける準備をします。

    まず、kintoneの接続情報をスクリプトプロパティに保存しておくと安全です。エディタ左側の「プロジェクトの設定」→「スクリプト プロパティ」に以下を登録してください。

    • KINTONE_SUBDOMAIN: yourcompany(.cybozu.com の前の部分)
    • KINTONE_APP_ID: 123(アプリID)
    • KINTONE_API_TOKEN: 発行したAPIトークン文字列

    STEP2: kintoneからレコードを取得してスプレッドシートに書き出す

    以下のコードをGASエディタに貼り付けます。kintone REST APIの records エンドポイントにGETリクエストを送り、取得したデータをスプレッドシートに書き出します。フィールドコード一覧をヘッダー行として出力し、各レコードの値を行として追記します。

    function fetchKintoneRecords() {
      const props = PropertiesService.getScriptProperties();
      const subdomain = props.getProperty('KINTONE_SUBDOMAIN');
      const appId = props.getProperty('KINTONE_APP_ID');
      const apiToken = props.getProperty('KINTONE_API_TOKEN');
    
      const baseUrl = 'https://' + subdomain + '.cybozu.com/k/v1/records.json';
      const query = 'app=' + appId + '&query=limit 100';
      const url = baseUrl + '?' + query;
    
      const options = {
        method: 'GET',
        headers: {
          'X-Cybozu-API-Token': apiToken,
          'Content-Type': 'application/json'
        },
        muteHttpExceptions: true
      };
    
      const response = UrlFetchApp.fetch(url, options);
      const data = JSON.parse(response.getContentText());
    
      if (!data.records || data.records.length === 0) {
        Logger.log('レコードが見つかりません');
        return;
      }
    
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      sheet.clearContents();
    
      const firstRecord = data.records[0];
      const fieldCodes = Object.keys(firstRecord);
      sheet.appendRow(fieldCodes);
    
      data.records.forEach(function(record) {
        const row = fieldCodes.map(function(code) {
          const field = record[code];
          return field ? field.value : '';
        });
        sheet.appendRow(row);
      });
    
      Logger.log(data.records.length + '件のレコードを書き出しました');
    }
    

    コードを保存して「fetchKintoneRecords」を実行すると、kintoneのレコードがスプレッドシートに書き出されます。初回実行時はGoogleアカウントへのアクセス許可を求めるダイアログが表示されるので「許可」をクリックしてください。

    STEP3: GASからkintoneにレコードを新規登録する

    次は逆方向の連携です。GASからkintone REST APIの record エンドポイントにPOSTリクエストを送り、新規レコードを登録します。以下の例では「会社名」「担当者名」「メモ」の3フィールドを持つアプリを想定しています。フィールドコードは実際のアプリに合わせて変更してください。

    function addKintoneRecord() {
      const props = PropertiesService.getScriptProperties();
      const subdomain = props.getProperty('KINTONE_SUBDOMAIN');
      const appId = props.getProperty('KINTONE_APP_ID');
      const apiToken = props.getProperty('KINTONE_API_TOKEN');
    
      const url = 'https://' + subdomain + '.cybozu.com/k/v1/record.json';
    
      const payload = {
        app: appId,
        record: {
          '会社名': { value: '株式会社サンプル' },
          '担当者名': { value: '田中 太郎' },
          'メモ': { value: 'GASから自動登録したレコードです' }
        }
      };
    
      const options = {
        method: 'POST',
        headers: {
          'X-Cybozu-API-Token': apiToken,
          'Content-Type': 'application/json'
        },
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      };
    
      const response = UrlFetchApp.fetch(url, options);
      const result = JSON.parse(response.getContentText());
    
      if (result.id) {
        Logger.log('レコード登録成功 ID: ' + result.id);
      } else {
        Logger.log('エラー: ' + response.getContentText());
      }
    }
    

    STEP4: kintone WebhookとGASを連携してSlack通知する

    kintoneにはWebhook機能があり、レコードの追加・更新・削除のタイミングで外部URLにPOSTリクエストを送ることができます。GASのウェブアプリを受け口にすれば、kintoneの変更をリアルタイムで検知して処理できます。まずGASにWebhookを受け取る doPost 関数を実装します。

    function doPost(e) {
      const body = JSON.parse(e.postData.contents);
      const record = body.record;
      const appName = body.app.name;
    
      const companyName = record['会社名'] ? record['会社名'].value : '(不明)';
      const message = 'kintone[' + appName + ']に新しいレコードが追加されました
    会社名: ' + companyName;
    
      const slackUrl = PropertiesService.getScriptProperties().getProperty('SLACK_WEBHOOK_URL');
    
      UrlFetchApp.fetch(slackUrl, {
        method: 'POST',
        contentType: 'application/json',
        payload: JSON.stringify({ text: message })
      });
    
      return ContentService.createTextOutput('OK');
    }
    

    このスクリプトをウェブアプリとしてデプロイし(「デプロイ」→「新しいデプロイ」→種類:「ウェブアプリ」、アクセスできるユーザー:「全員」)、発行されたURLをkintoneのWebhook設定画面に貼り付ければ連携完了です。

    STEP5: 複数レコードをまとめて更新する

    kintone REST APIには複数レコードを一括更新するエンドポイント(PUTメソッド)もあります。スプレッドシートで編集した内容をkintoneに反映するといった双方向同期にも応用できます。対象レコードのIDとフィールド値の配列を指定してリクエストします。

    function updateKintoneRecords() {
      const props = PropertiesService.getScriptProperties();
      const subdomain = props.getProperty('KINTONE_SUBDOMAIN');
      const appId = props.getProperty('KINTONE_APP_ID');
      const apiToken = props.getProperty('KINTONE_API_TOKEN');
    
      const url = 'https://' + subdomain + '.cybozu.com/k/v1/records.json';
    
      const records = [
        { id: '1', record: { 'ステータス': { value: '完了' } } },
        { id: '2', record: { 'ステータス': { value: '対応中' } } }
      ];
    
      const options = {
        method: 'PUT',
        headers: {
          'X-Cybozu-API-Token': apiToken,
          'Content-Type': 'application/json'
        },
        payload: JSON.stringify({ app: appId, records: records }),
        muteHttpExceptions: true
      };
    
      const response = UrlFetchApp.fetch(url, options);
      Logger.log(response.getContentText());
    }
    

    うまくいかないときのチェックリスト

    • APIトークンの権限が不足している: 取得には「レコード閲覧」、登録には「レコード追加」、更新には「レコード編集」の権限が必要です。kintone側のトークン設定を再確認してください
    • フィールドコードが間違っている: kintoneのフィールドコードは「表示名」ではなく「フィールドコード」を使います。アプリの設定画面で確認してください
    • クエリ構文のエラー: queryパラメータのkintoneクエリ構文が間違っているとエラーになります。まずは「limit 10」だけで動作確認しましょう
    • ウェブアプリのアクセス権限: Webhookを受け取るウェブアプリは「全員(匿名ユーザーを含む)」でアクセス許可しないとkintoneからのPOSTを受け取れません
    • GASの実行制限: 無料のGoogleアカウントでは1日の実行時間に上限(6時間)があります。大量データを扱う場合は分割処理を検討してください

    応用・発展

    kintoneとGASの連携をマスターすると、業務の幅が大きく広がります。例えば「スプレッドシートで集計した売上データを毎朝kintoneに自動登録する」「kintoneの問い合わせレコードをGASで解析してGmailで自動返信する」「kintoneとGoogleカレンダーをGASで同期して予定管理を一元化する」といった高度な自動化も実現できます。また、kintone側のプラグインやJavaScriptカスタマイズと組み合わせることで、ボタンクリックでGASを呼び出す双方向の連携も可能です。

    まとめ

    • kintone REST APIはAPIトークン認証でGASから簡単に呼び出せる
    • GETでレコード取得、POSTで新規登録、PUTで更新と、HTTPメソッドで操作を使い分ける
    • APIトークンはスクリプトプロパティに保存してコードに直書きしない
    • kintoneのWebhookとGASのウェブアプリを組み合わせるとリアルタイム処理が実現できる
    • スプレッドシートとの双方向同期や外部サービス(Slack・Gmail)への通知など、GASが仲介役になって業務自動化の幅が大きく広がる
  • GASでSlack通知を自動化する基本パターン

    GASでSlack通知を自動化する基本パターン

    Google Apps Script(GAS)とSlackを連携させることで、スプレッドシートの更新やフォームの送信を自動でSlackに通知できます。

    Slackはビジネスの情報共有ツールとして広く使われていますが、手動での通知作業は意外と手間がかかります。締め切りが近いタスクを毎日チャンネルに書き込む、新しい依頼が来るたびに担当者にメンションする――こういった繰り返し作業はGASで自動化できます。

    この記事では、GASからSlackにメッセージを送る基本パターンから、スプレッドシートのデータを定期通知する応用例まで、実際に動くコードで解説します。Incoming Webhookを使うので、Slack APIの深い知識は不要です。

    この記事でできること

    • GASからSlackの指定チャンネルにメッセージを送信する
    • スプレッドシートの内容を毎朝自動でSlackに通知する
    • フォーム送信時にリアルタイムでSlack通知を飛ばす
    • メンション(@channel、@here、個人)を含んだ通知を送る

    事前準備

    SlackのIncoming Webhookを有効にする必要があります。Slackの管理画面から「アプリを管理」→「カスタムインテグレーション」→「Incoming Webhook」を開き、通知を送りたいチャンネルを選んでWebhook URLを発行してください。URLは「https://hooks.slack.com/services/」で始まる文字列です。このURLは外部に漏らさないよう注意してください。

    GAS側の準備はとくに不要です。Googleアカウントがあれば、スクリプトエディタを開くだけで始められます。

    STEP1: 基本のSlack送信関数を作る

    まずはGASからSlackにメッセージを送る最小構成のコードです。スクリプトエディタ(script.google.com)を開いて、以下のコードを貼り付けてください。

    function sendSlackMessage(message) {
      const WEBHOOK_URL = "https://hooks.slack.com/services/XXXXX/YYYYY/ZZZZZ";
    
      const payload = {
        text: message
      };
    
      const options = {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload)
      };
    
      UrlFetchApp.fetch(WEBHOOK_URL, options);
    }
    
    function testSend() {
      sendSlackMessage("GASからのテストメッセージです!");
    }

    WEBHOOK_URLを自分のものに書き換えてから、testSend関数を実行してください。Slackの指定チャンネルにメッセージが届けば成功です。初回実行時は「外部サービスへのアクセスを許可しますか?」という確認ダイアログが表示されるので、「許可」をクリックしてください。

    STEP2: スプレッドシートのデータを通知する

    次に、スプレッドシートの内容を読み取ってSlackに送信する関数を作ります。例として、タスク管理シートの「期限が今日のタスク」を朝に通知する仕組みを作ります。A列:タスク名、B列:担当者、C列:期限 の構成を想定しています。

    function notifyTodayTasks() {
      const WEBHOOK_URL = "https://hooks.slack.com/services/XXXXX/YYYYY/ZZZZZ";
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("タスク");
      const today = Utilities.formatDate(new Date(), "Asia/Tokyo", "yyyy/MM/dd");
    
      const data = sheet.getDataRange().getValues();
      const todayTasks = [];
    
      for (let i = 1; i < data.length; i++) {
        const taskName = data[i][0];
        const assignee = data[i][1];
        const dueDate = Utilities.formatDate(new Date(data[i][2]), "Asia/Tokyo", "yyyy/MM/dd");
    
        if (dueDate === today && taskName !== "") {
          todayTasks.push("・" + taskName + "(担当: " + assignee + ")");
        }
      }
    
      if (todayTasks.length === 0) {
        return;
      }
    
      const message = "*本日締め切りのタスク(" + today + ")*
    " + todayTasks.join("
    ");
      const payload = { text: message };
      const options = {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload)
      };
    
      UrlFetchApp.fetch(WEBHOOK_URL, options);
    }

    シート名やカラム順は実際のスプレッドシートに合わせて変更してください。

    STEP3: 毎朝自動実行するトリガーを設定する

    GASのトリガー機能を使って、毎朝決まった時間に自動通知する設定にします。スクリプトエディタの左メニューから「トリガー」(時計のアイコン)をクリックし、「トリガーを追加」ボタンを押してください。

    設定内容は以下の通りです。

    • 実行する関数: notifyTodayTasks
    • イベントのソース: 時間主導型
    • 時間ベースのトリガーのタイプ: 日付ベースのタイマー
    • 時刻: 午前8時〜9時(業務開始前を選ぶ)

    これで毎朝8〜9時の間に自動的にnotifyTodayTasks関数が実行され、当日締め切りのタスクがSlackに通知されます。

    STEP4: フォーム送信時にリアルタイム通知する

    Googleフォームと連携させると、フォームが送信されるたびにリアルタイムでSlack通知を飛ばせます。フォームに紐付いたスプレッドシートのスクリプトエディタに、以下のコードを追加します。

    function onFormSubmit(e) {
      const WEBHOOK_URL = "https://hooks.slack.com/services/XXXXX/YYYYY/ZZZZZ";
    
      const responses = e.values;
      const timestamp = responses[0];
      const name = responses[1];
      const content = responses[2];
    
      const message = "*新しいフォーム送信がありました*
    " +
        "受付時刻: " + timestamp + "
    " +
        "名前: " + name + "
    " +
        "内容: " + content;
    
      const payload = {
        text: message,
        username: "フォーム通知Bot",
        icon_emoji: ":mailbox_with_mail:"
      };
    
      const options = {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload)
      };
    
      UrlFetchApp.fetch(WEBHOOK_URL, options);
    }

    このコードを保存したあと、トリガーを追加します。今度は「フォーム送信時」のトリガーを選択し、関数にonFormSubmitを指定してください。フォームが送信されるたびにSlackに通知が届くようになります。

    STEP5: メンションを入れた通知を送る

    特定の人や全員にメンションしたい場合は、メッセージテキストに特定の文字列を含めます。

    // @channel(チャンネル全員に通知)
    const message = "緊急連絡です!本日16時からミーティングがあります。";
    // Slackでは <!channel> と記述することでチャンネル全員に通知
    
    // @here(現在オンラインのメンバーに通知)
    // Slackでは <!here> と記述することでオンラインメンバーに通知
    
    // 個人へのメンション(メンバーIDが必要)
    const userId = "U01XXXXXXXX";
    // Slackでは <@メンバーID> の形式で個人メンションが可能

    個人のメンバーIDはSlackのプロフィール画面から確認できます。プロフィールの「…」メニューから「メンバーIDをコピー」を選択してください。実際のコードでは変数に格納したIDを動的に埋め込むことも可能です。

    うまくいかないときのチェックリスト

    • Webhook URLが正しいか確認する(スペースや改行が混入していないか)
    • GASの実行ログ(表示→ログ)でエラーメッセージを確認する
    • 「外部サービスへのアクセス」の許可が完了しているか確認する
    • Slackのチャンネルが存在し、Webhookがそのチャンネルに設定されているか確認する
    • スプレッドシートの日付フォーマットが「yyyy/MM/dd」と一致しているか確認する
    • トリガーの実行時間帯がズレていないか確認する(タイムゾーンをAsia/Tokyoに設定する)

    応用・発展

    基本のパターンを組み合わせることで、さらに高度な自動化が実現できます。例えば、Slackのメッセージをボタン付きにする場合はBlock Kit形式のペイロードを使います。また、複数チャンネルに同時通知したい場合は複数のWebhook URLに対してループ処理すればOKです。

    さらに発展させるなら、Slack APIのchat.postMessageメソッドを使うことで、スレッド返信や既存メッセージの更新、ファイルのアップロードなども可能になります。その場合はSlack AppとOAuthトークンが必要になりますが、Incoming Webhookで物足りなくなったタイミングで移行を検討してみてください。

    まとめ

    • GASからSlackへの通知はIncoming WebhookとUrlFetchApp.fetch()で実現できる
    • スプレッドシートのデータを読み取り、条件に合う情報だけを通知することが可能
    • 時間トリガーを使えば定期通知、フォーム送信トリガーを使えばリアルタイム通知ができる
    • @channelや@hereのメンションも特定の記法を埋め込むだけで対応できる
    • 基本パターンを覚えれば、あらゆる業務通知の自動化に応用できる
  • スプレッドシートで在庫管理を自動化する方法

    スプレッドシートで在庫管理を自動化する方法

    Googleスプレッドシート+GASで、専用ツールなしに在庫管理を自動化する実践的な手順を解説します。

    在庫管理の手間を省きたいけれど、高価な専用システムは導入できない——そんな中小企業や個人事業主にとって、Googleスプレッドシートは強力な味方です。しかし、入力・集計を手動で行っていては本末転倒。GAS(Google Apps Script)を使えば、在庫の増減を自動追跡し、在庫不足アラートまで自動化できます。

    この記事では「在庫マスタシート」「入出庫記録シート」「自動集計+アラート通知」の3点セットを、コピペで使えるGASコードとともに丁寧に解説します。初めてGASを触る方でも手順通りに進めれば1時間以内に完成できます。

    この記事でできること

    • スプレッドシートで在庫数をリアルタイムに自動集計する
    • 入出庫があるたびに残数を自動更新する
    • 在庫が設定した閾値を下回ったらメールで自動アラートを受け取る
    • 月次在庫レポートをシートに自動生成する

    事前準備

    必要なものはGoogleアカウントのみです。以下のシート構成で新しいスプレッドシートを作成してください。

    • 在庫マスタシート:列A=商品ID、列B=商品名、列C=現在庫数、列D=最低在庫数(アラート閾値)
    • 入出庫記録シート:列A=日付、列B=商品ID、列C=区分(入庫/出庫)、列D=数量、列E=担当者

    シートを作成したら、スプレッドシートのIDをメモしておきます(URLの /d/ と /edit の間の文字列)。

    STEP1: 在庫マスタシートにサンプルデータを入力する

    在庫マスタシートに以下のようなサンプルデータを入力して動作確認の準備をします。

    商品ID  | 商品名         | 現在庫数 | 最低在庫数
    P001   | ボールペン(黒)| 50      | 20
    P002   | コピー用紙A4   | 10      | 30
    P003   | ホッチキス針   | 200     | 50
    

    P002のコピー用紙は意図的に在庫数を最低在庫数以下にしています。アラートのテストに使います。

    STEP2: GASエディタを開いてスクリプトを作成する

    スプレッドシートのメニューから「拡張機能」→「Apps Script」を開きます。デフォルトの myFunction は削除し、以下のコードを貼り付けてください。

    const SS_ID = 'YOUR_SPREADSHEET_ID'; // ここをスプレッドシートIDに変更
    const ALERT_EMAIL = 'your-email@example.com'; // アラート送信先
    
    function updateStock() {
      const ss = SpreadsheetApp.openById(SS_ID);
      const masterSheet = ss.getSheetByName('在庫マスタ');
      const logSheet = ss.getSheetByName('入出庫記録');
    
      const masterData = masterSheet.getDataRange().getValues();
      const stockMap = {};
      for (let i = 1; i < masterData.length; i++) {
        stockMap[masterData[i][0]] = {
          row: i + 1,
          name: masterData[i][1],
          stock: masterData[i][2],
          minStock: masterData[i][3]
        };
      }
    
      const logData = logSheet.getDataRange().getValues();
      for (let i = 1; i < logData.length; i++) {
        const [date, itemId, type, qty, person] = logData[i];
        if (!itemId || logData[i][5] === '処理済') continue;
    
        if (stockMap[itemId]) {
          const delta = type === '入庫' ? Number(qty) : -Number(qty);
          stockMap[itemId].stock += delta;
          masterSheet.getRange(stockMap[itemId].row, 3).setValue(stockMap[itemId].stock);
          logSheet.getRange(i + 1, 6).setValue('処理済');
        }
      }
    
      checkLowStock(stockMap);
    }
    
    function checkLowStock(stockMap) {
      const alerts = [];
      for (const id in stockMap) {
        const item = stockMap[id];
        if (item.stock <= item.minStock) {
          alerts.push('【' + item.name + '】残数: ' + item.stock + ' / 最低在庫: ' + item.minStock);
        }
      }
    
      if (alerts.length > 0) {
        const subject = '【在庫アラート】補充が必要な商品があります';
        const body = alerts.join('\n') + '\n\n※このメールは自動送信されています';
        MailApp.sendEmail(ALERT_EMAIL, subject, body);
      }
    }

    STEP3: トリガーを設定して自動実行にする

    GASエディタの左メニューから「トリガー」(時計アイコン)を開き、「トリガーを追加」をクリックします。設定は以下の通りです。

    • 実行する関数: updateStock
    • イベントのソース: 時間主導型
    • 時間の種類: 時間ベースのタイマー → 1時間ごと(または任意の間隔)

    これで1時間ごとに入出庫記録が自動集計され、在庫不足があれば即座にメール通知が届くようになります。

    STEP4: 入出庫記録シートに記録するだけで在庫が動く

    日々の運用は「入出庫記録」シートへの入力だけです。以下のフォーマットで行を追加するだけで、次のトリガー実行時に在庫マスタが自動更新されます。

    日付       | 商品ID | 区分 | 数量 | 担当者
    2025-04-10 | P001  | 出庫 | 10  | 山田
    2025-04-10 | P002  | 入庫 | 100 | 鈴木
    

    列Fに「処理済」と自動で記録されるので、重複処理の心配もありません。

    STEP5: 月次レポートを自動生成する(応用)

    以下の関数をスクリプトに追加し、月次トリガー(月1回)に設定すると、毎月1日に前月分の入出庫サマリーを新シートに自動生成できます。

    function generateMonthlyReport() {
      const ss = SpreadsheetApp.openById(SS_ID);
      const logSheet = ss.getSheetByName('入出庫記録');
      const now = new Date();
      const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
      const reportName = '月次レポート_' + lastMonth.getFullYear() + String(lastMonth.getMonth()+1).padStart(2,'0');
    
      const reportSheet = ss.insertSheet(reportName);
      reportSheet.appendRow(['商品ID', '入庫合計', '出庫合計', '純増減']);
    
      const logData = logSheet.getDataRange().getValues();
      const summary = {};
      for (let i = 1; i < logData.length; i++) {
        const [date, itemId, type, qty] = logData[i];
        if (!itemId) continue;
        const d = new Date(date);
        if (d.getMonth() !== lastMonth.getMonth() || d.getFullYear() !== lastMonth.getFullYear()) continue;
        if (!summary[itemId]) summary[itemId] = { in: 0, out: 0 };
        if (type === '入庫') summary[itemId].in += Number(qty);
        else summary[itemId].out += Number(qty);
      }
    
      for (const id in summary) {
        const { in: inQty, out: outQty } = summary[id];
        reportSheet.appendRow([id, inQty, outQty, inQty - outQty]);
      }
      Logger.log('月次レポート「' + reportName + '」を生成しました');
    }

    うまくいかないときのチェックリスト

    • スクリプト内の SS_ID が正しいスプレッドシートIDになっているか確認する
    • シート名が「在庫マスタ」「入出庫記録」と完全一致しているか確認する(全角スペースや表記ゆれに注意)
    • GASの実行権限でGmailの使用を許可しているか確認する(初回実行時に許可ダイアログが出る)
    • 入出庫記録の「区分」列が「入庫」または「出庫」の全角表記になっているか確認する
    • トリガーが正常に登録されているかGASのトリガー一覧画面で確認する

    応用・発展

    この仕組みをベースに、以下のような発展的な機能も追加できます。Googleフォームと連携すれば、スマートフォンからのバーコードスキャン入力にも対応可能です。また、Slackと連携して在庫アラートをチームチャンネルに通知する方法は別記事で詳しく解説しています。複数拠点の在庫管理が必要な場合は、シートをタブで拠点ごとに分け、集計関数で合算する方法が効果的です。さらにAppSheetと組み合わせると、スプレッドシートのデータをモバイルアプリのUIで操作できるようになり、現場スタッフでも直感的に入出庫入力ができます。

    まとめ

    • スプレッドシート+GASで、無料で本格的な在庫管理自動化が実現できる
    • 入出庫記録シートへの入力だけで在庫マスタが自動更新される
    • 在庫不足はメールで自動アラート通知されるため見落としゼロ
    • 月次レポート自動生成で棚卸し作業も効率化できる
    • Googleフォーム・Slack・AppSheetとの連携でさらに発展できる
  • ChatGPT APIをGASから呼び出してメール文を自動生成する

    ChatGPT APIをGASから呼び出してメール文を自動生成する

    Google Apps ScriptからChatGPT APIを呼び出して、業務メールの文章を自動生成する仕組みを最短で構築する方法を解説します。

    「返信メールを毎回ゼロから書くのが面倒」「定型文にはしたくないが、一から考える時間もない」——そんな悩みを持つビジネスパーソンは多いでしょう。ChatGPT APIとGoogle Apps Script(GAS)を組み合わせると、スプレッドシートに入力した件名や概要を元に、自然な文体のメール本文を自動生成できます。

    本記事では、OpenAI APIキーの取得からGASのコード実装、実際のメール送信まで、ブラウザとGASだけで完結する手順を丁寧に説明します。プログラミング初心者でも、この記事を読み終えた後には実際に動作する自動化を手に入れられます。

    この記事でできること

    • GASからChatGPT API(gpt-4o-mini)を呼び出してメール文を生成する
    • スプレッドシートの入力内容をもとに宛先・件名・本文を自動作成する
    • 生成したメールをGmailで送信する(または下書き保存する)
    • APIキーをスクリプトプロパティで安全に管理する

    事前準備

    以下のものを用意してください。

    • Googleアカウント(GmailとGoogleスプレッドシートが使えるもの)
    • OpenAIアカウントとAPIキー(platform.openai.comで取得)
    • APIの利用料金:gpt-4o-miniは非常に安価(1000トークン約$0.00015)なので、1通あたり数円以下です

    OpenAI APIキーはOpenAIダッシュボードの「API keys」メニューから「Create new secret key」で発行できます。発行したキーは一度しか表示されないため、必ずメモしておいてください。

    STEP1: スプレッドシートを準備する

    新しいGoogleスプレッドシートを作成し、以下の列を設定します。

    • A列: 送信先メールアドレス
    • B列: 件名のキーワード(例: 「打合せ日程の確認」)
    • C列: メールの概要・ポイント(例: 「来週月曜の14時に会議室Aで打合せしたい。参加者3名。アジェンダを事前に送ってほしい」)
    • D列: 生成されたメール本文(GASが書き込む列)
    • E列: 送信ステータス(GASが「送信済み」などを書き込む列)

    1行目にヘッダー(「メールアドレス」「件名キーワード」「概要」「生成本文」「ステータス」)を入力し、2行目以降にデータを入力しておきましょう。

    STEP2: GASプロジェクトを作成してAPIキーを設定する

    スプレッドシートのメニューから「拡張機能」→「Apps Script」を開きます。GASエディタが開いたら、まずAPIキーをスクリプトプロパティに安全に保存します。

    左のメニューから「プロジェクトの設定」(歯車アイコン)をクリックし、「スクリプトプロパティ」セクションで「プロパティを追加」をクリックします。プロパティ名を「OPENAI_API_KEY」、値を取得したAPIキーに設定して保存します。コード内に直接APIキーを書くと、スクリプトを共有した際に漏洩する危険があるためこの方法を使います。

    STEP3: ChatGPT APIを呼び出す関数を書く

    GASエディタのコードエリアに以下のコードを貼り付けます。

    function generateEmailContent(subject, summary) {
      const apiKey = PropertiesService.getScriptProperties().getProperty('OPENAI_API_KEY');
      const url = 'https://api.openai.com/v1/chat/completions';
    
      const prompt = `以下の情報をもとに、ビジネスメールの本文を日本語で作成してください。
    件名のキーワード: ${subject}
    メールの概要・要点: ${summary}
    
    条件:
    - 丁寧なビジネス敬語を使う
    - 書き出しは「お世話になっております。」から始める
    - 署名部分は「以上、よろしくお願いいたします。」で締める
    - 本文のみを出力し、件名や宛名は不要`;
    
      const payload = {
        model: 'gpt-4o-mini',
        messages: [
          { role: 'system', content: 'あなたはビジネスメールの文章作成を支援するアシスタントです。' },
          { role: 'user', content: prompt }
        ],
        max_tokens: 800,
        temperature: 0.7
      };
    
      const options = {
        method: 'post',
        contentType: 'application/json',
        headers: { 'Authorization': 'Bearer ' + apiKey },
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      };
    
      const response = UrlFetchApp.fetch(url, options);
      const json = JSON.parse(response.getContentText());
    
      if (json.error) {
        throw new Error('API Error: ' + json.error.message);
      }
    
      return json.choices[0].message.content.trim();
    }

    この関数はOpenAI APIにリクエストを送り、生成されたメール本文の文字列を返します。プロンプトで「ビジネス敬語」「書き出し・締めの形式」を指定することで、品質の安定した文章が生成されます。

    STEP4: スプレッドシートを読み取ってメールを送信するメイン関数を書く

    先ほどのコードの下に、以下のメイン処理関数を追加します。

    function sendAIGeneratedEmails() {
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const lastRow = sheet.getLastRow();
    
      for (let i = 2; i <= lastRow; i++) {
        const emailAddress = sheet.getRange(i, 1).getValue();
        const subjectKeyword = sheet.getRange(i, 2).getValue();
        const summary = sheet.getRange(i, 3).getValue();
        const status = sheet.getRange(i, 5).getValue();
    
        if (!emailAddress || !subjectKeyword || !summary) continue;
        if (status === '送信済み') continue;
    
        try {
          const body = generateEmailContent(subjectKeyword, summary);
          sheet.getRange(i, 4).setValue(body);
          GmailApp.sendEmail(emailAddress, subjectKeyword, body);
          sheet.getRange(i, 5).setValue('送信済み');
          Utilities.sleep(1000);
        } catch (e) {
          sheet.getRange(i, 5).setValue('エラー: ' + e.message);
        }
      }
    
      SpreadsheetApp.getUi().alert('処理完了');
    }

    スプレッドシートの2行目から最終行まで順番に処理し、ChatGPT APIで生成した本文をD列に書き込んでからGmailで送信します。APIのレート制限を避けるため、各行の処理後に1秒待機しています。

    STEP5: 下書き保存モードと実行ボタンを追加する

    本番送信の前に下書きで確認したい場合は、sendEmailの代わりにGmailApp.createDraftを使います。以下のように切り替え可能な設計にすると安全です。

    // 送信モード: true=即時送信 / false=下書き保存
    const SEND_MODE = false;
    
    if (SEND_MODE) {
      GmailApp.sendEmail(emailAddress, subjectKeyword, body);
      sheet.getRange(i, 5).setValue('送信済み');
    } else {
      GmailApp.createDraft(emailAddress, subjectKeyword, body);
      sheet.getRange(i, 5).setValue('下書き保存');
    }

    また、スプレッドシートのメニューから実行できるカスタムメニューを追加すると便利です。

    function onOpen() {
      SpreadsheetApp.getUi()
        .createMenu('メール自動化')
        .addItem('AIメール生成・送信', 'sendAIGeneratedEmails')
        .addToUi();
    }

    このonOpen関数はスプレッドシートを開くたびに自動実行され、「メール自動化」というカスタムメニューが追加されます。

    うまくいかないときのチェックリスト

    • 「Exception: Request failed」→ OpenAI APIキーが正しいか、スクリプトプロパティの名前が「OPENAI_API_KEY」と完全一致しているか確認
    • 「Insufficient quota」エラー → OpenAIの残高が0になっている。ダッシュボードでクレジットを追加する
    • 「You do not have permission」→ GASの実行権限でGmailへのアクセスを許可していない。初回実行時に表示される権限承認ダイアログで「許可」をクリック
    • メール本文が空欄になる → APIレスポンスのjson.choices[0]が存在しない場合。console.logでレスポンス全体を確認する
    • APIのレート制限に引っかかる → Utilities.sleep(2000)に増やして処理間隔を広げる

    応用・発展

    この仕組みをベースに、さらに高度な自動化も実現できます。たとえば、Gmailで受け取った問い合わせメールを自動で読み取り、内容を解析して返信案を生成するシステムに発展させることができます。また、HTMLメール形式(GmailApp.sendEmailのオプションでhtmlBodyを指定)にすることで、見栄えの良いメールマガジンを自動生成することも可能です。さらに、Googleカレンダーと連携して打合せ日程の候補を自動的に含めたアポイントメールを生成するなど、データソースを増やすことでよりインテリジェントなメール自動化が実現します。

    まとめ

    • GASのUrlFetchApp.fetchを使えばChatGPT APIを簡単に呼び出せる
    • APIキーはスクリプトプロパティで管理することでセキュリティを確保できる
    • スプレッドシートの入力情報をプロンプトに組み込むことで、状況に応じたメール文を生成できる
    • SEND_MODEフラグで「下書き保存」と「即時送信」を切り替えることで、安全に運用できる
    • gpt-4o-miniは低コストで高品質なため、日常的な業務メール自動化に最適なモデル
  • NotionとGASを連携して日報を自動生成する

    NotionとGASを連携して日報を自動生成する

    NotionのデータベースとGoogle Apps Scriptを組み合わせることで、毎日の日報作成を完全自動化できます。

    「毎日の日報作成に時間がかかる」「書き忘れが多い」という悩みは、多くのビジネスパーソンに共通しています。Notionは情報管理ツールとして優秀ですが、単体では自動化に限界があります。そこでGoogle Apps Script(GAS)と連携させることで、Notionのデータを自動で集計し、日報を自動生成・送信する仕組みを構築できます。

    本記事では、Notion APIとGASを使って「Notionのタスクデータベースから当日の完了タスクを自動収集し、日報メールを自動送信する」システムを一から作る手順を解説します。プログラミング初心者でも手順通りに進めれば実装できるよう、詳しく説明します。

    この記事でできること

    • Notion APIを使ってデータベースのデータをGASで取得する
    • 毎日決まった時刻に日報を自動生成する
    • 完成した日報をメールで自動送信する
    • 日報内容をNotionに自動で記録・保存する

    事前準備

    以下のものが必要です。作業開始前に揃えておきましょう。

    • Notionアカウント(無料プランでOK)
    • Googleアカウント(GASを使用)
    • Notionのタスク管理データベース(プロパティ:タスク名、担当者、完了フラグ、日付)

    STEP1: Notion APIキーを取得する

    まずNotionとGASを連携させるためのAPIキーを取得します。

    1. Notionにログインし、notion.so/my-integrationsにアクセスします
    2. 「新しいインテグレーション」をクリックし、名前(例:GAS日報Bot)を入力します
    3. 「送信」をクリックするとInternal Integration Tokenが発行されます
    4. このトークン(secret_xxxx…形式)をコピーして保存します

    次に、連携したいNotionデータベースを開き、右上の「…」メニューから「接続」→作成したインテグレーションを選択して権限を付与します。データベースのURLに含まれる32文字の英数字がデータベースIDです。このIDも控えておきます。

    STEP2: GASのスクリプトを作成する

    Google Driveにアクセスし、「新規」から「Google Apps Script」を選択してプロジェクトを作成します。スクリプトエディタで以下の内容を入力します。まず設定項目として、NOTIONトークン、データベースID、送信先メール、氏名を定数として定義します。

    メイン関数generateDailyReport()では、今日の日付をyyyy-MM-dd形式で取得し、fetchNotionTasks()でタスク一覧を取得します。タスクがあればcreateReportBody()で日報テキストを作成し、sendReportEmail()でメール送信します。

    fetchNotionTasks()ではNotionのデータベースクエリAPIを呼び出します。filterにより完了フラグがtrueかつ本日の日付のタスクだけを絞り込みます。レスポンスのresults配列からタスク名とカテゴリを抽出して返します。

    createReportBody()では日報のテキストを組み立てます。日付・担当者・完了タスク一覧・所感欄をテンプレートに従って結合します。sendReportEmail()ではGmailAppのsendEmail()を使ってメール送信します。

    STEP3: 設定値を書き換える

    コードの上部にある設定項目を自分の環境に合わせて書き換えます。

    • NOTION_TOKEN: STEP1で取得したIntegration Tokenに置き換え
    • DATABASE_ID: STEP1で控えたデータベースIDに置き換え
    • REPORT_EMAIL: 日報の送信先メールアドレスに変更
    • YOUR_NAME: 自分の名前に変更

    Notionデータベースのプロパティ名がコードと一致しているか確認してください。チェックボックスのプロパティ名が「完了」であれば、コード内の「完了フラグ」を「完了」に変更します。

    STEP4: 動作テストをする

    実際にスクリプトを実行してテストします。

    1. GASエディタの上部にある関数選択プルダウンでgenerateDailyReportを選択します
    2. 「実行」ボタンをクリックします
    3. 初回実行時はGoogleアカウントの権限承認画面が表示されます。「許可」をクリックします
    4. 実行ログに「日報送信完了」が表示されれば成功です
    5. 指定したメールアドレスに日報メールが届いていることを確認します

    うまく動作したら、次のSTEPで毎日自動実行する設定をします。

    STEP5: 毎日自動実行のトリガーを設定する

    GASには「トリガー」という自動実行機能があります。これを設定することで、毎日決まった時刻に日報が自動送信されるようになります。

    1. GASエディタの左メニューから「トリガー」(時計アイコン)をクリックします
    2. 右下の「トリガーを追加」ボタンをクリックします
    3. 実行する関数にgenerateDailyReportを選択、イベントのソースを時間主導型、日付ベースのタイマーで17時〜18時に設定します
    4. 「保存」をクリックして完了です

    これで毎日17〜18時の間に自動で日報が送信されます。

    うまくいかないときのチェックリスト

    • APIトークンエラー: Notionのインテグレーションが正しく作成されているか、トークンをコピーし直してみる
    • タスクが0件になる: Notionデータベースのプロパティ名がコードと一致しているか確認。日付フォーマットがyyyy-MM-dd形式になっているか確認
    • メールが届かない: REPORT_EMAILに正しいアドレスが設定されているか確認
    • 権限エラー: Notionデータベースに対してインテグレーションのアクセス権が付与されているか確認
    • トリガーが動かない: GASプロジェクトがスタンドアロン型になっているか確認

    応用・発展

    基本的な日報自動化ができたら、さらに発展させることができます。

    • Slack通知に変更する: メールの代わりにSlack Incoming Webhookを使い、UrlFetchApp.fetch()でSlackに送信できます
    • 日報をNotionに記録する: Notion APIのpages.createエンドポイントを使い、生成した日報を別のNotionページとして自動保存できます
    • 週次サマリーを作る: トリガーを週ベースに設定し、1週間分のタスクをまとめた週次報告書を自動生成できます
    • ChatGPT APIと組み合わせる: タスクリストをChatGPT APIに送り、振り返りコメントを自動生成して日報に追加できます

    まとめ

    • Notion APIとGASを連携させることで、日報作成を完全自動化できる
    • Notion Integrationを作成してAPIトークンを取得し、GASからデータを取得する
    • GASのトリガー機能で毎日決まった時刻に自動実行できる
    • Slack通知やNotion記録など、応用範囲は広い
    • 日報の書き忘れゼロ・作成時間ゼロを実現し、本来の業務に集中できる
  • GAS初心者が最初に作るべき業務自動化3選【コピペで使えるサンプルコード付き】

    GAS初心者が最初に作るべき業務自動化3選【コピペで使えるサンプルコード付き】

    Google Apps Script(GAS)を初めて使う方が、すぐに業務効率化の成果を実感できる自動化ツール3つを、コピペで使えるサンプルコードとともに解説します。

    「GASを使ってみたいけど、何から始めればいいかわからない」という方は多いのではないでしょうか。プログラミングの経験が少なくても、GASはGoogleスプレッドシートやGmailと連携できる強力な自動化ツールです。

    この記事では、GAS初心者が最初に取り組むべき自動化テーマを3つ厳選しました。どれも実務で即活用できるものばかりで、コードをコピペするだけで動かせます。GASの基礎を学びながら、業務改善の成功体験を積んでいきましょう。

    この記事でできること

    • GASの基本的なスクリプトエディタの使い方を理解できる
    • Googleスプレッドシートのデータを自動処理する仕組みを作れる
    • メールの自動送信(Gmailとの連携)を実装できる
    • 定期実行(トリガー)の設定方法を習得できる
    • 3つの実用的な自動化スクリプトをコピペで使える

    事前準備

    GASを使うには、Googleアカウントがあればそれだけで十分です。追加のインストールや費用は一切不要です。

    • 必要なもの:Googleアカウント(無料)
    • 動作環境:Webブラウザのみ(ChromeまたはSafari推奨)
    • 開発環境:Googleスプレッドシートのメニューから「拡張機能」→「Apps Script」を開くだけ

    スクリプトエディタを開いたら、左側のメニューに「コード.gs」というファイルが表示されます。ここにコードを記述していきます。なお、GASのコードはJavaScriptをベースにしているため、JavaScriptの基礎知識があると理解しやすいですが、なくても本記事のサンプルコードは動作します。

    自動化①:スプレッドシートの入力をチェックして通知メールを送る

    最初に取り組むテーマとして最適なのが「スプレッドシートの変化を検知してメール通知する」仕組みです。たとえば、申込フォームの回答がスプレッドシートに追加されたタイミングで、担当者に自動でメールを送ることができます。

    シナリオ例

    Googleフォームでお問い合わせを受け付け、回答がスプレッドシートに記録されるたびに、担当者のGmailに通知メールを自動送信するケースです。

    スクリプトの作成手順

    Googleフォームに紐づいたスプレッドシートを開き、「拡張機能」→「Apps Script」を選択してスクリプトエディタを開きます。以下のコードを貼り付けてください。

    function sendNotificationEmail() {
      // スプレッドシートの最新データを取得
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const lastRow = sheet.getLastRow();
      const data = sheet.getRange(lastRow, 1, 1, sheet.getLastColumn()).getValues()[0];
    
      // メール送信先(担当者のメールアドレスに変更)
      const recipient = "your-email@example.com";
      const subject = "【自動通知】新しいお問い合わせが届きました";
    
      // メール本文の作成
      const body = "新しいお問い合わせが届きました。
    
    "
        + "受信日時: " + new Date().toLocaleString('ja-JP') + "
    "
        + "内容: " + data.join(', ') + "
    
    "
        + "スプレッドシートを確認してください。";
    
      // メール送信
      GmailApp.sendEmail(recipient, subject, body);
      Logger.log("通知メールを送信しました");
    }
    

    コードを貼り付けたら「Ctrl + S」で保存します。次に、トリガーを設定します。左メニューの時計マーク(トリガー)→「トリガーを追加」をクリックし、「実行する関数」に「sendNotificationEmail」、「イベントのソース」に「スプレッドシートから」、「イベントの種類」に「フォーム送信時」を選択して保存します。

    これでフォームに回答があるたびに自動でメールが届く仕組みが完成です。

    自動化②:毎朝9時にその日のタスク一覧をメールで送る

    次は「定期実行トリガー」を活用した自動化です。スプレッドシートで管理しているタスクリストを毎朝メールで受け取ることで、確認漏れや対応忘れを防げます。

    シナリオ例

    A列に期日、B列にタスク名を記載したスプレッドシートを用意し、毎朝9時に「本日期限のタスク」をまとめたメールが届く仕組みを作ります。

    スクリプトの作成手順

    スプレッドシートの1行目をヘッダー(「期日」「タスク名」など)にし、2行目以降にデータを入力しておきます。スクリプトエディタに以下のコードを貼り付けます。

    function sendDailyTaskReminder() {
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const data = sheet.getDataRange().getValues();
      const today = new Date();
      today.setHours(0, 0, 0, 0);
    
      let taskList = [];
    
      // 2行目以降のデータをループ(1行目はヘッダー)
      for (let i = 1; i < data.length; i++) {
        const dueDate = new Date(data[i][0]);
        dueDate.setHours(0, 0, 0, 0);
        const taskName = data[i][1];
    
        // 本日期限のタスクを抽出
        if (dueDate.getTime() === today.getTime() && taskName) {
          taskList.push("・" + taskName);
        }
      }
    
      // タスクがある場合のみメール送信
      if (taskList.length > 0) {
        const recipient = Session.getActiveUser().getEmail();
        const subject = "【本日のタスク】" + today.toLocaleDateString('ja-JP') + " (" + taskList.length + "件)";
        const body = "本日期限のタスクは以下の" + taskList.length + "件です。
    
    "
          + taskList.join('
    ')
          + '
    
    スプレッドシートで確認・更新してください。';
        GmailApp.sendEmail(recipient, subject, body);
        Logger.log(taskList.length + "件のタスクをメール送信しました");
      } else {
        Logger.log("本日期限のタスクはありません");
      }
    }
    

    保存後、トリガーを設定します。「トリガーを追加」→「実行する関数:sendDailyTaskReminder」「イベントのソース:時間主導型」「時間ベースのトリガーのタイプ:日付ベースのタイマー」「時刻:午前9時〜10時」を選択して保存します。

    これで毎朝9時台に自動でタスクリマインダーメールが届くようになります。

    自動化③:月次レポートを自動集計してPDF化・メール送信する

    少し応用的ですが、最も実務インパクトが大きい自動化です。月初めに先月のデータを集計し、PDF化してメールで送付する仕組みを作ります。月次レポート作成の手間を大幅に削減できます。

    シナリオ例

    売上データが記録されているスプレッドシートの集計シートを、毎月1日に自動でPDF出力し、上長にメール送付するケースです。

    スクリプトの作成手順

    スプレッドシートに「月次レポート」というシートを用意し、集計・グラフなどを作成しておきます。スクリプトエディタに以下のコードを貼り付けます。

    function sendMonthlyReport() {
      const ss = SpreadsheetApp.getActiveSpreadsheet();
      const reportSheet = ss.getSheetByName("月次レポート");
    
      if (!reportSheet) {
        Logger.log("「月次レポート」シートが見つかりません");
        return;
      }
    
      // 先月の年月を取得
      const now = new Date();
      const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
      const yearMonth = lastMonth.getFullYear() + "年" + (lastMonth.getMonth() + 1) + "月";
    
      // スプレッドシートをPDFとしてエクスポート
      const ssId = ss.getId();
      const sheetId = reportSheet.getSheetId();
      const pdfUrl = "https://docs.google.com/spreadsheets/d/" + ssId + "/export"
        + "?format=pdf&gid=" + sheetId + "&size=A4&portrait=true&fitw=true&sheetnames=false&printtitle=false";
    
      const token = ScriptApp.getOAuthToken();
      const response = UrlFetchApp.fetch(pdfUrl, {
        headers: { 'Authorization': 'Bearer ' + token }
      });
      const pdfBlob = response.getBlob().setName(yearMonth + "月次レポート.pdf");
    
      // メール送信(添付ファイル付き)
      const recipient = "manager@example.com"; // 送信先を変更
      const subject = "【月次レポート】" + yearMonth;
      const body = "お疲れ様です。
    
    " + yearMonth + "の月次レポートをお送りします。
    ご確認のほどよろしくお願いいたします。";
    
      GmailApp.sendEmail(recipient, subject, body, {
        attachments: [pdfBlob]
      });
      Logger.log(yearMonth + "のレポートを送信しました");
    }
    

    保存後、トリガーを「毎月1日の午前8時〜9時」に設定すれば、月次レポートの作成・送付が完全自動化されます。

    うまくいかないときのチェックリスト

    • 「承認が必要です」エラー:初回実行時は必ず権限の承認が必要です。「権限を確認」→「詳細」→「安全でないページに移動」→「許可」の順にクリックしてください
    • メールが届かない:スパムフォルダを確認してください。また、GmailApp.sendEmailの送信先メールアドレスが正しいか確認してください
    • 「スコープが不足しています」エラー:スクリプトを保存し直して再度実行すると、必要な権限の承認画面が表示されます
    • トリガーが実行されない:「実行数」メニューでエラーログを確認してください。トリガーの設定が保存されているかも確認しましょう
    • シート名が見つからないエラー:getSheetByName()に渡す文字列が、実際のシート名と完全に一致しているか確認してください(全角・半角スペースの違いに注意)
    • 日付の比較がうまくいかない:スプレッドシートの日付セルは「日付形式」に設定されているか確認してください

    応用・発展

    今回紹介した3つの自動化を土台に、さらに発展させることができます。たとえば、通知メールに「承認ボタン」のリンクを埋め込んでワークフロー化したり、Slackと連携してメールではなくチャットで通知したりすることも可能です。また、GASはGoogleドライブ、Googleカレンダー、Google Meet、さらには外部APIとも連携できるため、活用の幅は非常に広いです。次のステップとして、ChatGPT APIとGASを連携してメール文を自動生成する仕組みや、kintoneとGASを組み合わせた業務システム連携なども検討してみてください。

    まとめ

    • GASはGoogleアカウントだけで使えるノーコスト・ノーインストールの自動化ツール
    • 初心者が最初に作るべき自動化は「通知メール送信」「タスクリマインダー」「月次レポート自動送付」の3つ
    • トリガー機能を使えば定期実行・イベント実行の両方に対応できる
    • コピペで動かしてみることが、GASを身につける最短ルート
    • 1つ成功体験を積むと、応用が広がり業務全体の効率化につながる