Line botをスマホでプログラミングできるようにしてみた


モチベーション

Line botでも作ろうかなと思って、GAS(google apps script)を使うとサーバー持たずに簡易DB(スプレッドシート)込みで作れると知った時、GASはウェブエディタだし実行環境はLINEだし、全部スマホで作れるのではと思ったら作れなかった※1ので作れるようにした話※2

※1・・・GASのウェブエディタはスマホのブラウザをサポートしていなかった。
※2・・・結局のところ、GASのスクリプトをgithubで管理して、スマホ上で編集&コミットすると(githubはスマホでもPC版サイトモードにすると使える)CircleCI経由でclaspを使って自動的にデプロイされるようにするよという話

前提

  • PC開発環境はMac
  • 最近のバージョンのnode&npm環境が整っている
  • スマホはiPhoneで確認している

という前提で書かれています。
なんとなくわかっている人向けの簡易版手順を最後に載せていますので、なんとなくわかっている人はそちらを参照。

環境準備(PC編)

環境構築もスマホで完結させたかったけど一部のID情報取得や権限許可のUI操作がややこしそうだったので、初期設定はPCで。

claspのインストール&ログイン

まずはGASをCLIで操作できるclaspの環境を準備します。

$ npm i @google/clasp -g

続いてclaspでログインします。

$ clasp login

このコマンドを実行すると、ブラウザが立ち上がりgoogleアカウントの選択と権限許可の画面が表示されます。画面の指示に従ってログイン処理を終えてください。

GASプロジェクトの作成

$ mkdir testbot
$ cd testbot
$ clasp create 
## 作成するGASプロジェクトのtypeが聞かれるので`webapp`を選択。

正常に動作すれば、appscript.jsonというマニフェストファイルが生成されます。マニフェストに、LINEbotからのwebアクセスやMessegingAPIを使用するのに権限を追加しておきます。

appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "webapp": {
    "access": "ANYONE_ANONYMOUS",
    "executeAs": "USER_DEPLOYING"
  },
  "exceptionLogging": "STACKDRIVER",
  "oauthScopes": ["https://www.googleapis.com/auth/script.external_request"]
}

スプレッドシートの編集やdriveへのアクセスを行うなら、oauthScopeshttps://www.googleapis.com/auth/spreadsheetsとか、https://www.googleapis.com/auth/driveを加えておきましょう。
※不必要な権限を与えると危険性が高まるので理解した上で追加しましょう。本来、該当のコードが追加された際に承認を求められるのでウェブエディタで操作している分には不要です。

続いてメインのスクリプトを追加します。

$ touch bot.js

bot.jsの中身は後ほど作っていきますので、現時点では中身はなくてもOKです。

GASプロジェクトの公開

ここで一連のファイルをGASプロジェクトにpushします。

$ clasp push
## Manifestを上書きしますか?と聞かれますが`y`で。

ここまで来たら、一度GASのウェブエディタを開きます。

$ clasp open

ブラウザが起動されて、作ったGASプロジェクトのエディタ画面が開きます。bot.gsが作られていることが確認できます。(.jsファイルは.gsファイルとなる)

ウェブエディタから「公開」->「ウェブアプリケーションとして導入」を選択します。更新ボタンを押すと、追加した権限に対する承認処理が要求されるので、確認して承認します。

承認ができたら一度ローカル環境側でもpullしておきます。

$ clasp pull

これで一旦GASプロジェクトに関する設定は完了です。

githubリポジトリの作成

編集対象のgithubリポジトリを作成します。github上で適当な名前のリポジトリを作成してリポジトリURLをコピーしておいてください。

続いて、ローカルのGASプロジェクトをgitに紐付けます。

$ git init
$ git remote add origin <リポジトリURL>

コミット&プッシュの前にcircleCIの設定に入ります。

circleCIのプロジェクト作成

circleCIとは:流行りだしている(?)CI(continuous integration:継続的インテグレーション)サービス。Jenkinsとかが有名(?)ですね。あんまり自分では触れてこなかったので、その勉強も兼ねてます。

まずは、circleCIにアクセスしてgithubアカウントでログインします。「ADD PROJECTS」から前節で作ったgithubリポジトリを選んで「Set Up Project」を押します。

Next Stepsに書かれている通りですが、circleciのコンフィグファイルを作ってpushします。

$ mkdir .circleci && touch .circleci/config.yml

config.ymlは以下のように編集しておきます。

config.yml
version: 2

jobs:
  build:
    docker:
      - image: circleci/node:8.9.4

    working_directory: /home/circleci/project

    steps:
      - checkout

      - run:
          name: Show system information.
          command: |
            echo "Node $(node -v)"
            echo "Npm $(npm -v)"

      - run:
          name: deploy to gas
          command: |
            echo $CLASPRC_JSON > ~/.clasprc.json
            echo $CLASP_JSON > ./.clasp.json
            echo 'var ACCESS_TOKEN = "'$LINE_ACCESS_TOKEN'";' > ./config.js
            npx @google/clasp push
            npx @google/clasp deploy -i $DEPLOY_ID

gitignoreファイルを作って必要なファイルをまとめてpush

$ touch .gitignore
$ echo '.clasp.json' >> .gitignore
$ git add .
$ git commit -m "first commit"
$ git push origin master 

pushが完了したら、circleCIのページからstart buildingします。

が、この時点ではbuildが失敗するはずです。config.yml内で使用している環境変数の設定が行われていないためです。ちなみに、Show system information.までは成功するはずなので、nodeとnpmのバージョンが表示されていることを確認してください。

circleCI環境変数の設定

GASへのdeployの際に利用している4つの環境変数($CLASPRC_JSON,$CLASP_JSON,$DEPLOY_ID,$LINE_ACCESS_TOKEN)を設定していきます。circleCI上での環境変数の設定は、リポジトリ名の横にある設定ボタン->「Environment Variables」から設定することができます。

$CLASPRC_JSON:

clasp loginをすると生成される設定ファイルです。認証トークン情報とかが記載されています。内容をコピーして環境変数に設定してください。

$ cat ~/.clasprc.json | pbcopy
$CLASP_JSON:

clasp createするとプロジェクトのディレクトリ内に生成されます。GASプロジェクトのscriptIDが記載されています。これはGASプロジェクトのURLからも取得することが可能です。(https://script.google.com/d/xxxx/editのxxxxの部分)内容をコピーして環境変数に設定してください。

$ cat ./.clasp.json | pbcopy
$DEPLOY_ID:

対象のGAS プロジェクトで、すでにウェブアプリケーションとして導入しているバージョンのdeploy_idを取得します。deploy一覧はclasp deploymentsで取得できます。ウェブアプリケーションとして公開されているものはweb app meta-versionという説明が付与されていますので、そのdeploy_idをコピーして環境変数として設定します。circleCIではこのdeployを対象にアップデートしていくことになります。

$ clasp deployments
2 Deployments.
- xxxx @HEAD 
- yyyy @1 - web app meta-version <- yyyyの部分をコピー

1行で取得するなら以下のような感じに。

$ clasp deployments | grep 'web app meta-version' | awk '{print $2}' | pbcopy
$LINE_ACCESS_TOKEN

名前から想像するとおり、LINEbotがLINEにアクセスするためのトークンです。後述するLinebotの設定を行って取得したアクセストークンを環境変数に設定してください。
このトークンは別にcircleCIの環境変数で管理しなくてもいいのですが、リポジトリにトークン情報いれるのも嫌なのでこちらで設定しています。

Linebotの設定

ただ、Linebotの設定はいろんな人が画像付きで解説しているので細かな説明はそちらに譲ります。(なげやり)例えばこちらとか。

必要になるのは

  • アクセストークンの取得
  • Webhook URLの設定

です。

アクセストークンはLINEbot設定画面の以下赤枠の部分から取得できるので、コピーして、circleCIの環境変数に設定してください。

Webhook URLは「公開」->「ウェブアプリケーションとして導入」から、画像の赤枠部分で確認できます。

こちらをコピーしてLinebotのWebhook URLに設定してください。(貼り付けるのはscript.google~
Webhook送信利用するに設定するのを忘れずに。

Linebotプログラミング

さて、あとはbotプログラムを作っていくわけですが、動作確認がてら、おうむ返しするLinebotをつくってみましょう。

ローカル開発環境で以下のようにbot.jsを編集し、git add & commit & pushしてみてください。

bot.js
var lineEndpoint = "https://api.line.me/v2/bot/message/reply";
function doPost(e) {
  var json = JSON.parse(e.postData.contents);
  var replyToken = json.events[0].replyToken;
  var userMessage = json.events[0].message.text;

  UrlFetchApp.fetch(lineEndpoint, {
    'headers': {
      'Content-Type': 'application/json; charset=UTF-8',
      'Authorization': 'Bearer ' + ACCESS_TOKEN,
    },
    'method': 'post',
    'payload': JSON.stringify({
      'replyToken': replyToken,
      'messages': [{
        'type': 'text',
        'text': 'samplebot ver1.00:'+userMessage,
      }],
    }),
  });
}

きちんと設定できていれば、git pushされるとcircleCIのデプロイスクリプトが起動し、claspを使用したコードpushとデプロイが行われるはずです。
line上でbotを友達登録してメッセージを送るとsamplebot ver1.00:という文字列とともに送ったメッセージが返されるかと思います。

スマホでプログラミング

ここまでできたらあとはスマホでプログラミングしていくことが可能です。
スマホからgithubのリポジトリページにアクセスして、PC版サイトで表示するとソースコードの編集を行うことができます。編集を終えてコミットすると、circleCIによって自動的にデプロイされます。

短縮版

以上で作成したプロジェクトもろもろをまとめたリポジトリを作成しました。
https://github.com/naokisekiguchi/gas-linebot-template
適当にForkして使用して頂ければと。
以下に短縮版の手順を記載しておきます。

## Fork https://github.com/naokisekiguchi/gas-linebot-template
$ git clone [email protected]:<your account>/gas-linebot-template.git testbot
$ cd testbot
$ npm i @google/clasp -g
$ clasp login
## ログイン処理
$ clasp create
$ clasp push
$ clasp open
## ウェブアプリケーションとして導入->承認処理
$ clasp pull
## circleCIでプロジェクト作成
## Linebotの設定
## circleCIの環境変数の設定
$ cat ~/.clasprc.json | pbcopy
$ cat ./.clasp.json | pbcopy
$ clasp deployments | grep 'web app meta-version' | awk '{print $2}' | pbcopy
## コーディング
$ git add
$ git commit 
$ git push
## botの動作確認
## done!

まとめ

Line botでも作ろうと思ったことでCIサービスとかGASとかclaspとか触れて満足しました。
GASはclaspができたことで(おそらく)格段に開発しやすくなって(git管理が楽になるので)、webサービスとスプレッドシート操作が簡単なので簡易的なツール作成には重宝しそうです。
circleCI簡単に使えそうなので今後活用していきたい。
(本来作ろうと思ってたbotは中途半端で放置されているわけですが)

参考