Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Tomokatsu-Sakamoto/c80e67f5d998b807999a7554d635f363 to your computer and use it in GitHub Desktop.
Save Tomokatsu-Sakamoto/c80e67f5d998b807999a7554d635f363 to your computer and use it in GitHub Desktop.
"use strict"; // 変数の宣言を強要する
const SUBJECT_TITLE = 'OCR Request'; // 処理対象となるメールの件名
const RESPONSE_TITLE = 'OCR Response'; // 返信メールの件名
const RETURN_MAIL = ''; // 返信先のメールアドレス
const DELETE_IMAGE = true; // 処理後に画像ファイルを削除する
const DELETE_DOCS = true; // 処理後に Google ドキュメントを削除する
const TRANSLATE_LANG = 'ja'; // 翻訳対象となる言語 'ja' : 日本語
const BCC2ME = true; // 自身に BCC で送信するか?
/**
* トリガー関数を設定するためのメニュー項目を設定
*/
function onOpen() {
let ui = SpreadsheetApp.getUi(); // Uiクラスを取得する
let menu = ui.createMenu('トリガー関数'); // Uiクラスからメニューを作成する
menu.addItem('トリガー関数を設定する', 'setTrigger'); // メニューにアイテムを追加する
menu.addToUi(); // メニューをUiクラスに追加する
}
/**
* トリガー関数を設定するためのメニュー項目を設定
*/
function setTrigger() {
let triggers = ScriptApp.getProjectTriggers();
let ret = null;
for (let i = 0; i < triggers.length; i++) {
if (triggers[i].getEventType() == 'CLOCK') {
// 登録しようとしているトリガーと同じタイプのものが既に登録されている
if (triggers[i].getHandlerFunction() == 'checkGmail') {
// 登録しようとしている関数と同じ名前
ret = triggers[i].getUniqueId();
console.info('既にトリガー関数が設定されている');
break;
}
else {
// 登録しようとしている関数とは違う関数が登録されている
console.warn('異なるトリガー関数が設定されているため、削除します');
ScriptApp.deleteTrigger(triggers[i]); // 現在設定されているトリガーを削除
break; // ここで既存のトリガーを削除し、チェックを終了することで、新規に登録される
}
}
}
// 登録しようとしているトリガーが設定されていなければ、新規に登録する
if (ret == null) {
// 登録されていないので登録する
let trigger = ScriptApp.newTrigger('checkGmail')
.timeBased()
.everyMinutes(5) // 5分間隔で実行する
.create();
ret = trigger.getUniqueId();
console.info('トリガー関数を設定しました');
}
}
/**
* Gmail の受信状況をチェックして、処理対象のメールがあるかをチェックする
*
* 参考:
* Google Apps ScriptでGmailの特定のメールを受信したらLINEと連携して通知する
* https://asatte.biz/gmail-line/
*/
function checkGmail() {
const ssId = SpreadsheetApp.getActiveSpreadsheet().getId();
const file = DriveApp.getFileById(ssId);
const folderId = file.getParents().next().getId(); // スプレッドシートの保存されているフォルダの ID を取得
let bccMail = ''; // BCC の送信先
if (BCC2ME == true) {
bccMail = Session.getActiveUser().getUserLoginId();
}
let findSubject = 'subject:(' + SUBJECT_TITLE + ') ';
// 指定された件名のスレッドを検索して取得(先頭 10件)
// https://developers.google.com/apps-script/reference/gmail/gmail-app#searchquery,-start,-max
let myThreads = GmailApp.search(findSubject, 0, 10);
// スレッドからメールを取得し二次元配列に格納
// https://developers.google.com/apps-script/reference/gmail/gmail-app#getmessagesforthreadsthreads
let myMessages = GmailApp.getMessagesForThreads(myThreads);
// https://developers.google.com/apps-script/reference/gmail/gmail-message
for (let i in myMessages) {
for (let j in myMessages[i]) {
//スターがないメッセージのみ処理
// https://developers.google.com/apps-script/reference/gmail/gmail-message#isstarred
if (!myMessages[i][j].isStarred()) {
let iCount = 0;
let strDate = myMessages[i][j].getDate(); // 送信日時
let strFrom = myMessages[i][j].getFrom(); // 差出人
let strSubject = myMessages[i][j].getSubject(); // 件名
let attachments = myMessages[i][j].getAttachments();
let strMessage = myMessages[i][j].getPlainBody().slice(0, 200);
if (RETURN_MAIL != '') { // 返信先が個別に指定されている?
strFrom = RETURN_MAIL; // 指定されているアドレスを宛先に指定
}
console.info('Date : ' + strDate);
console.info('From : ' + strFrom);
// 添付ファイルを確認
// https://developers.google.com/apps-script/reference/gmail/gmail-attachment
for (let k in attachments) {
// 添付されているファイルが画像ファイルであれば、OCR でテキスト化する
let fileName = attachments[k].getName(); // 添付ファイルのファイル名を取得
let type = attachments[k].getContentType(); // 添付ファイルの形式を取得
let types = type.split('/');
if (types[0] != 'image') {
console.info('添付されている ' + attachments[k].getName() + ' の形式は、' + type + ' で画像ファイルではありません。');
continue; // 画像ファイルでなければ、処理対象ではない
}
iCount++; // 処理対象の画像ファイルをカウント
console.info(iCount + ' : ' + fileName);
// 添付ファイルを、一旦ドライブに保存する
// https://developers.google.com/apps-script/reference/gmail/gmail-attachment#copyblob
let blob = attachments[k].copyBlob(); // 添付ファイルを blob として取得
let imageFile = DriveApp.getFolderById(folderId).createFile(blob); // blob を画像ファイルとして保存
imageFile.setName(strDate + ' ' + fileName); // 画像ファイルに名前を設定しておく
// 画像ファイルを、Google ドキュメントに貼り付けてテキスト化
const image = Drive.Files.copy( // 画像ファイルを OCR 機能でテキスト化
{ title: "tmp" },
imageFile.getId(),
{ "ocr": true, "ocrLanguage": "ja" }
);
const document = DocumentApp.openById(image.id);
document.setName(strDate + ' ' + fileName); // ファイル名を日付にしておく
const text = document.getBody().getText(); // OCR によってテキスト化されたデータを取得
// LanguageApp.translate 関数で指定した言語で翻訳する
// 参考:
// Google Apps Script(GAS)で翻訳する方法!英訳や和訳の実装(translateメソッド)
// https://auto-worker.com/blog/?p=2416
let transText = LanguageApp.translate(text, '', TRANSLATE_LANG); // 指定言語での翻訳
// テキスト化した内容をメールで返送する
const Draft = GmailApp.createDraft(
strFrom,
RESPONSE_TITLE,
`Date : ${strDate}
From : ${strFrom}
Subject : ${strSubject}
Attachment : ${fileName}
[ 元のテキスト情報 ]
----- ----- ----- ----- -----
${text}
----- ----- ----- ----- -----
[ 翻訳後のテキスト情報 ]
----- ----- ----- ----- -----
${transText}
----- ----- ----- ----- -----`,
{ name: 'Automatic Emailer Script', bcc: bccMail });
Draft.send();
// 作業用のファイルを削除する
if (DELETE_IMAGE == true) {
Drive.Files.remove(imageFile.getId()); // 画像ファイルを削除
}
if (DELETE_DOCS == true) {
Drive.Files.remove(image.id); // Google ドキュメントを削除
}
}
if (iCount == 0) { // メール中に処理対象の添付ファイルがなかった
const Draft = GmailApp.createDraft(
strFrom,
RESPONSE_TITLE,
`Date: ${strDate}\nFrom: ${strFrom}\nSubject: ${strSubject}\n\nメール中に翻訳対象となる画像ファイルが存在していませんでした。`,
{ name: 'Automatic Emailer Script', bcc: Session.getActiveUser().getUserLoginId() });
Draft.send();
}
// 処理済みのメッセージをスターをつける
myMessages[i][j].star();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment