GAS + TypeScriptでLINEに通知を送る方法を紹介します
時代はサーバレスへ
以前、PHPでLINE NotifyのAPIを叩くプログラムを書きました。
関連記事: GASをclasp(CLIツール)+ TypeScriptでローカルで開発する
この時はPHPファイルをレンタルサーバーに置き、cronで定期実行させていました。
しかし、時代はサーバレスです。APIを叩くだけならGoogle Apps ScriptやAWS LambdaといったFaaSで実現できます。
今回はTypescriptを学びたかったので、claspを使ってGoogle Apps Scriptにデプロイすることにしました。claspを使うと、webpackなどの設定が不要になり、気軽にTypescriptのコードを書くことができます。
claspの主なコマンド
開発中に使う主なclaspコマンドは以下です。
$ clasp login // script.google.comにログインする
$ clasp create // プロジェクトを作成する
$ clasp push // tsファイルのコンパイルとGASにアップロード
$ clasp open // 該当のGASのページをブラウザで開く
$ clasp deploy [Version] [Description] // バージョンを管理できる
claspについては下記の記事が詳しいです。
コードを書く
const properties = PropertiesService.getScriptProperties()
// APIトークンは下記ページから発行する。通知を投稿するチャンネルを選択すればトークンが発行される。
// https://notify-bot.line.me/ja/
const TOKEN = properties.getProperty('LINE_NOTIFY_TOKEN')
const FROM = new Date(properties.getProperty('FROM'))
const ENDPOINT = 'https://notify-api.line.me/api/notify'
const MILLISECONDS_OF_DAY = 86400000
const DAYS_OF_YEAR = 365
// スタンプのIDは下記アドレスに記載
// https://devdocs.line.me/files/sticker_list.pdf
const STAMPS = [
608, // プレゼントボックス
301, // カクテル
269, // ハート
268, // 虹
]
function getHeaders(): { [key: string]: string } {
return {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": `Bearer ${TOKEN}`
}
}
function getStampNumber(): number {
const length = STAMPS.length
const random = getRandomInt(length)
return STAMPS[random]
}
function getRandomInt(max: number): number {
return Math.floor(Math.random() * Math.floor(max));
}
function getPayload(): string {
const params = {
'message': getMessage(),
'stickerPackageId': 4,
'stickerId': getStampNumber()
}
let body = [];
Object.keys(params).map(key => {
body.push(key + '=' + encodeURI(params[key]));
})
return body.join("&")
}
function getMessage(): string {
const now = new Date()
const diff = getDayDiff(now)
const [years, days] = getYearsAndDays(diff)
return createMessage(diff, years, days)
}
function getDayDiff(now: Date): number {
const diff = (now - FROM) / MILLISECONDS_OF_DAY
return Math.floor(diff)
}
function getYearsAndDays(diff: number): Array<number> {
const years = Math.floor(diff / DAYS_OF_YEAR)
const days = diff - DAYS_OF_YEAR * years
return [years, days]
}
function createMessage(diff: number, years: number, days: number): string {
return `
🎉おめでとう🎉
二人が付き合ってから
${diff}日が経ちました😍
今日で${years}年と${days}日です💕
これからもよろしくね😘`
}
function send(): void {
const options = {
"method": "POST",
"headers": getHeaders(),
"payload": getPayload(),
"muteHttpExceptions": true
}
Logger.log(options);
const res = UrlFetchApp.fetch(ENDPOINT, options);
Logger.log(res.getContentText());
}
GASのメリット
APIのトークンを「プロジェクトのプロパティ」に記述できるため、誤ってトークンが流出することを避けられる。
PropertiesService.getScriptProperties().getProperty('KEY名')
で値を取得する。FROM
は2019-04-01のようにYYYY-MM-DD
で定義する。
claspのメリット
- ES6の構文が使える
- テンプレートリテラルが使え、文字列の連結を多用せずに済む
- Typescriptを学ぶことができる
- 導入方法についてはclaspのTypeScriptのドキュメントを参照
- GitHubでのコードの管理が楽
- もし
clasp push
がなければ、ローカルで書いたコードをGASにコピペするため煩雑
- もし
- 今回は不使用だが、Class構文も使える
結果
PHPからGAS+Typescriptへ載せ替えができました!
Happy Coding 🎉