K.Y. Design
K.Y. Design
K.Y. Design

GAS(Google Apps Script)でよく使うコード集

個人的に仕事でよく使うGASのコードをまとめていきたいと思います。
こちらのページは今後もどんどん更新していきます。

Google スプレッドシート

指定範囲の値を2次元配列として取得

var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('hoge');
var range = sheet.getRange('A1:D16');
var values = range.getValues();

配列の要素を改行区切りで文字列として出力

var array = ['hoge', 'fuga', 'piyo'];
array.join('\n') );

for文を使って配列に要素を1つずつ格納

var array = [];
for (var i = 0; i < hoge.length; i++) {
  var data = hoge[i] + 1;
  array.push(data);
}

配列の空要素除去

var values = range.getValues().filter(v => v[0]);

本日の日付を取得してフォーマット

var today = new Date();
var strToday = Utilities.formatDate(today, 'Asia/Tokyo', 'yyyyMMdd');//日付を8桁の数字に変更(例:2021年3月5日→20210305)

参考:https://blog.8basetech.com/google-apps-script/gas-formatdate/

1次元配列に含む値の数だけ繰り返し処理

for (var i = 0; i < hoge.length; i++) {
  var data = hoge[i];
}

2次元配列に含む値の数だけ繰り返し処理

参考:https://www.yukibnb.com/entry/2020/01/27/182118

for(var r = 0; r < hoge.length; r++) {
  for(var c = 0; c < hoge[r].length; c++) {
    Logger.log(hoge[r][c]);
  }
}

二次元配列を一次元配列に変更

var before_array = [[aaa, bbb, ccc, ddd, eee], [fff, ggg, hhh, iii, jjj]];
var after_array = Array.prototype.concat.apply([], before_array);

独自メニュー追加

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  var menu = ui.createMenu('追加Menu');
  menu.addItem('メニュー名', '関数名');
  menu.addToUi();
}

配列に含まれているかどうかの検証

配列(array)にvalueの値が含まれている時は、その配列の要素のインデックス番号が返される。
含まれていない時は-1を返す。

//含まれている時
array.indexOf(value) >= 0
//含まれていない時
array.indexOf(value) < 0

HTMLで記述可能なメッセージボックス

var message = '<p>HTML本文</p>';
var htmlOutput = HtmlService
  .createHtmlOutput(message)
  .setWidth(800)
  .setHeight(500);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, 'タイトル');

条件付き書式設定

var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet = spreadsheet.getSheetByName('hoge');
var range = sheet.getRange('A1:B2');
var rule = SpreadsheetApp.newConditionalFormatRule()
  .setRanges([range])
  .whenFormulaSatisfied('=AND ($E7<>"", $D7 <= F$5 , $E7 >= F$5)')
  .setBackground("#ffff00")
  .build();
var rules = ganttChartSheet.getConditionalFormatRules();
rules.push(rule);
ganttChartSheet.setConditionalFormatRules(rules);

毎日同じ時間にトリガーを設定

毎日ある時間帯でsetTriggerが動作するようにトリガーを設定する。
参考:https://tonari-it.com/gas-trigger-set/#toc2
参考:https://tonari-it.com/gas-trigger-delete/

//「myFunction」トリガーを削除
function delTrigger() {
  var triggers = ScriptApp.getProjectTriggers();
  for(var trigger of triggers){
    if(trigger.getHandlerFunction() === 'myFunction'){
      ScriptApp.deleteTrigger(trigger);
    }
  }
}

//実行した日の15:00に「myFunction」を動作させるトリガーを設定
//timeで設定した時間より前の時間でsetTriggerをトリガー設定する
function setTrigger(){
  delTrigger();
  var time = new Date();
  time.setHours(15);
  time.setMinutes(00);
  ScriptApp.newTrigger('myFunction').timeBased().at(time).create();
}

Google ドキュメント

bodyの内容の全削除

var body = DocumentApp.getActiveDocument().getBody();
body.clear();

一番上の段落を削除

appendParagraphした時に発生する先頭の空白行を削除する時に便利。

var body = DocumentApp.getActiveDocument().getBody();
var paragraphs = body.getParagraphs();
paragraphs[0].removeFromParent();

段落の挿入

var body = DocumentApp.getActiveDocument().getBody();
body.appendParagraph('');

改ページ

var body = DocumentApp.getActiveDocument().getBody();
body.appendPageBreak();

文字の書式設定変更

見出し2、文字色#FF0000、背景色#FFEE6A、フォントサイズ15として設定した場合。

hoge.setHeading(DocumentApp.ParagraphHeading.HEADING2).editAsText().setForegroundColor('#FF0000').setBackgroundColor('#FFEE6A').setFontSize('15');

Gmail

メールの送信

function sendEmail() {

//メールアドレス
var email = 'hoge.com';

//件名
var subject = 'お申し込みありがとうございます。';
      
//メール本文
var body = 'お世話になっております。...';
  
// メール送信
  MailApp.sendEmail({
    to: email,
    subject: subject,
    body: body
  });

}

Google フォーム

フォームの回答の取得

function onFormSubmit(e) {
  var name = e.namedValues['氏名'][0];//フォームの見出しが「氏名」だったとき
  var email = e.namedValues['メールアドレス'][0];//フォームの見出しが「メールアドレス」だったとき
}

フォームのプルダウン項目をスプレッドシートから取得

function djListMaker() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName('hoge');
  var range = sheet.getRange('A1:A100');
  var allData = range.getValues().filter(v => v[0]);
  var listItems = Array.prototype.concat.apply([], allData);

  var form = FormApp.openById('fuga');
  var items = form.getItems(FormApp.ItemType.LIST);
  items[0].asListItem().setChoiceValues(listItems);
  //リストボックスタイプのフォームアイテムがフォーム内に複数ある場合は、
  //items[0]のインデックス番号を変更する。
}

Google カレンダー

カレンダーIDを取得&新規イベントの作成

あらかじめタイムゾーンを日本にすると便利。
参考:https://walking-elephant.blogspot.com/2021/01/gas.timezone.html

var Calender = CalendarApp.getCalendarById('au9tbu73m47jna450j8i18at2k@group.calendar.google.com')
      Calender.createEvent(
        'title',
        new Date(start_time),
        new Date(end_time),
        {
          description: 'hoge'
        }
      );

日本語の曜日を取得

var jp_day = ['日', '月', '火', '水', '木', '金', '土'];
var day_num = date.getDay(); //dateはdate型のデータ
var day = jp_day[day_num];

スクレイピング

基本型

事前にParserライブラリを追加する必要あり。
参考:https://script.google.com/home/projects/1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw/edit

function websiteScraping() {

  var url = 'https:hoge.com';
  var html = UrlFetchApp.fetch(url).getContentText('UTF-8');
  var parser = Parser.data(html);
  var res = parser.from('<ul class="fuga">').to('</ul>').build();
  //スクレイピングした結果が複数ある場合は.build()を.iterate()に変更する

}

動的なWebページのスクレイピング

事前にParserライブラリを追加する必要あり。
事前にPhantomJsCloudのAPIキーを発行する必要あり。
参考:https://auto-worker.com/blog/?p=1976

function phantomJSCloudScraping(URL) {

  let key = '';//こちらにAPIキーを入力。
  let option =
  {
    url: URL,
    renderType: 'HTML',
    outputAsJson: true
  };
  let payload = JSON.stringify(option);
  payload = encodeURIComponent(payload);
  let apiUrl = 'https://phantomjscloud.com/api/browser/v2/' + key + '/?request=' + payload;
  let response = UrlFetchApp.fetch(apiUrl);
  let json = JSON.parse(response.getContentText());
  let source = json['content']['data'];
  return source;

}


function websiteScraping() {

  var url = 'https:hoge.com';
  var html = phantomJSCloudScraping(url);
  var parser = Parser.data(html);
  var res = parser.from('<ul class="fuga">').to('</ul>').build();
  //スクレイピングした結果が複数ある場合は.build()を.iterate()に変更する

}

HTMLタグの削除

「hoge」という配列を想定。
replace().replace()とつなげることで、別の文字列を同時に置換できる。
gオプションを使うことで一致する全ての文字列を置換できる。

var fuga = hoge[i].replace(/<("[^"]*"|'[^']*'|[^'">])*>/g, '');

Zoom

Zoom API

あらかじめZoom API Keyの発行が必要。
参考:https://qiita.com/coticoticotty/items/56ff2a3324fe408b06ca
参考:https://qiita.com/coticoticotty/items/a167b2c6db56dd42a7f7

function getZoomAccessToken() {
  var ZOOM_API_KEY = '';//API KEYを入力
  var ZOOM_API_SECRET = '';//API SECRETを入力

  var header = { alg: 'HS256', typ: 'JWT' };
  var payload = {
    iss: ZOOM_API_KEY,
    exp: Date.now() + 1800,//時間設定
  };

  // ヘッダーとペイロードをコード化
  var jsonHeader = JSON.stringify(header);
  var encodedHeader = Utilities.base64Encode(jsonHeader);
  var jsonPayload = JSON.stringify(payload);
  var encodedPayload = Utilities.base64Encode(jsonPayload);

  // 署名を符号化した後にコード化
  var signatureHMAC = Utilities.computeHmacSha256Signature(`${encodedHeader}.${encodedPayload}`, ZOOM_API_SECRET);
  var encodedSignature = Utilities.base64Encode(signatureHMAC);

  // 戻り値にTokenを設定
  return `${encodedHeader}.${encodedPayload}.${encodedSignature}`;
}

function getZoomUserId() {
  var request = UrlFetchApp.fetch('https://api.zoom.us/v2/users/', {
    method: 'GET',
    contentType: 'application/json',
    headers: { Authorization: `Bearer ${getZoomAccessToken()}` },
  });
  var users = JSON.parse(request.getContentText());
  return users.users[0].id;
}

function createZoomMeeting() {  
  var meetingOptions = {
  'topic':'hoge',
  'type': '2',//ミーティングのタイプを入力。1が即時で2が予約。
  'start_time': '2022-08-16T11:30:00',//開始時刻を入力
  'duration': '120',//ミーティングの時間を設定
  'timezone': 'Asia/Tokyo',
  'password': '',//パスワードを設定
  'agenda': '',
  'settings': {
    'host_video': 'true',//ホストのビデオをオンにするか
    'participant_video': 'true',//参加者のビデオをオンにするか
    'cn_meeting': 'false',//ホストが中国からか
    'in_meeting': 'false',//ホストがインドからか
    'join_before_host': 'false',//ホストより前に参加者がミーティングに参加できるようにするかどうか
    'mute_upon_entry': 'false',//入室時にミュートにするかどうか
    'watermark': 'false',//画面共有時に透かしを加えるかどうか
    'use_pmi': 'false',
    'approval_type': '0',//参加者の入室を許可する方法
    'registration_type': '1',
    'audio': 'both',//参加者がどういった手段でミーティングの音声に参加するか
    'auto_recording': 'none',//ミーティングの自動録画設定
    'enforce_login': 'false',
    'enforce_login_domains': '',
    'waiting_room': 'true',//参加者を一度待機させるかどうか
    'alternative_hosts': '',
    'global_dial_in_countries': [
      ''
    ],
    'registrants_email_notification': 'false'
    }
  };

  var request = UrlFetchApp.fetch(
    `https://api.zoom.us/v2/users/${getZoomUserId()}/meetings`,
    {
      method: 'POST',
      contentType: 'application/json',
      headers: { Authorization: `Bearer ${getZoomAccessToken()}` },
      payload: JSON.stringify(meetingOptions),
    }
  );

  var cont = JSON.parse(request.getContentText('UTF-8'));
  Logger.log(cont['join_url']);
  Logger.log(cont['password']);
}

Slack

自動送信bot

トークンの取得とライブラリの追加が必要。
参照:https://auto-worker.com/blog/?p=2904#toc_id_4_1

プライベートチャンネルに投稿させるには、自動投稿アプリを該当のチャンネルに招待しなければいけない。招待は、任意のチャンネルで表示されているアプリのアイコンをクリックし、後に表示される「チャンネルにこのアプリを連携する」からできる。

function sendToSlack() {
  var token = '';トークンを設定
  var slackApp = SlackApp.create(token);
  var channelId = '';//投稿先チャンネル
  var message = '<!here>' + 'お疲れ様です。';//投稿するメッセージ
  slackApp.postMessage(channelId, message);
}
«
»