LINE でもらったスケジュールも Gemini に渡して Google カレンダーに登録してもらうようにしました

スマートホーム

私の夫は週3日在宅勤務なので、その日のミーティングの予定を LINE で送ってもらいます。
うちでは MacroDroidと IFTTT を連携させていて、私の Google カレンダーに入っている予定を参照して、自宅特定のライト(電球)をつけることで夫の会議の予定を可視化しています。

で、 Google カレンダーに自分で予定を入力するのがとても面倒なので、以前夫が送ってくれたLINEの文面を ChatGPT にそのまま貼り付けて『会議登録の URL』を出してもらうという仕組みを作った話を書きました。

去年の12月ころから Gemini に課金をしているので、もう ChatGPT を使用していません。
本当であれば、両方に課金して使い分け…ということをすべきなのかもしれませんが、まぁ今のところ Gemini だけでかなり事が足りているので、Gemini にしか課金してない状況です。

なので、この仕組みも Gemini 用に変更をしました。

Gemini にも、ChatGPT の『プロジェクト』このような機能である『Gem』という機能があるので、まず会議登録用の Gem を作成しました。
その中のカスタム指示のところに

あなたは、ユーザーの入力から会議や予定の情報を抽出し、Googleカレンダーに登録するためのアシスタントです。

後にGoogle Apps Script (GAS) で連携処理を行うため、以下のルールを厳密に遵守してください。

【重要:タイトル生成の絶対ルール】

  • 会話の一番最初に、以下の文章を出してください。(yymmdd は年月日)
  • yymmdd_💡会議予定のGoogleカレンダー登録
  • 会議の予定タイトルは、以下の文字列のみを正確に使用してください。
    • 正:☆会議☆
    • 誤:『☆会議☆』「☆会議☆」MTG
  • 注意: 前後にカギ括弧(『』や「」)やスペースなどの余分な文字は絶対に含めないでください。

【対話と登録のフロー】

  1. 情報の抽出と確認:
    • ユーザーの入力テキストから「日時」を抽出します。
    • 「例えば~」といった仮定の話や過去の文脈は無視してください。
    • 明示的な指示がない限り、「会議」以外の予定(昼食、休憩など)は無視し、会議の予定のみを対象とします。
    • 重要: 日時を特定した後、必ず「以下の内容で登録しますか?」とテキストで内容の確認を行ってください。
  2. ツールの実行:
    • ユーザーから「はい」「お願いします」等の承認が得られた場合のみ、Googleカレンダー連携ツール(Extensions)を使用して予定作成を提案してください。

【禁止事項】

  • ユーザーの承認なしにツールを呼び出すこと。
  • ユーザーが求めていない長文の解説や挨拶。
  • calendar/render?action=TEMPLATE 等を含む手動登録用のURLリンクを表示すること。

という文面をペタっと貼り付けています。
これで、いつも夫が送ってくれる

今日は1030-11、14-17に MTG があります

的な文章を送りつけると

  1. 予定名: ☆会議☆
    時間: 10:30-11:00
     
  2. 予定名: ☆会議☆
    時間: 14:00-17:00

という2つの予定を、私の Google カレンダーのデフォルトのカレンダーに【 登録 】してくれるようになりました!
…ChatGPT だと、会議を直接 Google カレンダーに登録してくれなくて、『登録する用の URL』を発行してくれるので、私がそれをクリックする必要があったんです。
Gemini だと、直接会議の予定を登録してくれるようになったんですよ!
これはすごく嬉しかったんですけど…、問題は『デフォルトのカレンダーにしか入れてくれない』ということでした。
今組んでいる MacroDroid の会議のシステムだと、私の Google カレンダーの『会議』というカレンダーの中にある予定を見てライト(電球)の ON・OFF をするような設定になっているので、デフォルトのカレンダーだと駄目なんですよねー。
いろいろ試したんですが、どうしてもやっぱりデフォルトのカレンダーにしか入れてくれないようなので、今度は GAS を使って予定を移動させることにしました。

GAS はもちろん Gemini に書いてもらいました(笑)。
一応下に乗せますが、Gemini にお願いすればおんなじような物を書いてくれると思います。

function moveMeetings() {
  var now = new Date();
  var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());

  // 月〜金以外は何もしない
  var day = today.getDay(); // 0:日,1:月,...,6:土
  if (day === 0 || day === 6) return;

  var srcCal = CalendarApp.getDefaultCalendar();
  var dstCals = CalendarApp.getCalendarsByName('会議');
  if (!srcCal || dstCals.length === 0) {
    Logger.log('元カレンダーまたは「会議」カレンダーが見つかりません。');
    return;
  }
  var dstCal = dstCals[0];

  // 今日 0:00 ~ 明日 0:00
  var start = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 0, 0, 0);
  var end   = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 1, 0, 0, 0);

  var events = srcCal.getEvents(start, end);
  var movedCount = 0;

  for (var i = 0; i < events.length; i++) {
    var ev = events[i];

    if (ev.getTitle() !== '☆会議☆') continue;

    var evStart = ev.getStartTime();
    var evEnd   = ev.getEndTime();

    // 重複防止
    var exist = dstCal.getEvents(evStart, evEnd).some(function(dstEv) {
      return dstEv.getTitle() === ev.getTitle();
    });

    if (!exist) {
      var guests = ev.getGuestList().map(function(g) {
        return g.getEmail();
      });

      dstCal.createEvent(ev.getTitle(), evStart, evEnd, {
        description: ev.getDescription(),
        location: ev.getLocation(),
        guests: guests.join(','),
        sendInvites: false
      });
    }

    // 元予定を削除(移動)
    ev.deleteEvent();
    movedCount++;
  }

  // ---- MacroDroid Webhook(URL) 呼び出し ----
  try {
    // あなたの MacroDroid Webhook URL(TinyURLでも可)
    var baseUrl = 'https://tinyurl.com/XXXXX/Kaigi_GAS';

    var runAt = Utilities.formatDate(now, 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss');

    // クエリパラメータで件数と実行時刻を渡す
    var url = baseUrl + '?movedCount=' + encodeURIComponent(movedCount) +
                        '&runAt=' + encodeURIComponent(runAt);

    UrlFetchApp.fetch(url, {
      method: 'get',
      muteHttpExceptions: true
    });
  } catch (e) {
    Logger.log('Webhook送信エラー: ' + e);
  }
}

『移動』というか、正確には『コピーして元を消す』という感じですかね。
ポイントは

  • 土日には実行されないようにした
  • 実行されたら、MacroDroid の Webhook に『実行した時間』と『移動した予定の件数』を送るようにした
    (MacroDroid 側で受け取ってスマホに通知を出すようにした)

かな。
しかし、ちょっとお願いするだけでこれだけ書いてくれますからね、本当にありがたいことです。
ちなみに、今まで GAS を自分で書いたこともあったんですが、あくまで『スプレッドシート上で動かす GAS』しかやったことがなかったので、「GAS 単体ってどこから書けばいいんですか…?」という質問もしました。
ちょっと恥ずかしかった(笑)。
(Google ドライブの『+ 新規』のところの下の方に『Google App Script』があるので、そこからです)

それから、スクリプトの編集画面の左側のところから『トリガー』を選び、

  • 時間主導型
  • 日付ベースのタイマー
  • 午前9時~10時
     
  • 時間主導型
  • 日付ベースのタイマー
  • 午前10時~11時

の2つのトリガーを設定しました。
これで、月~金の9:00~10:00で1回、月~金の10:00~11:00で1回、このスクリプトが実行されるようになりました。
2回実行にしたのは、一応毎回9時前には予定を送ってくれるんですが、たまーーに9時過ぎてから送ってくれることもあって、その時用にです。
まー、ほとんど9時台の方で拾われる感じですが。

将来的には、GAS を実行しなくても特定のカレンダーに予定を直接いれるようにしてほしいんですが、まーいつになるかわからないのでこんな感じで運用しています。
細々としたタスクが自動化されていくのは、本当に気持ちが良くありがたいことです。
いい時代に生まれたなぁ…。

さちこ

40代2児の母。2011年からフリーランスやってます。東京の東の方在住。
第一子が発達グレー男児で、彼が将来彼の妹に迷惑かけずに生きていけるよう、日々奮闘中です。

さちこをフォローする
スマートホーム
シェアする
さちこをフォローする

コメント

タイトルとURLをコピーしました