この記事をおすすめする人
- 仕事で業務効率化を頼まれてどうしていいかわからない人
- GASの存在は知っているけど、使い方がわからない人
- GASでできる幅を増やしてみたい人
Google Apps Script(GAS)とは
Google Apps Script(GAS)は、Googleが作ったJavaScriptをベースとしたスクリプトサービスで、Googleのサービス群(スプレッドシート、Googleフォーム、Slackなど)との連携を簡単に実現することができるサービスである。
GASでできること
- Google SpreadSheetのデータの読み書き
- Google Formの回答共有
- Gmailの操作(送信、受信メールの内容共有など)
-
Slackへのメッセージ投稿
などなど
(リンクから該当部分に飛べます👍)
Google SpreadSheetの操作方法
GASの開き方
Google SpreadSheetを操作するためのコード
(前提として、全てのコードが上から順に繋がっていると思ってください!!)
〜〜〜下準備〜〜〜
const ss = SpreadsheetApp.getActiveSpreadsheet()
const sheet = ss.getSheetByName('シート名(下のタブのところの名前)')
〜〜〜各種コード〜〜〜
var values = sheet.getDataRange().getValues()
// 出力:[["A1", "B1"], ["A2", "B2"]]
// シートの指定はsheetで指定したシートが参照される
sheet.getRange(1, 1).setValue("書き込みたい内容")
// 数字は順に行、列の番号(ex. A1→1,1 / B1→1,2)
// 「=」から始めれば関数も入れられる
sheet.getRange(1, 1, 2, 2).setValues(2次元配列)
// 数字は順に変更対象の開始行、列、終了の行、列の番号
// (ex. A1:B2→1,1,1,2 / C3:D5→3,3,5,4)
【注意事項】
setValuesの引数には、セルをいくつ選択して更新するにしても必ず2次元配列である必要がある
〜〜〜番外編〜〜〜
// 通常は以下のコードでGASを開いたGoogle SpreadSheetと繋がる
const ss = SpreadsheetApp.getActiveSpreadsheet()
// 以下のコードで他のGoogle SpreadSheetと繋げられる
const ss = SpreadsheetApp.openById("Google SpreadSheetのID")
【IDについて】
Google SpreadSheetのIDは、Google SpreadSheetのURLに含まれている
https://docs.google.com/spreadsheets/d/< ここの部分がIDになっている >/edit#gid=0
// 下準備
const ss = SpreadsheetApp.getActiveSpreadsheet()
const sheet = ss.getSheetByName('シート名(下のタブのところの名前)')
// 各種コード
var values = sheet.getDataRange().getValues()
sheet.getRange(1, 1).setValue("書き込みたい内容")
// 番外編
const ss = SpreadsheetApp.getActiveSpreadsheet()
const ss = SpreadsheetApp.openById("Google SpreadSheetのID")
Google Formの操作方法
GASの開き方
Google Formを操作するための方法・コード
初期設定(絶対必要)
①関数の作成(フォームが回答された時に実行したいやつです!)
function onFormSubmit(e){
console.log(e)
}
// 引数(括弧の中)に回答内容などの回答に関する情報が格納される
引数(括弧の中)には「e」などの変数を必ず入れること
②画面の保存ボタンでの保存(フロッピーみたいなやつ)
③トリガーを開く
⑤トリガーの設定をし、保存する
項目名 | 選択肢 |
---|---|
実行する関数を選択 | 実行させたい関数名 |
実行するデプロイを選択 | Head |
イベントのソースを選択 | フォームから |
イベントの種類を選択 | フォーム送信時 |
(もし画面が切り替わった場合)
⑥「Choose an account」でGoogleアカウントを選択
⑦「Allow」を選択
〜〜〜各種コード〜〜〜
function onFormSubmit(e){
console.log(e)
}
// 変数eの内容
{ toString: [Function],
authMode:
{ toString: [Function: toString],
name: [Function: toString],
toJSON: [Function: toString],
ordinal: [Function: ordinal],
compareTo: [Function: compareTo],
NONE:
{ toString: [Function: toString],
name: [Function: toString],
toJSON: [Function: toString],
ordinal: [Function: ordinal],
compareTo: [Function: compareTo],
NONE: [Circular],
CUSTOM_FUNCTION: [Object],
LIMITED: [Object],
FULL: [Circular] },
CUSTOM_FUNCTION:
{ toString: [Function: toString],
name: [Function: toString],
toJSON: [Function: toString],
ordinal: [Function: ordinal],
compareTo: [Function: compareTo],
NONE: [Object],
CUSTOM_FUNCTION: [Circular],
LIMITED: [Object],
FULL: [Circular] },
LIMITED:
{ toString: [Function: toString],
name: [Function: toString],
toJSON: [Function: toString],
ordinal: [Function: ordinal],
compareTo: [Function: compareTo],
NONE: [Object],
CUSTOM_FUNCTION: [Object],
LIMITED: [Circular],
FULL: [Circular] },
FULL: [Circular] },
response:
{ toString: [Function],
submit: [Function],
getTimestamp: [Function],
getId: [Function],
getRespondentEmail: [Function],
getItemResponses: [Function],
getGradableItemResponses: [Function],
getResponseForItem: [Function],
getGradableResponseForItem: [Function],
withItemResponse: [Function],
withItemGrade: [Function],
toPrefilledUrl: [Function],
getEditResponseUrl: [Function] },
source:
{ toString: [Function],
getId: [Function],
removeViewer: [Function],
addViewers: [Function],
addViewer: [Function],
getViewers: [Function],
submitGrades: [Function],
setAcceptingResponses: [Function],
createResponse: [Function],
setShowLinkToRespondAgain: [Function],
setProgressBar: [Function],
addScaleItem: [Function],
addCheckboxItem: [Function],
addCheckboxGridItem: [Function],
addGridItem: [Function],
addListItem: [Function],
addMultipleChoiceItem: [Function],
addPageBreakItem: [Function],
addParagraphTextItem: [Function],
addSectionHeaderItem: [Function],
addTextItem: [Function],
addDateItem: [Function],
addDateTimeItem: [Function],
addTimeItem: [Function],
addDurationItem: [Function],
addImageItem: [Function],
addVideoItem: [Function],
setAllowResponseEdits: [Function],
canEditResponse: [Function],
setCollectEmail: [Function],
collectsEmail: [Function],
setRequireLogin: [Function],
hasProgressBar: [Function],
getConfirmationMessage: [Function],
getDestinationType: [Function],
getSummaryUrl: [Function],
getItemById: [Function],
getPublishedUrl: [Function],
isAcceptingResponses: [Function],
isPublishingSummary: [Function],
hasRespondAgainLink: [Function],
removeDestination: [Function],
setCustomClosedFormMessage: [Function],
getCustomClosedFormMessage: [Function],
setConfirmationMessage: [Function],
setDestination: [Function],
setPublishingSummary: [Function],
setLimitOneResponsePerUser: [Function],
hasLimitOneResponsePerUser: [Function],
setShuffleQuestions: [Function],
getShuffleQuestions: [Function],
shortenFormUrl: [Function],
getResponses: [Function],
deleteAllResponses: [Function],
deleteResponse: [Function],
requiresLogin: [Function],
isQuiz: [Function],
deleteItem: [Function],
getEditUrl: [Function],
moveItem: [Function],
setIsQuiz: [Function],
setTitle: [Function],
getDestinationId: [Function],
getTitle: [Function],
setDescription: [Function],
getResponse: [Function],
getItems: [Function],
getDescription: [Function],
removeEditor: [Function],
addEditor: [Function],
addEditors: [Function],
getEditors: [Function] },
triggerUid: '22652169' }
function onSubmit(e){
const itemResponse = e.response.getItemResponses()
for (var i = 0; i < itemResponse.length; i++){
var formData = itemResponse[i]
// 質問文
var title = formData.getItem().getTitle()
// 回答内容
var response = formData.getResponse()
}
}
// 変数eの中のresponseの中のgetItemResponses()に回答内容が入っている
質問種類ごとに受け取る回答の型が違う
質問種類 | 回答の受け取り型 | 例 |
---|---|---|
ラジオボタン | 文字列 | 選択肢 1 |
チェックボックス | 配列 | [ '選択肢 1', '選択肢 2' ] |
プルダウン | 文字列 | 選択肢 1 |
記述式 | 文字列 | HelloWorld |
段落 | 文字列 | HelloWorld |
均等目盛 | 文字列 | 3 ←目盛名が入っている |
選択式(グリッド) | 配列 | [ '2 列目', '1 列目' ] ←列名が入っている |
日付 | 文字列 | 2024-01-01 |
時刻 | 文字列 | 00:00 |
※配列は回答が1つでも必ず配列の形で変えされる
【Tips】
console.log()で確認すると便利(詳細は番外編で!)
〜〜〜番外編〜〜〜
console.log()
// console.logの引数に入れたものの中身を確認できる
// 変数などなんでもできる
// Logger.log()も同じ(少し違いはあるが大きな違いはないので割愛)
console.log()の結果の見方
- 左側のタブから3本線のようなもの(実行数)を選択する
- 実行された結果が一覧に出るので、結果を見たいものを選択しクリックする
- console.log()の結果が表示される
Slackと連携する方法
初期設定
- Webでこのページ(https://slack.com/intl/ja-jp/apps)を開く(ログインが必要な場合はログインする)
- 右上のプルダウンから連携したいワークスペースを選択する
- 右上の「管理」を押して新しい画面へ移る
- 左側のタブの「カスタムインテグレーション」を選択する
- 「Incoming Webhook」をクリックする(ない場合は、画面上部の検索欄から検索してる追加する)
- 「Slackに追加」を押して、次の画面でチャンネルを選択し、「Incoming Webhook インテグレーションの追加」をクリック
- 表示された「Webhook URL」をコピーする(これがとても大事)
Slackへメッセージを送るコード
function sendToSlack(){
const url = "<上でコピーしたWebhook URLを入れる>"
var message = "<送りたい文章を入れる>"
var jsonData = {
"text" : message
}
var options =
{
"method" : "POST",
"contentType" : "application/json",
"payload" : JSON.stringify(jsonData)
}
UrlFetchApp.fetch(url, options)
}
// 実行するとmessageに格納した内容がWebhook URLを発行した時に選択したチャンネルに流れる
function sendToSlack(){
const url = "<上でコピーしたWebhook URLを入れる>"
var message = "<送りたい文章を入れる>"
var username = "<通知の時に表示したい名前を入れる>"
var channel = "<送る先のチャンネルを入れる ex)#general>"
var icon = "<通知の時に表示したいアイコンを入れる ex):white_check_mark:>"
var jsonData = {
"username" : username,
"channel" : channel,
"text" : content,
"icon_emoji" : icon
}
var options =
{
"method" : "POST",
"contentType" : "application/json",
"payload" : JSON.stringify(jsonData)
}
UrlFetchApp.fetch(url, options)
}
// 絶対にusername、channel、iconを必ず埋めなければいけないわけではないので、
// 適宜削除しても大丈夫
アイコンは、Slackのスタンプならなんでも入る
アイコンは、Slackのメッセージで絵文字の部分にカーソルを当ててコピーすると例のように「:」で囲まれた文字が取得でき、それを用いる
<@メンバーID>
// 出力:@Yamashita
// 以上の文字列を入れることでメンションできる
メンバーIDは、Slack上でメンバーIDを取得したい人のプロフィールを開き、右側にある「3つの点」をクリックして「メンバーID をコピー」を選択すると取得できる
(↑わからなければググってみてください😭いい記事ありそうです…)
// *太文字*
// _イタリック_
// ~取り消し線~
// `コード`
// ```コードブロック```
// >引用
// \n(これで改行できる)
詳細は、こちら(https://slack.com/intl/ja-jp/help/articles/202288908-メッセージの書式設定)などを参考に〜〜
Gmailを操作する方法
初期設定
- GASのホームから新しいプロジェクトを作成(Google SpreadSheetに紐づいたGAS等でも大丈夫!)
以上!(とりあえずプロジェクトを作成してください〜〜)
Gmailを操作するためのコード
〜〜〜各種コード〜〜〜
GmailApp.sendEmail("送信先メールアドレス", "メールのタイトル", "メールの本文")
// varとかつけなくて大丈夫です👍
上のコードを実行することで実行したGoogleアカウント(トリガーの場合はトリガーを設定したアカウント)からメールが送信される!
【注意事項】
「実行の成功」 = 「送信成功」ではなく、送信できたかどうか別途確認する必要がある!
// 検索条件に合うメールのグループ一覧の取得(返信のメールなどの特定のメールに紐づいたメールは分割されずに1つのグループになって扱われる)
var threads = GmailApp.search("検索条件")
// グループになっているメールを1つづつ取り出していく
for(var i=0; i<threads.length; i++) {
var messages = threads[i].getMessages();
for(var j = 0; j < messages.length; j++) {
// これが1つ1つのメール
var message = messages[j]
// 個々のメールのタイトル、本文、日付
var subject = message.getSubject()
var body = message.getPlainBody()
var date = Utilities.formatDate(message.getDate(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss')
}
}
【検索条件について】
-
Gmailを開いて検索窓の右側の3本線を開いて検索条件を入力する
(Gamilの検索窓を使わずとも検索条件を設定できるが、検索窓を使うのが一番早いのでおすすめ👍)
メール送信同様、実行したGoogleアカウント(トリガーの場合はトリガーを設定したアカウント)かのメールボックスが参照される!
〜〜〜番外編〜〜〜
// -------------------------------------------------------
// メール送信部分
var email = "送信先のメールアドレス"
var subject = "メールのタイトル"
var body = "メールの本文"
// メールを送信
GmailApp.sendEmail(email, subject, body)
// -------------------------------------------------------
// -------------------------------------------------------
// 送信確認の部分
var email = "送信先のメールアドレス"
var subject = "メールのタイトル"
var body = "メールの本文"
var query = "is:sent to:(" + email + ")"
// is:sentで送信済みのフォルダを検索できる
// 送信していたか判別するフラグ
var flag = false
var threads = GmailApp.search(query)
for(var i=0; i<threads.length; i++) {
var messages = threads[i].getMessages();
for(var j = 0; j < messages.length; j++) {
// これが1つ1つのメール
var message = messages[j]
// 個々のメールのタイトル、本文、日付
var messageSubject = message.getSubject()
if(messageSubject == subject) {
flag = true
}
}
}
console.log(flag)
// trueであれば送信済みでfalseであれば送信できていない
送信済みフォルダを検索することで送信できているか確認している
【注意事項①】
送信直後(一度の実行でメール送信と送信済みメール探索を実行するなど)に送信済みメール探索を実行すると直後すぎてデータを取得できない可能性があるので少し時間を空けて実行すると良い
【注意事項②】
上のコードは送信済みのフォルダの中で
・送信したメールアドレスと同じアドレス
・送信したメールと同じタイトル
のものを探しているので過去に同じタイトルで送信していると正確に判定することができない
簡易版なので正確に送信判定ができない場合があるが、送信済みフォルダから取得したメールの送信時間も取得できるため送信時間も含めて判定するとより正確に判定できる
最後に
GASを用いた業務効率化で使えそうな内容をまとめてみました〜〜
気が向いたらいいねしてもらえるとめちゃくちゃ嬉しいです!!