[サイトリニューアル]記事URLが変更になりました。旧URLへのアクセスはトップページへ転送されます。お探しの記事は「サイト内検索」をご利用ください。

LINE処方箋自動印刷システム自作(第2回:GAS設定編 ~Googleドライブをつなぐ~)

薬局とIT
スポンサーリンク

今回やること:システムの「脳みそ」を作る

前回はシステムの全体像をお話ししました。

今回からいよいよ手を動かしていきます。 まずは、LINEから送られてきた画像を受け取り、Googleドライブへの保存と患者さんに自動返信する「プログラム(GAS)」の部分です。

「プログラムを書く」と言っても安心してください。AIが用意してくれたコードを「コピペ」するだけで終わります。 重要なのは、コードの中身よりも「設定の手順」です。ここにはいくつか必ずハマる落とし穴がありますので、併せて紹介します(私自身がハマったところでもあります)。

手順1:Googleドライブに「受信箱」を作る

まずは、処方箋画像が保存されるフォルダを作ります。

薬局のGoogleアカウントでGoogleドライブを開きます。

新規フォルダを作成し、名前を付けます(例:Rx_Inbox など)。私の環境では受け付けた画像をまずRx_Inboxフォルダに入れ、印刷が済んだものをRx_Doneフォルダへ移動するという流れにしたので、2つのフォルダを作成しました。

【重要】処方箋画像を保存するためのフォルダID(Rx_Inboxの方)を控える
作成したフォルダを開いた状態で、ブラウザのURLバー(アドレスバー)を見てください。 https://drive.google.com/drive/folders/XXXXXXXXXXX…
この末尾の英数字の羅列(今はXXXX…に書き換えてあります)が、このフォルダの住所(ID)です。後で使うので、どこかにメモしておいてください。

「XXXXXX」に該当する部分がフォルダのIDです

手順2:Google Apps Script (GAS) を開く

Googleドライブの「新規」ボタン > 「その他」 > 「Google Apps Script」 をクリックします。

新しいタブで、コードを書く画面が開きます。

プロジェクト名(「無題のプロジェクト」となっている場所)をクリックし、わかりやすい名前(例:LINE_Rx_System)に変更します。

手順3:コードをコピペする

元々書いてあるコード(function myFunction…)をすべて消して、以下のコードをまるっと貼り付けてください。

// ▼▼▼ 設定エリア ▼▼▼

// LINE Developersで取得した「チャネルアクセストークン(長期)」を貼り付ける
const LINE_ACCESS_TOKEN = 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ';

// GoogleDrive「Rx_Inbox」のフォルダID
const FOLDER_ID = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; 

// ▲▲▲ 設定エリア終了 ▲▲▲


function doPost(e) {
  const json = JSON.parse(e.postData.contents);
  const events = json.events;

  events.forEach(function(event) {
    // 画像メッセージの場合のみ処理
    if (event.type === 'message' && event.message.type === 'image') {
      const messageId = event.message.id;
      const replyToken = event.replyToken;
      const userId = event.source.userId; 
      
      try {
        // 1. Googleドライブに保存
        saveImageToDrive(messageId);
        
        // 2. カウンター付き自動返信
        sendReplyWithCounter(replyToken, userId);
        
      } catch (error) {
        console.error('Error:', error);
      }
    }
  });
  
  return ContentService.createTextOutput(JSON.stringify({'content': 'post ok'})).setMimeType(ContentService.MimeType.JSON);
}

function saveImageToDrive(messageId) {
  const url = 'https://api-data.line.me/v2/bot/message/' + messageId + '/content';
  const options = {
    'method': 'get',
    'headers': {
      'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN
    }
  };
  
  const response = UrlFetchApp.fetch(url, options);
  // ファイル名に日時をつけて重複回避
  const fileName = 'rx_' + Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyyMMdd_HHmmss') + '.jpg';
  const imageBlob = response.getBlob().setName(fileName);
  
  // 指定フォルダ(Rx_Inbox)に保存
  const folder = DriveApp.getFolderById(FOLDER_ID);
  folder.createFile(imageBlob);
}

function sendReplyWithCounter(replyToken, userId) {
  const cache = CacheService.getScriptCache();
  let count = cache.get(userId);
  
  if (!count) {
    count = 1;
  } else {
    count = parseInt(count) + 1;
  }
  
  // カウントを更新(有効期限は60秒)
  cache.put(userId, count.toString(), 60);
  
  // 3枚目までは返信する
  if (count <= 3) {
    const messageText = `送信いただいた処方箋画像を受け付けました(${count}枚目)。\nお薬の準備をいたします。\n\n※このメッセージはシステムによる自動応答です。`;

    const url = 'https://api.line.me/v2/bot/message/reply';
    const payload = {
      'replyToken': replyToken,
      'messages': [{
        'type': 'text',
        'text': messageText
      }]
    };
    
    const options = {
      'method': 'post',
      'headers': {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + LINE_ACCESS_TOKEN
      },
      'payload': JSON.stringify(payload)
    };
    
    UrlFetchApp.fetch(url, options);
  }
}

貼り付けたら、上部の FOLDER_ID の部分(’…’の中身)を、先ほどメモしたフォルダIDに書き換えて、フロッピーアイコン(💾)を押して保存します。

※LINE_ACCESS_TOKEN は次回設定するので、今はそのままでOKです。

実は私も何が書いてあるのかさっぱり分かりませんが、ところどころ日本語のところがあるので、それを見るとなんとなくイメージしてもらえるでしょうか。画像名が重複しないようにしてあるところと、連続して画像が送付された場合の挙動についても、AIに希望を伝えて反映してもらってあります。

システムによる自動返信であることは、しっかりと入れたほうがいいです。というのも、LINEの画像を取りに行くのはトークルームではなく、別の画像サーバーなので、処方箋を送った患者さんからすると「既読がついていないのに、薬局からメッセージが返ってきた」状態になるからです。

「const messageText」の部分が、実際に自動で返信される文言ですので、必要に応じてここを書き換えます。薬局で画像を確認後(=既読がついた後)、アプリやwebからメッセージを送ることももちろんできますので、その段階で調剤の進捗状況や不足薬がある場合の対応などを伝えることになります。

手順4:最大の難所「デプロイ」

ここが一番の難所かもしれません。 このプログラムを外部(LINE)からアクセスできるように公開(デプロイ)するのですが、権限設定を間違えると動きません。

右上の 「デプロイ」 ボタン > 「新しいデプロイ」 をクリック。

左上の歯車アイコン > 「ウェブアプリ」 を選択。

【最重要】ここを間違えないで!

説明: 「処方箋システム v1」など適当に。

次のユーザーとして実行: 「自分」 (お使いのGoogleアカウント)

アクセスできるユーザー: 「全員」 (Anyone)

「デプロイ」 ボタンをクリック。

アクセスできるユーザーを「全員」に

アクセス承認の画面が出たら、「アクセスを承認」→「詳細」→「(安全ではないページ)に移動」と進んで許可してください。

手順5:ウェブアプリURLをコピー

デプロイが完了すると、長ーいURL(https://script.google.com/macros/s/…/exec)が表示されます。 これが、このプログラムの「玄関の住所」 です。

「コピー」 ボタンを押して、このURLを大切に保管してください。次回のLINE設定で使います。

今回のまとめ

これで、Googleドライブ側に「受け入れ態勢」が整いました。 今はまだ、LINEと繋がっていないので何も起きませんが、裏側の仕組み(脳みそ)は完成です。

次回は、いよいよLINE側の設定(LINE Developers)を行い、このシステムと接続します!

第3回予告: LINE Developers の設定編 ~Botを動かすための準備~

おまけ

この仕組みが動く前提として、メッセージを送られただけでは作動せず、画像が送られてきて初めて印刷されるように組み立ててあります。じゃあ処方箋ではない画像が来たらどうするのかと疑問に思いますよね。

薬局のアカウントなので、プライベートな写真やいたずらで送られてくることはまずないでしょうという見込みで、それについての対策は現状何もしていません。ただ仕組みとしては、ここにAIを噛ませて、送られた画像が処方箋かどうかを判定して、その結果印刷するかどうか振り分けるということも可能なはずです。実証・検証はしていませんし、これよりも高度になります。システムも重くなりますので、もしその必要性が出てきたらその時に考えたいと思います。

Anout us

このブログを書いている人
くま☆

薬局で働く薬剤師
「薬局のオモテとウラ」(2006~)
日経DI:熊谷信の「薬剤師的にどうでしょう」連載中(2009~)
詳しくはこちら

くま☆をフォローする

コメント

定期購読にオススメの1冊


調剤と情報 薬局 Rp.+(レシピプラス) 日経DI 月刊薬事
タイトルとURLをコピーしました