メインコンテンツへスキップ
見出し画像

【後半】MicrosoftFormsの内容に Geminiからのコメントが 届く仕組み

    ChatGPTと組んで完成させた、AIフィードバック自動メール配信システム!


    📬 Formsで児童が送信したふりかえり。

    それがGoogleスプレッドシートに転記されたその瞬間、もう魔法が始まっていました。

    🎯 目指したのは、「子ども × AI × 担任」がつながるフロー

    Microsoft Forms → Power Automate までは前回紹介しました。

    今回はその続き。

    Google スプレッドシートに転記された児童の「振り返り」に、
    今度は Gemini API(Googleの生成AI) が優しく返事を書いてくれます。
    そして…その内容は、児童と担任だけが参加しているTeamsのプライベートチャネルのアドレス宛に、メールで配信されるのです。

    画像



    🧩 使ったツールはこの4つ!

    ・Microsoft Forms:児童がふりかえりを送信
    ・Power Automate:Googleスプレッドシートに転記
    ・Google Apps Script:変更を検知してフィードバック生成
    ・Gemini API AIコメントを生成
    ・Gmail API(GAS) メールで自動配信

    ⚙ どんなフローになってるの?

    1. 児童がFormsに入力 → PowerAutomateでC列に転記

    2. GASの onChange() が発火!

    3. callGeminiAPI() がC列の内容をGeminiに渡す

    4. D列にAIフィードバックを表示

    5. A列に設定されたTeamsチャネルのメールアドレスに、C列+D列のセットを自動送信!

    最終的に完成したGASは次のとおりです。
    *私は一行も書いていません

    // ✅ Gemini API用の設定(APIキーは自分のものに置き換えてください)
    const API_KEY = '<ここにあなたのGemini APIキー>';
    const MODEL_URL = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=' + API_KEY;
    
    // ✅ Gemini APIからフィードバックを取得する関数
    function callGeminiAPI(promptText) {
      const payload = {
        contents: [{
          parts: [{
            text: '以下の内容について、小学生向けのやさしいフィードバックを日本語で100文字以内で書いてください。内容:「' + promptText + '」'
          }]
        }]
      };
    
      const options = {
        method: 'post',
        contentType: 'application/json',
        payload: JSON.stringify(payload),
        muteHttpExceptions: true,
      };
    
      try {
        const response = UrlFetchApp.fetch(MODEL_URL, options);
        const code = response.getResponseCode();
        const body = response.getContentText();
        Logger.log(`【APIレスポンスコード】${code}`);
        Logger.log(`【APIレスポンス本文】${body}`);
    
        if (code !== 200) {
          return null;
        }
    
        const json = JSON.parse(body);
        const reply = json?.candidates?.[0]?.content?.parts?.[0]?.text;
        return reply || null;
      } catch (error) {
        Logger.log("【APIエラー】" + error);
        return null;
      }
    }
    
    // ✅ C列の内容が更新されたときに、D列にAIフィードバックを書き、A列のメールアドレスに送信するメイン処理
    function onChange(e) {
      const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
      const lastRow = sheet.getLastRow();
    
      const emails = sheet.getRange(2, 1, lastRow - 1).getValues();       // A列(メールアドレス)
      const reflections = sheet.getRange(2, 3, lastRow - 1).getValues();  // C列(児童のふりかえり)
      const feedbacks = sheet.getRange(2, 4, lastRow - 1).getValues();    // D列(前回のAIフィードバック)
      const previous = sheet.getRange(2, 5, lastRow - 1).getValues();     // E列(前回のC列内容)
    
      for (let i = 0; i < reflections.length; i++) {
        const row = i + 2;
        const email = emails[i][0];
        const reflection = reflections[i][0];
        const lastReflection = previous[i][0];
    
        // C列が空、または前回と同じならスキップ
        if (!reflection || reflection === lastReflection) continue;
    
        // フィードバック生成
        const aiFeedback = callGeminiAPI(reflection);
        if (!aiFeedback) continue;
    
        // D列とE列に反映
        sheet.getRange(row, 4).setValue(aiFeedback);    // AIコメント(D列)
        sheet.getRange(row, 5).setValue(reflection);    // 履歴保存用(E列)
    
        // メール送信(A列にアドレスがある場合)
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        if (emailRegex.test(email)) {
          const subject = "今日のふりかえりとAIコメント";
          const body = `【児童のふりかえり】\n${reflection}\n\n【AIからのコメント】\n${aiFeedback}`;
          try {
            GmailApp.sendEmail(email, subject, body);
            Logger.log(`📧 メール送信完了:${email}`);
          } catch (err) {
            Logger.log(`⚠ メール送信エラー(${email}):${err}`);
          }
        } else {
          Logger.log(`⚠ 無効なメールアドレス:${email}`);
        }
      }
    }
    

    *コード内の「以下の内容について、小学生向けのやさしいフィードバックを日本語で100文字以内で書いてください。」の文章を変えると、フィードバックの内容を改善することができます。

    🔐 APIキーの扱いについて

    ※このコードでは API キー部分を <ここにあなたのAPIキー> としています。実際に利用するには、Google Cloud Consoleで Gemini API のキーを取得して貼り付けてください。APIキーは個人情報ですので、他人と共有しないようご注意ください。

    🧠 この仕組みで生まれた価値

    • 児童の記述が即座にAIと担任に共有される

    • 担任は「フィードバックがすでに届いている」状態から、次の対話に集中できる

    • 子どもは「誰かが読んでくれてる」という安心感を得られる

    画像
    Teamsのプライベートチャネルにメールという形で届く

    🤖 ChatGPTとの開発:まるで相棒

    今回も、困ったことがあればすぐに ChatGPT に聞きました。

    • 「GASが動かない…」

    • 「範囲がおかしい…」

    • 「Teamsのアドレスにメールが行かない…」


    画像
    時にエラー画面のスクリーンショットとうなり声だけでも対応してくれました

    そのたびに、何度でもつきあってくれて、いつもポジティブ。
    結局、63往復以上のやりとりを経て、完成までこぎつけました。

    🗒️ おわりに

    …「こうすればもっとよくなるかも」と想像する力が、これからの教師にますます求められてくるのだと思います。

    テクノロジーはあくまで手段。
    でも、その手段を知っていることで、子どもとの関わり方は変えられる。
    このシステムづくりを通して、私はそれを実感しました。

    「生成AIって難しそう」
    「ICTは得意じゃないから…」

    そんなふうに思っている先生こそ、「児童の顔を思い浮かべながら試してみる」ことで、きっと一歩踏み出せると思います。

    あなたの“できたらいいな”を、一緒にカタチにしてくれる相棒として。
    生成AI、そしてChatGPTは、これからも先生たちのそばにいるはずです。

     
     
    小学校教員/MIEE2022-2026/Google認定教育者Lv.2/WakeletAmbassador/KahootAmbassador

    あなたへのおすすめ