Slide 1

Slide 1 text

RPA勉強会! Google Apps Talk #3 2021/08/27 1 〜GASでGmail活用術〜 ※ 本内容は個人的な見解であり、所属する組織と関係ありません。

Slide 2

Slide 2 text

自己紹介 Apachan @ApachanHonpo 埼玉県戸田市 宮城県仙台市 会社員&副業 2 お仕事...

Slide 3

Slide 3 text

宣伝 3 2021/3 発売 2020/5 発売 来春 改定版 発売予定 徹底解説 RPAツール WinActor導入・応用 完全ガ イド 絶対失敗しない!ロボット 1000体導入してわかった RPA成功の秘訣 Google Apps Script 目的別リファレンス 実践サンプルコード付き GAS本大幅リニューアルの方向で対応中

Slide 4

Slide 4 text

スタンス 4 ・業務効率化が主目的 ・ツール選定は是々非々 ・GASは超有効な手段のひとつ

Slide 5

Slide 5 text

参加者属性① - GASの経験 5 データソース: connpass申込時アンケート(n = 72) 2021/08/26時点

Slide 6

Slide 6 text

参加者属性② - RPAの経験 6 データソース: connpass申込時アンケート(n = 72) 2021/08/26時点

Slide 7

Slide 7 text

参加者属性③ - 職種 7 データソース: connpass申込時アンケート(n = 72) 2021/08/26時点

Slide 8

Slide 8 text

8

Slide 9

Slide 9 text

Google Apps Script 利用のきっかけ 9 日々システムの問い合わせに追われる毎日

Slide 10

Slide 10 text

Google Apps Script 導入後 10 定型の問い合わせをGASで自動化 約 80 % 残りは手動 全体的にレス ポンスが改善

Slide 11

Slide 11 text

Google Apps Scriptの特徴 11 ★ JavaScriptベースのプログラミング言語 ・RPAとは違ってコードの記述が必要 ・2020年2月にECMASCRIPT2015対応 ・Googleアプリ操作のクラスが充実 ・SlackなどのSaaSと相性が良い ・外部サイトのスクレイピングも可 ★ クラウドベースの実行環境 ・クライアントPCの操作は不可 ・クライアントPCへのインストール不要(激楽) ・クライアントPC起動有無に関わらず24時間スケジュール実行が可能 ・第3者との環境差分の考慮が不要 ★ 無償と有償アカウントの違い ・利用できる機能にほぼ差分なし ・メール送信数・実行時間などスクリプト実行制限に差分あり ※ Google Workspace導入企業であれば基本的に利用可能なケースが多い

Slide 12

Slide 12 text

Google Apps Scriptの構成 12 Advanced Google services Google WorkSpace services (Googleアプリ特有) Script Services (Googleアプリ共通) Standard built-in objects JS構文 演算子/関数/データ 型 etc DOM/Window Object etc Google Apps Script JavaScript ※ 2020年2月よりECMASCRIPT2015対応

Slide 13

Slide 13 text

注意点 13 ・ローカル環境の操作は一切できない ・利用制限を超えるとスクリプトが実行できなくなる ex )6分/回 ・ごく稀にサーバー側の不具合でことごとくエラーがでることがある

Slide 14

Slide 14 text

考察① RPAとの棲み分け 14 RPAとの棲み分け整理で保守運用が安定 ローカル環境
 クラウド環境
 Googleアプリ内の操作や SaaS連携はGAS, それ以外 はRPAにおまかせ★ GUI操作のSaaS連携は超カ ンタン!細かい処理は有償 プランや対応外!?

Slide 15

Slide 15 text

考察② アプリ開発 15 ノーコード/ローコードツールの可能性を拡大

Slide 16

Slide 16 text

考察③ GIGAスクール構想 16 小学生からGoogle Apps主体の教育現場

Slide 17

Slide 17 text

現在のGASアウトプット活動 17 週1回朝活でライブコーディング実施 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 #01 #02 #03 #04 #05 #06 #07 #08 #09 #10 #11 #12 #13 #14 #15 #16 #17 #18 難易度 活用度

Slide 18

Slide 18 text

実施内容 18 #01 ~ 二次元配列①(concat()/データ結合) #02 ~ 二次元配列②(スプレッド構文) #03 ~ 二次元配列③(破壊メソッド/非破壊メソッド/shift()/push()/pop()) #04 ~ 分割代入/アロー関数 #05 ~ 反復メソッド(map()/filter()) #06 ~ フォームの扱い①(基本の作成方法/イベントオブジェクトの構造) #07 ~ フォームの扱い②(オブジェクトの取り扱い/残余引数) #08 ~ フォームの扱い③( FormResponseオブジェクト/Slackへの通知) #09 ~ フォームの扱い④(特定の設問と回答のみ抽出する方法) #10 ~ SSに編集があった際のイベントオブジェクト扱い/転記処理 #11 ~ HTMLメール①( HTML/CSSとは?/CSSの扱い方) #12 ~ HTMLメール②( HTMLへの変数の埋め込み/表形式) #13 ~ ワークフロー①(フォームからHTMLメールを送信) #14 ~ ワークフロー②(URL(リクエスト)に対応した処理作成 ※ 承認/否認各々の処理) #15 ~ ライブラリの使い方 #16 ~ Gmail①(GmailAppクラス) #17 ~ Gmail②(本文抽出) #18 ~ Gmail③(重複メールの除去)

Slide 19

Slide 19 text

19

Slide 20

Slide 20 text

今回のテーマ Gmailの活用術 20

Slide 21

Slide 21 text

前回との違い 21 https://www.youtube.com/watch?v=IAqiyIG8Ujc 前回 #2 メールの送信 今回 #3 受信メールの監視

Slide 22

Slide 22 text

受信メールの監視 想定業務 22 ・問い合わせメールの管理 ・多数の返信が発生する案件管理 ・メールをチャットへカスタマイズして転送 ...etc

Slide 23

Slide 23 text

GASとRPA(RDA)との違い 23 RPA(RDA) GAS クライアント ローカルPC、もしくは仮想環境の起動 が必須 電源ON Googleサーバー上動作のためクライア ント環境不要 電源OFF ライセンス 必要 ※ 頻度が高いほど占有 不要 ※ 別途制限あり GmailのUI変更 影響あり 影響なし

Slide 24

Slide 24 text

GmailAppサービス概要 24 GmailMessage GmailThread GmailApp

Slide 25

Slide 25 text

25 GmailThreads GmailMessages GmailThreads[0] GmailThreads[1] GmailThreads[2] GmailThreads[3] GmailThreads[4] GmailMessages[0] GmailMessages[0] GmailMessages[0] GmailMessages[0] GmailMessages[0] GmailMessages[1] GmailMessages[1] GmailMessages[2] ※ イメージ図 GmailMessageは必ずGmailThreadの中!

Slide 26

Slide 26 text

26 Let's Try 特定メールをスプレッドシートに書出す! Step ToDo 事前準備 検索対象メールの送信 ① 受信メールの検索条件の設定 ② 検索条件にマッチするGmailThreadsの取得 ③ GmailThreadsからGmailMessageの取得 ④ メールID、受信日時、件名、差出人、本文などシート最終行に追加 ⑤ トリガーの設定 ⑥ 試実行 → 重複メールの対処が必要 ⑦ 重複メールの除外 おまけ 本文からテキスト抽出

Slide 27

Slide 27 text

事前準備 検索対象メールの送信 27 件名 本文 発送依頼202108271900 ご担当者様 お疲れ様です。 以下ご対応お願いします。 発送先:名古屋 発送物:大型什器2、丸テーブル1 種別:緊急 備考:着払い よろしくお願いします。 自分自身 に セット テキストはコチラ

Slide 28

Slide 28 text

Step① 受信メールの検索条件の設定 28 newer_than演算子を活用して対象の絞り込み Gmailの検索演算子

Slide 29

Slide 29 text

Step② 検索条件にマッチするGmailThreadsの取得 29 function myFunction(){ const threads = GmailApp.search('Step①で作成した検索条件'); Logger.log(threads); // [GmailThread, GmailThread, GmailThread, ...] } ※ 本スクリプトを実行するアカウントに紐付く受信メールが検索対象になります。

Slide 30

Slide 30 text

Step③ GmailThreadsからGmailMessageの取得 30 function myFunction(){ const threads = GmailApp.search('Step①で作成した検索条件'); Logger.log(threads); // [GmailThread, GmailThread, GmailThread, ...] for(const thread of threads){ const messages = thread.getMessages(); Logger.log(messages); // [GmailMessage, GmailMessage, ...] const message = messages[0] } }

Slide 31

Slide 31 text

Step④ 各種情報のシート最終行追加 31 // for ブロックの中 for(const thread of threads){ const messages = thread.getMessages(); const message = messages[0] const mailId = message.getId(); const mailDate = message.getFrom(); const mailBody = message.getPlainBody(); const sh = SpreadsheetApp.getActivesheet(); sh.appendRow([mailId, mailDate, mailBody]); }

Slide 32

Slide 32 text

Step⑤ トリガーの設定 32 画面操作で設定OK! 1 2 3 4 5

Slide 33

Slide 33 text

Step⑥ 重複メールの対処が必要 33 重複 重複 重複

Slide 34

Slide 34 text

Step⑦ 重複メールの除外 3パターン 34 項目 ① トリガー実行間隔調整 ② メールIDの活用 ③ プロパティストアの活用 内容 検索時に遡る時間とトリ ガーの時間間隔を合わせる 処理したメールのIDと重複 しないものを処理 処理したメールの受信日時 のプロパティストアに保存 記述量 少 中 多 正確性 秒単位のタイムラグがある あるため漏れ発生の可能性 あり 同一アカウントで実行する 限りは正確 秒単位で複数メール受信し ている場合は漏れ発生の可 能性あり その他 メールチェックのタイミン グは1時間以下にはできない Message-IDを利用すれば複 数名での運用もOK 様々なケースで応用が可能

Slide 35

Slide 35 text

Step⑦ メールIDによる重複除外 35 // (続)for ブロックの中 // 既存IDの取得 const cols = sh.getRange(1, 1, sh.getLastRow(), 1).getValues(); console.log(cols); const col = cols.flat(); console.log(col); // 既存IDに新しく取得したメールIDが存在しなければ... if(!col.includes(mailId)){ // 最終行に挿入 sh.appendRow([mailId, mailDate, mailBody]); }

Slide 36

Slide 36 text

おまけ 本文からテキスト抽出 36 // 本文(mailBody)からのテキスト抽出 // 正規表現を使って「名前」と「改行改行」の間の文字列を取得 const part = mailBody.match(/発送先([\s\S]*?)\r\n\r\n/)[0]; // 中身チェック console.log(part); // テキスト抽出 const str01 = part.split('発送先:')[1].split('\r\n')[0]; const str02 = part.split('発送物:')[1].split('\r\n')[0]; const str03 = part.split('種別:')[1].split('\r\n')[0]; const str04 = part.split('備考:')[1].split('\r\n')[0];

Slide 37

Slide 37 text

End Of File 37