こんにちは、学生エンジニアのkoyamaです。
皆さんはLINE Notifyをご存知でしょうか?LINE NotifyはLINEのトークに対してpush通知を送ることに適したAPIです。ここではサービス登録を行って、通知を送るためのアクセストークンを取得するまでの流れについてご紹介したいと思います。

前提条件

前提条件として以下のサービスを使用しました。

  • Firebase Cloud Functions
  • Firebase Hosting

Firebaseの無料プラン(sparkプラン)では外部通信を発生させることが出来ないので、今回は従量課金プラン(Blaze)プランを使用します。
また、Firebase Cloud Functionsでは外部通信のために”request”というパッケージを使用します

サービス登録までの流れ

サービス登録までには以下のような流れがあります。

  • Firebase HostingでLINEログインページに飛ぶリンクを持つページを公開
  • Firebase Functionsでアクセストークンを取得するためのページを公開
  • LINE Notifyでサービスを登録

アクセストークン取得までの流れ

OAuth認証をクリアするまでの流れを記します。

  • サービスのクライアントIDなどのパラメータを持ったログインページへのリンクを踏ませる
  • LINEから送られるレスポンスを受け取るリダイレクトページから任意のパラメータをPOSTする
  • レスポンスとして、アクセストークンを含むJSONが帰ってくる

これらの流れに必要なパラメータなどの情報はこちらの公式ドキュメントに記載されています

LINE Notify APIにログインさせるためのページを作る

まずFirebaseの公式ページに行き、コンソール画面からプロジェクトを新規に立ち上げます。
プロジェクトを作成したのちに、料金プランをBlazeにアップグレードしておきましょう。

次にターミナルを立ち上げて作業ディレクトリに移動します。 $firebase initをするとプロジェクトを選択できるようになります。 機能の選択画面ではFunctionsとHostingを選択することでこれらの機能が使用できるようになります。

初期化作業が終了したら、publicディレクトリにindex.htmlがあるのでこれを編集していきます。
index.htmlにLINEの認証ページに飛ばすために以下の表にあるログインurlに必要なクエリパラメータを持ったリンクを追加しましょう。必要なパラメータは公式ドキュメントからでも確認ができます。

$firebase deployで先ほど編集したページを公開します。また、Firebaseのプロジェクト管理画面→Hostingからページのurlを確認することが出来ます。

ちなみに今回のhtmlはこんな感じになりました


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>認証ページ</title>
  </head>
  <body>
    <div>
      <h1>ここで認証URLを踏んでください</h1>
      <a href="https://notify-bot.line.me/oauth/authorize?response_type=code&client_id=client_id&redirect_uri=redirect_uri&scope=notify&state=state">ここにリンク</a>
    </div>
  </body>
</html>

トークのアクセストークンを取得する部分を作る

ターミナルから、今度はfunctionsディレクトリの中にあるindex.jsを編集していきます。
index.jsでは以下のパラメータをAPIにPOSTして、返ってくるJSONを確認する機能を持たせます。
POSTに必要なパラメータは以下のようになります

これらのパラメータを正常に取得できた場合、以下のようなJSONが返ってきます。
{"status":200,"message":"access_token is issued","access_token":"012345thisisaccesstoken"} 

次に、webページとしての機能を持たせるためにHTMLの部分を表示するようにします。

exports.get_response_json = functions.https.onRequest((req, res) => {
  res.status(200).send(`ここにhtml`)
});
このようにするとresponseとしてwebページを表示させることができます。
最後にデプロイを行うとページが公開され、URLを確認できます。

今回のindex.jsは以下のような感じになりました。


const functions = require('firebase-functions');
const admin = require("firebase-admin");
admin.initializeApp(functions.config().firebase);
const request = require('request');

async function get_response(code){
  console.log(response_code)
  var headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
  };

  var dataString = 'grant_type=authorization_code&code=' + code + '&redirect_uri=redirect_uri&client_id=client_id&client_secret=client_secret';

  var options = {
    url: 'https://notify-bot.line.me/oauth/token',
    method: 'POST',
    headers: headers,
    body: dataString
  };

  async function callback(error, response, body) {
    if (response.statusCode == 200) {
      console.log("1",body)
      push_to_db(body)
    }else{
      console.log(error)
    }
  }
  request(options, callback);
}

async function push_to_db(response){
  let access_token = eval(JSON.parse(response))
  console.log(access_token)
}


exports.get_response_json = functions.https.onRequest((req, res) => {
  let resCode = req.query.code
  if (req.method === "GET"){
    let resCode = req.query.code
    get_response(req.query.code)
  }
  res.status(200).send(`
    <!DOCTYPE html>
    <html lang="ja">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <title>トークンリクエスト</title>
      </head>
      <body>
        <div>
          <h1>これはトークンのリクエストです。</h1></b>
          トークンを送信しました
        </div>
      </body>
    </html>`
  );
});


サービスを登録する

まず「LINE Notify」で検索して、公式の紹介ページに行きます。ここでは、LINE Notifyの紹介やサービス管理状況やAPIドキュメントが確認できます、右上のログインボタンからログインをしておきましょう。
今回はNotifyとサービス利用者の1:1で完結させたいので、右上のユーザー名をクリックして現れるボックスの「登録サービス管理」からサービス登録を始めます。

サービス登録画面に行くと以下のようなフォームが現れるのでもれなく記入していきましょう。
サービスURLはFirebase Hostingで公開したwebページのURLを入力していきます。また、Callback URLは通知を送ったりするAPIになるページのURLを入れます、今回はアクセストークンを取得したいだけなのでFirebase Cloud Functionsで公開したページのURLを入れます。

サービス登録が完了すると以下のようにクライアントIDやクライアントシークレットが表示されるので、index.htmlとindex.jsの部分を更新しておきましょう。

動作確認

公開したindex.htmlのリンクを開くと以下のようなページになっています

リンクを踏むとログイン画面が現れて通知先トークを選択し、その後リダイレクトURLに飛ばされて、POSTリクエストを送信します。

最後にFirebaseのログを確認すると確かにアクセストークンが取得できています。

最後に

この記事を作るにあたってサービス登録をしてLINE Notify APIを使っている先駆者の方々が思ったより少なく思い、またその方法についての記事も少なかった印象がありました。ここまで拙い文章で解説してきましたが、この記事が誰かの助けになれば幸いです。