Google App Script LINE データ管理

【GAS】画像のテキスト抽出ーOCR(6) LINE UIにメール送信機能追加

はじめに

今回は、前回までに作成したLINEを使ったOCRにメール送信機能を追加します。

今日の課題は前回と同様です。

今日の課題

  • LINEで画像を送ったら画像中の文字をテキストとして抽出した結果をメッセージで取得し、指定したメールアドレスに送信したい。

では、実現方法を見ていきましょう。

その前におさらい

初めてこの記事を見る方は、以下の5つの記事を確認することをお勧めします。

今回の追加機能

前回紹介したコードにメール送信機能を追加します。

メール送信機能は以下の関数で実現します。

function sendMail(fileId, mailAddress, title, text){
    var blb = DriveApp.getFileById(fileId).getBlob();
    var options = {
      "attachments":blb,
      };
    MailApp.sendEmail(mailAddress, title, text, options);
}

OCR対象の画像ファイルのIDと、送信先メールアドレス、メールのタイトル、OCR結果の文字をこのsendMail()関数に渡すことで、指定したメールアドレスに画像とOCR結果を送信します。

この関数を、メイン関数であるdoPost()のOCR処理後に呼び出します。

実装コード

全てのコード

以下にGoogle Apps Scriptの全てのコードを示します。

コード中の3か所で指定している以下のIDはご自分の環境に合わせて置き換えてください。

  • <チャネルアクセストークンを指定>
  • <Google Driveの画像保存フォルダIDを指定>
  • <ログ出力用スプレッドシートのIDを指定>
// LINE Messaging API チャネルアクセストークン
var LINE_ACCESS_TOKEN = '<チャネルアクセストークンを指定>';

// 画像保存フォルダID
var GOOGLE_DRIVE_FOLDER_ID = '<Google Driveの画像保存フォルダIDを指定>';

// logOut用
var PRJ_NAME = 'LineOCR';

//LINE Messaging APIからのPOST受信処理
function doPost(e){
  try{
    if (typeof e === "undefined"){
      return;
    } 

    //JSON文字列解析
    var json = JSON.parse(e.postData.contents);
    var replyToken = json.events[0].replyToken;
    var messageId = json.events[0].message.id;
    var messageType = json.events[0].message.type;

    //画像以外は動作終了
    if(messageType !== "image"){
      sendMessage(replyToken, '画像を送信してください');
      return;
    }

    var LINE_END_POINT = "https://api-data.line.me/v2/bot/message/" + messageId + "/content";
    var fileId = saveImage(LINE_END_POINT);
    var text = ocr(fileId);
    logOut(PRJ_NAME, 'ocr text: ' + text);

    // メッセージ送信
    sendMessage(replyToken, text);

    // メール送信
    var now = new Date();
    var title = Utilities.formatDate(now, 'Asia/Tokyo', 'yyyy/MM/dd hh:mm ');
    sendMail(fileId, 'ayikes@gmail.com', title, text);

    // 保存画像削除
    Drive.Files.remove(fileId);
  }
  catch(e){
    logOut(PRJ_NAME, 'doPost():' + e.message);
  }
}

// Blob形式で画像取得
function saveImage(LINE_END_POINT){
  var now = new Date();
  var formattedDate = Utilities.formatDate(now, 'Asia/Tokyo', 'yyyyMMdd_hhmmss')

  try {
    var url = LINE_END_POINT;
    var headers = {
      "Content-Type": "application/json; charset=UTF-8",
      "Authorization": "Bearer " + LINE_ACCESS_TOKEN
    };

    var options = {
      "method" : "get",
      "headers" : headers,
    };

    // 画像ファイル保存
    var res = UrlFetchApp.fetch(url, options);
    var imageBlob = res.getBlob().getAs("image/png").setName(formattedDate + ".png");
    var folder = DriveApp.getFolderById(GOOGLE_DRIVE_FOLDER_ID);
    var file = folder.createFile(imageBlob);

    return file.getId();
  } 
  catch(e) {
    logOut(PRJ_NAME, 'saveImage(): ' + e.message);
  }
}

// OCR処理
function ocr(srcId){
  try{
    // 一時ファイル名
    var resource = {
      title: "tmp"
    };

    // OCR設定
    var option = {
      "ocr": true,        // OCRを行う
      "ocrLanguage": "ja",// OCRの言語設定
    }

    // OCR処理を行う
    var image = Drive.Files.copy(resource, srcId, option);      // ファイルコピー(OCR処理実施)
    var text = DocumentApp.openById(image.id).getBody().getText();  // OCRテキスト取得

    // 一時ファイル削除
    Drive.Files.remove(image.id);

    return text;
  }
  catch(e){
    logOut(PRJ_NAME, 'ocr(): ' + e.message);
  }
}

// メッセージ送信
function sendMessage(replyToken, text){
  var replyUrl = "https://api.line.me/v2/bot/message/reply";
  var headers = {
    "Content-Type": "application/json; charset=UTF-8",
    "Authorization": "Bearer " + LINE_ACCESS_TOKEN
  }; 

  var postData = {
    "replyToken": replyToken,
    "messages": [{
                  "type": "text",
                  "text": text
                  }]
  };

  var options = {
    "method" : "post",
    "headers" : headers,
    "payload" : JSON.stringify(postData)
  };

  UrlFetchApp.fetch(replyUrl, options);
}

function logOut(prjName, msg) {
  var id = '<ログ出力用スプレッドシートのIDを指定>';
  var spreadsheet = SpreadsheetApp.openById(id);
  var sheet = spreadsheet.getSheets()[0];
  sheet.appendRow([new Date(), prjName, msg]);
}

function sendMail(fileId, mailAddress, title, text){
    var blb = DriveApp.getFileById(fileId).getBlob();
    var options = {
      "attachments":blb,
      };
    MailApp.sendEmail(mailAddress, title, text, options);
}

また、以下に注意してください。

コードを実行する前に、サービスに「Drive API」を追加することを忘れないようにしましょう。

コードを記述したらデプロイしてWebアプリとして公開しましょう。

実行

以下の画像をLINEに投稿して文字列が応答メッセージとして返ってくるか確認します。

投稿してから数秒待つと、以下のように抽出した文字を応答メッセージとして得ることができます。

また、以下のようにメールも送信されました。

まとめ

いかがでしたでしょうか。

もう、メールを送信する処理もお手の物ですね。

メールアドレスをEvernoteの転送先アドレスにすれば、Evernoteに自動的にノート追加もできます。

これにより、OCRの結果をすぐに手に入れられてかつ、メールやEvernoteにデータも蓄積できる状況を作ることができました。

メールアドレスの追加修正などの機能追加もそれほど難しくはないので、興味のある方は実装を考えてみるのも楽しいかと思います。

では、今日もよい一日を。

-Google App Script, LINE, データ管理
-, , ,