LANG SELRCT

コードを書く場所

2018年11月29日木曜日

新規作成したLINE BOTが反応しなくて「Webhookの送信」を選択し直したら反応するようになった


LINE BOTでwebhookが反応しなくて「Webhookの送信」を選択し直したら反応するようになった備忘録。



最近新たにLINE BOTを作ったときに webhook のURLにデータが送られてこないということがありました。
(以前は同じ手順でデータが送られてきていた)

エラーも飛んでこなかったので何が原因なのか手がかりがなく、いろいろ試してみたところひとつ解決策を見つけました。

解決策:
Webhook送信 を「利用する」から「利用しない」に戻して再度「利用する」にして更新するとデータが送られてくるようになりました。


他に解決策があるのかもしれませんが、それらしき情報が見つからなかったので書き残しておきます。


一度LINE BOTを作ってメッセージが返ってこなかった前提で以下進めます


チャネル基本設定の「Webhookの送信」で「編集」をクリックします

前提から、すでに「利用する」にチェックが入っていると思うので

「利用しない」にチェックを入れて

再度「利用する」にチェックを入れ直して「更新」ボタンをクリックします

詳しい原因はわかりませんが、これでメッセージが返って来るようになりました。


もしかしたら一度目の「利用する」チェックが効いていないとかだろうか?



2018年11月27日火曜日

特定の範囲に特定の値を一気に入力したい


特定の列から、値が入っている最後の列まで、指定した文字列を入力したくて書いたコードです。


2行目の5列目から
このシートで値が入っている最後の列(L列)まで
OKという文字列を入力する



コード.gs
function setValuesSpecificRange() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var lastColumn = sheet.getLastColumn();
  var startRow = 2;
  var startColumn = 5;
  var numRows = 1;
  var numColumns = (lastColumn - startColumn) + 1;
  var value = 'OK';
  var values = creteValues(numColumns, value);
  var range = sheet.getRange(startRow, startColumn, numRows, numColumns);
  range.setValues([values]);
}

function creteValues(num, value) {
  var values = [];
  for(var i = 0; i < num; i++) {
    values.push(value);
  }
  return values;
}
意訳
この機能がやること
シートを取得する
値が入っている最終列を取得する
開始行
開始列
行数
列数
入力する値
入力する値を列数分作成する
対象の範囲を指定して
入力する


この機能がやること
配列を用意する
引数で受け取ったnumの数だけ繰り返す
引数で受け取ったvalueの数だけ配列に追加する

出来上がった配列を返す



参考

getRange(row, column, numRows, numColumns)
https://developers.google.com/apps-script/reference/spreadsheet/sheet#getrangerow-column-numrows-numcolumns

setValues(values)
https://developers.google.com/apps-script/reference/spreadsheet/range#setValues(Object)

文字列から特定の文字列を抜き出したい substr


あいうえお

の文字列の中から

いうえ

を抜き出したい


'あいうえお'.substr(1, 3)



コード.gs
function getExtract() {
  var value = 'あいうえお';
  var  extract = value.substr(1,  3);
  Logger.log(extract);
}
意訳
この機能がやること
対象の文字列
1文字目から3文字目を取り出す(先頭は0)
ログに出す



実行結果



参考

String.prototype.substr()
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/substr

2018年11月26日月曜日

WEEKNUM(日付, 種類)を使ってみる


スプレッドシートの関数の話です

WEEKNUM(日付, 種類)


種類は週の最初の曜日を表す数字
1= 日曜日、2= 月曜日 始まりということ

A1に
2018/11/26
が入力されていて

B1に
=WEEKNUM(A2,2)
を入力すると

B1は
48
になる


2018/11/26 は 2018年の 48週目


参考

WEEKNUM
https://support.google.com/docs/answer/3294949

MID(文字列, 開始位置, 長さ)で文字を抽出する


スプレッドシートの関数の話です

MID(文字列, 開始位置, 長さ)


2018/11/26 という文字列から 11 を抽出してみる


A1の
2018/11/26
から

11
をB1に抽出するには

B1に
=MID(A1,6,2)
と入力する



参考

MID
https://support.google.com/docs/answer/3094129

2018年11月25日日曜日

スプレッドシートのA1に入力した場所の地図をメールで送る(コードラボのサンプル)


スプレッドシートとGoogleマップとGmailを連携する
というおもしろい例がコードラボにあったので試してみました



スプレッドシートのA1に場所を入力して

今回のコードを実行すると

Gmailに地図が送られてくる






コード.gs
function sendMap() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var address = sheet.getRange('A1').getValue();
  var map = Maps.newStaticMap().addMarker(address);
  GmailApp.sendEmail('NAME@gmail.com', 'Map', 'See below.', {attachments:[map]});
}
意訳
この機能がやること
アクティブシートを取得する
そのシートのA1の値(場所)を取得する
その場所を地図で見つけてマーカーを付ける
Gmailで指定したアドレスにその地図を添付して送信する



参考

Google Developers
https://codelabs.developers.google.com/?cat=apps

Hands-on with Google Apps Script: accessing Google Sheets, Maps & Gmail in 4 lines of code!
https://codelabs.developers.google.com/codelabs/apps-script-intro/index.html?index=..%2F..index#4

Google Formでscopeを追加する


新規でGoogleフォームを作成して送信時にトリガーを設定したときに

TypeError: undefined のメソッド「getItemResponses」を呼び出せません。

または

TypeError: Cannot call method "getItemResponses" of undefined.

というエラーが出たら以下の2つの方法で解決するようです
  • FormApp.getActiveForm(); をコードに記述する
  • マニフェストファイルにスコープを追加する

参考
https://issuetracker.google.com/issues/118921815


FormApp.getActiveForm(); をコードに記述する場合


コード.gs
function get_item_responses(e) {
  FormApp.getActiveForm();
  var itemResponses = e.response.getItemResponses();
  var result = [];
  for (var i = 0; i < itemResponses.length; i++) {
    var itemResponse = itemResponses[i];
    var question = itemResponse.getItem().getTitle();
    var answer = itemResponse.getResponse();
    result.push([question, answer]);
  }
  Logger.log(result);
}
意訳.gs
実行する機能を定義する
フォームを取得する
回答を取得して
回答を入れるresulという入れ物を用意して
回答の内容の数(=質問の数)だけ以下を繰り返す
回答をひとつずつ取得して
Title(=質問内容)を取得し
回答した内容を取得し
resultに入れる

それらを配列に入れてログに出す




ファイル > プロジェクトのプロパティ > スコープ
を見るとスコープに何も入っていない

編集 > プロジェクトのトリガー
を開いて
フォーム送信時にトリガーを設定して保存すると

アカウントの選択を求められて

許可を求められて

https://www.googleapis.com/auth/forms
が スコープに入る


appscript.json(マニフェストファイル)に追加する場合



"oauthScopes": [
  "https://www.googleapis.com/auth/forms"
],
を追加して保存後にトリガー設定すると
アクセスの許可を求められるようになります


参考

https://issuetracker.google.com/issues/118921815
https://ja.stackoverflow.com/questions/50010/
https://stackoverflow.com/questions/53377027/

2018年11月24日土曜日

Google Slideの特定のスライド内の要素の下端の位置を取得する


特定のスライド内の要素の下端の位置を取得したくて書いたコードです。

単位はポイントです



コード.gs
function getLastBottom() {
  var url = 'SLIDE URL';
  var slide = SlidesApp.openByUrl(url);
  var slide0 = slide.getSlides()[0];
  var nextTop = getNextTop(slide0);
  Logger.log(nextTop);
}

function getNextTop(slide0){
  var elems = slide0.getPageElements();
  var len = elems.length;
  var lastElem = elems[len-1]
  var lastTop = lastElem.getTop();
  var lastHeight = lastElem.getHeight();
  var nextTop = lastTop + lastHeight;
  return nextTop;
}
意訳
この機能がやること
スライドのURLを指定する
対象のスライドを取得する
先頭のスライドを取得する
最後の要素の上部からの位置を取得する
ログに出す


この機能がやること(対象のスライドを受け取る)
スライド内の要素をすべて取得する
要素の数を取得する
配置されている最後の要素を取得して
その要素の上部からの位置を取得して
その要素の高さを取得して
nextTopを決めて
返す



参考

Slides Service
https://developers.google.com/apps-script/reference/slides/

Google Slideに要素を追加する


特定のスライドに要素がなければ最上部に要素を追加して
すでに要素があればその下に要素を追加する
というコードを書いてみました。



コード.gs
function insertNewShape() {
  var value = 'テキスト';
  var url = 'SLIDE URL';
  var slide = SlidesApp.openByUrl(url);
  var slide0 = slide.getSlides()[0];
  
  var nextTop = getNextTop(slide0);
  var rect = slide0.insertShape(SlidesApp.ShapeType.RECTANGLE)
  .setWidth(360)
  .setHeight(60)
  .setTop(nextTop)
  .setLeft(0);
  rect.getText().setText(value)
  .getTextStyle().setFontSize(36);
  rect.getFill().setSolidFill("#C9DAF8");
}

function getNextTop(slide0){
  var elems = slide0.getPageElements();
  var len = elems.length;
  var nextTop;
  if(len === 0){
    nextTop = 0;
  }else{
    var lastElem = elems[len-1]
    var lastTop = lastElem.getTop();
    var lastHeight = lastElem.getHeight();
    nextTop = lastTop + lastHeight;
  }
  return nextTop;
}
意訳
この機能がやること
テキストの値を決める
スライドのURLを指定する
対象のスライドを取得する
先頭のスライドを取得する

getNextTopにスライドを渡して結果を受け取る
長方形の図形を挿入する
幅を決める
高さを決める
上部からの位置を決める
左からの位置を決める
テキストを取得して値を書き込む
テキストのスタイルを取得して文字サイズを決める
塗りつぶしの色を指定する


この機能がやること(対象のスライドを受け取る)
スライド内の要素をすべて取得する
要素の数を取得する
nextTop(上部からの距離)
elemがなければ
nextTopは0
elemがあれば
配置されている最後の要素を取得して
その要素の上部からの位置を取得して
その要素の高さを取得して
nextTopを決めて

返す



参考

Slides Service
https://developers.google.com/apps-script/reference/slides/

Google Slideに配置されたすべての要素を削除する


Google Slideの特定のスライド内の要素をすべて削除するコードを試してみます



コード.gs
function removeSlideElements() {  
  var url = 'SLIDE_URL';
  var slide = SlidesApp.openByUrl(url);
  var slide0 = slide.getSlides()[0];
  var elems = slide0.getPageElements();
  removeElems(elems);
}

function removeElems(elems){
  for(var i = 0; i < elems.length; i++){
    elems[i].remove();
  }
}
意訳
この機能がやること
対象のスライドのURLを指定する
対象のスライドを開く
先頭のスライドを取得する
すべての要素を取得する
それらを削除する


この機能がやること(要素を受け取る)
受け取った要素の数だけ繰り返す
要素をあるだけ全部削除する




削除

openByUrl(url)
https://developers.google.com/apps-script/reference/slides/slides-app#openByUrl(String)

getSlides()
https://developers.google.com/apps-script/reference/slides/presentation#getSlides()

getPageElements()
https://developers.google.com/apps-script/reference/slides/page#getPageElements()

remove()
https://developers.google.com/apps-script/reference/slides/page-element#remove()


Google Slideを新規作成してみる


スクリプトで新規スライドを作成してみるコードです



コード.gs
function createNewSlide() {  
  var name = 'TEST';
  var slide = SlidesApp.create(name);
  var url = slide.getUrl();
  Logger.log(url);
}
意訳
この機能がやること
ファイル名を決める
新規スライドを作成する
そのスライドのURLを取得する
それをログに出す



参考

create(name)
https://developers.google.com/apps-script/reference/slides/slides-app#create(String)

2018年11月19日月曜日

ラジオボタンを未選択状態にする


選択されているラジオボタンのチェックを外したくて
対象のフォームのすべてのラジオボタンのcheckedをfalseにする
ということをやってみました


デモ

ラジオ1 ラジオ2 ラジオ3




クリアボタンをクリックすると
選択されたラジオボタンのチェックが外れます



コード.gs
function doGet() {
  return HtmlService.createHtmlOutputFromFile("index");
}
意訳
この機能がやること
指定したHTMLファイルを表示する




index.html
<!DOCTYPE html>
<html>
  <body>
    <form id="radios">
      <input type="radio" id="radio1" name="group1">ラジオ1
      <input type="radio" id="radio2" name="group1">ラジオ2
      <input type="radio" id="radio3" name="group1">ラジオ3
    </form>
    <button id="bt">クリア</button>
  </body>
  <script>
  
  document.getElementById("bt").onclick = btClicked;
  
  function btClicked() {
    var form = document.getElementById("radios");
    for(var i = 0; i < form.length; i++) {
      form[i].checked = false;
    }
  }
  </script>
</html>



2018年11月18日日曜日

GmailAppで条件を指定して検索結果を取得したい


条件を指定してAppsScriptからGmailを取得したときの備忘録

GmailApp.search(query)で抽出できる


含む文字で検索する場合


コード.gs
function getGmail() {
  var query = '含む文字';
  var threads = GmailApp.search(query);
  Logger.log(threads.length)
}


var queryの中身は、Gmailで検索するときの画面で指定できる条件で絞れそう


件名と検索する前後期間を指定した場合

このような検索条件をqueryとして指定できる

var query = 'subject:(テスト) after:2018/11/16 before:2018/11/19';


参考

search(query)
https://developers.google.com/apps-script/reference/gmail/gmail-app#search(String)

2018年11月11日日曜日

AppMakerで Cloud SQL を選択できるようにしたい


AppMakerの公式Tutorial 2: Work with Data
https://developers.google.com/appmaker/tutorials/work-with-data/

を試したときにぶつかった壁
Create Model で Cloud SQLが選択できない


利用するには Cloud SQL の設定をしておく必要があるらしい


というわけで sets up Cloud SQL のリンクを開いてみます

開いてみると以下の設定が必要らしいのでひとつずつ設定していきます



まずは

1.Google Cloud Platform(GCP)が有効であることを確認する


無料トライアルで住所やクレジットカード情報を登録します
するとこのようなメッセージが表示されます


GCPの初期画面がこのように表示されます



2.App Maker 用の Cloud SQL インスタンスを設定する


Cloud SQL インスタンス のリンクを開きます
「インスタンスを作成」をクリックします


「MySQL」を選択して次へをクリックします


「第2世代を選択」をクリックします


「インスタンス ID」に任意の文字を入力します
「rootパスワード」を任意の文字で設定します
「作成」をクリックします


このような画面が表示されます



3.App Maker 用の Cloud SQL の役割を追加する


左上のナビゲーションメニューの三のようなアイコンをクリックします
「IAMと管理」を選択します


上部の「追加」をクリックします


「新しいメンバー」に
appmaker-maestro@appspot.gserviceaccount.com」
を入力すると候補が出るので選択します


「役割を選択」をクリックします
Cloud SQL を選択して Cloud SQL 管理者を選択します


「保存」をクリックします



4.Cloud SQL インスタンスを Google 管理コンソールに追加する


SQL インスタンスに移動します
手順2で作ったインスタンスをクリックします

「インスタンス接続名」をコピーします


Google 管理コンソールのApp Maker の設定を開きます
「App Maker で使用する Google Cloud SQL インスタンスの接続名 を入力:」にコピーした接続名を貼り付けます
「保存」をクリックします



5.App Maker でモデルを作成できることを確認する


App Maker で DATA の + アイコンをクリックします


Google Cloud SQL(recommended)が選択できるようになります



参考

Google Cloud SQL
https://developers.google.com/appmaker/models/cloudsql#Terms

App Maker 用の Google Cloud SQL データベースを設定する
https://support.google.com/a/answer/7550053

2018年11月10日土曜日

AppMakerのHello App Maker!チュートリアルをやってみる


今回試したのは公式サイトにあるAppMakerのチュートリアルです

Hello App Maker!
https://developers.google.com/appmaker/tutorials/hello-appmaker/


チュートリアルのゴール


Type your nameのテキストボックスに名前を入力してSAY HELLOボタンを押すと



このようにアラートでメッセージが表示されます


ゴールまでの道


G Suite Developer Hub を開いて「新しいアプリ」を選択します
https://script.google.com/home



このような画面が表示されます


アプリ名をUntitled Appから「Hello App Maker」に変更します


PAGESのNewPage左端の︙ をクリックして「Rename」を選択します

「HelloPage」に変更してOKをクリックします




テキストボックスやボタンなどのパーツは左サイドの「Widgets」の中から選択して掴んで、中央の画面の置きたい場所まで持っていくと配置できます



テキストボックスのPropertyを設定します
  • name欄に「YourName」と入力します
  • label欄に「Type your name」と入力します



ボタンのPropertyを設定します
  • text欄に「Say Hello」と入力します
  • onClick欄をクリックしてCustom Actionを選択します

「alert("Hello " + app.pages.HelloPage.descendants.YourName.value + "!")」と入力してDONEをクリックします

ボタンのPropertyはこのようになります


動作を確認するために左上にある「PREVIEW」をクリックします


作ったアプリが表示されます




アプリを公開してみる

PREVIEWの左隣にある「PUBLISH」をクリックすると以下のような画面になります
「PUBLISH NEW DEPLOYMENT」をクリックします


Deployment nameを入力します
Application accessを任意で選択します
「PUBLISH」をクリックします

「PREVIEW PERMISSIONS」をクリックします

このような画面が表示されます
Deployment URLのリンクをクリックします

公開したアプリケーションが開きます


参考

App Maker
https://gsuite.google.co.jp/intl/ja/products/app-maker/

App Maker Guides
https://developers.google.com/appmaker/tutorials/

Tutorial 1: Hello App Maker!
https://developers.google.com/appmaker/tutorials/hello-appmaker/