LINEBotでポートフォリオを作ろう【TypeScript】1/5 おうむ返しBot編

# はじめに
みなさん、自分のポートフォリオはありますか？
僕はないです。

エンジニアたるものポートフォリオを作ろう！という気持ちは理解できますし、憧れもあります。しかし、いかんせんめんどくさいですよね。

そんな時、研究で「登録文化財の検索やそこで開催されるイベントの発信、情報収集がLINEアプリ上で手軽にできる」というLINE Botを開発しました。そこから「これでポートフォリオを作ったら楽だしおもろいんじゃね」と思ったので作ってみることにしました。真似するだけで誰でもお手軽に作れる（多分）、LINE Botのポートフォリを全5回で紹介、解説します。

第1回目でやることは、ポートフォリオの前段階としてTypeScriptとFirebaseを使って「おうむ返しをするだけのBot」の実装です。
LINE Botの開発そしたことがない人向けに、LINE BotやFirebaseの使い方についても説明しているので、安心してください。
ちなみに「おうむ返しをするBot」についての記事は数多くあるので、この第1回の記事は飛ばしてもらっても問題ありません。
次回以降では、このBotに機能を追加する形でポートフォリオを充実させていきます。

# 目次
 - [最終的にできるLINE Bot](#最終的にできるline-bot)
 - [そもそもLINE Botとは？](#そもそもline-botとは)
 - [LINE公式アカウントを作ろう](#lineアカウントを作ろう)
     - [LINE Botの例](#line-botの例)
 - [Firebaseを使ってみよう](#firebaseを使ってみよう)
 - [おうむ返しをさせよう](#おうむ返しをさせよう)
 - [おわりに](#おわりに)

# 最終的にできるLINE Bot
全5回の記事を通して作るLINE Botは次のような要素があるLINE Botです。
- ポートフォリオとして、プロフィールやアカウントが確認できる
- ZennやQiitaに投稿した記事が確認できる
- Github のパブリックなリポジトリを確認できる
- ポートフォリオを介して自分にメッセージを飛ばせる

全5回を通してこれらの機能を備えたポートフォリオLINE Botを作っていきます。

自分が作ったポートフォリオLINE Botは[こちら](https://lin.ee/WShvSEz)から友達になれます。
Githubで中身も公開しているので気になる人は見てみてください。

https://github.com/nissy-yuki/PortfolioLINEBot


### 使用技術
ポートフォリオLINE Botの開発には以下の技術を使用します。
- Node.js
- TypeScript
- Express
- MessagingAPI
- Firebase Cloud Functions
- ヘキサゴナルアーキテクチャ
- NotionAPI (プロフィールのDBとして)
- Qiita API
- Zenn API
- GitHub REST API
- LIFF
- React

# そもそもLINE Botとは？
LINE Botとはコミュニケーションアプリである「LINE」上で動作するBotのことです。LINE公式アカウントと呼ばれる情報発信向けのアカウントを使用して、不特定多数のユーザに対して情報発信や機能の提供を行うことが可能となっています。

https://www.lycbiz.com/jp/service/line-official-account/

GUI上で自動応答や配信メッセージなどを設定して、Botを運用することもできますが、[MessagingAPI](https://developers.line.biz/ja/reference/messaging-api/)を利用したプログラムによる複雑な応答や機能の提供を実現することも可能です。

今回はFirebase Cloude Funtionsを使って関数を公開し、それを利用してLINE Botに応答させます。

# LINE公式アカウントを作ろう
それでは、ポートフォリオとして使うためのLINE公式アカウントを作りましょう。
まずは、以下リンクからLINE Developersにアクセスして下さい。

https://developers.line.biz/console/

「LINEアカウントでログイン」から、普段利用しているLINEアカウントでログインするとLINE Developersにアクセスできます。
ただ、LINEアカウントにメールアドレスを登録していないとログインができないため、もししていない場合はLINEアプリの 設定＞アカウント＞メールアドレス からメールアドレスの登録が必要です。

無事にログインができたら、以下のような画面が開かれます。
日本語にしたい場合は右上の地球儀マークから変更してください。

![console_home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741818/aeeb5e63-3094-affa-9152-268b1161d963.png "LINE DevelopersのConsole Home")

[Provider](https://developers.line.biz/ja/glossary/#provider)(以下プロバイダー)というのは、アプリ(チャットボットやミニアプリなど)を提供する個人や組織のことです。このプロバイダーの中にアカウントを作るというイメージなので、createからプロバイダーを作成しましょう。

プロバイダーを作成できたら、このようなページが開かれます。

![provider_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741818/39ed948d-9f14-89ef-d818-bedfc602a624.png)

新たなLINE公式アカウント(正確にはチャンネル)を作成するには「Create a Messaging API channel」をクリックしてください。
すると、各種情報を入力するフォームが表示されるので、名前や説明など必要な部分を入力して「create」を押しましょう。

こんな画面になったら作成完了です。

![channle_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741818/2ca88043-0edf-1a7b-f1e0-e35a37b05ff6.png)

ここで、Botを開発するにあたって利用する2つのキーをメモしておきます。(必要な時に見てもらっても構いません。)
1つが チャネル基本設定 > チャネルシークレットです。
もう1つが  MessagingAPI設定 > チャネルアクセストークンです。
この2つをプログラムの中で使います。

２つのキーが確認できたら、作成したアカウントと友だちになって動作を確認してみましょう。

作成したアカウントは「認証アカウント」ではないので、検索では表示されません。そのため、QRコードなどから友だちに登録する必要があります。(勝手に友だちやトークに追加されていることもあります)
LINE Official Account Manager > 友だちを増やす > 友だち追加ガイド からQRコードやURLを取得できるのでそこから友だち登録をしましょう。

![manager_page.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741818/18f75e56-6e9a-358c-432d-cb294e39cb74.png)

無事にLINE公式アカウントとして動作してることが確認できましたか？
現状では何も設定してないので、最初のあいさつ以外は何を送っても「個別の問い合わせは対応していません」みたいな返事しか返ってきません。

プログラムによってLINE Botの応答を制御したい場合は、LINE公式アカウントのWebhookにエントリポイントを設定する必要があります。

# Firebaseを設定しよう
Webhookに設定するエントリポイントのためにFirebaseの設定をしましょう。
Firebase Cloud Functionsを使ってLINE Bot用の関数を公開してWebhookに設定します。

以下リンクからFirebaseでプロジェクトを作成してください。

https://firebase.google.com/?hl=ja

「使ってみる」から「プロジェクトを追加」を押して、今回のLINE Botに使うプロジェクトを追加しましょう。

Firebase Cloud Funtionsを利用するわけですが、無料プランのSparkだとFunctionsが使えないので、従量課金制のBlazeプランに変更してください。左下のところから変えられます。
「えー課金必要なの」と思うかもしれませんが、月200万回(2024年4月7日時点)以上呼び出すまでは無料なので基本的には課金されることはありません。

Blazeプランに変更できたら、Firebase上での準備は完了です。

# おうむ返しをさせよう
ここまで前準備として長々と説明をしてきました。
それでは、ようやくですが本題のLINE Bot開発に入りましょう。
ユーザが送信してきた内容をそのままオウム返しをするだけのLINE Botを実装します。

初めに、開発するLINE Bot用のディレクトリ作成してそのディレクトリに移動してください。
```
mkdir portfolio_bot
cd portfolio_bot
```

無事にディレクトリへ移動出来たら、firebaseプロジェクトの設定をします。
```
#Firebase CLI をインストール
npm install -g firebase-tools

#Google アカウントで Firebase にログイン
firebase login
```

```
#Firebaseプロジェクトの設定
firebase init

#プロジェクトで使う機能を選択。今回はFunctionsしか使わないのでFunctionsを選択してください。(色々選択してもらっても大丈夫です)
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection)
 ◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◉ Functions: Configure and deploy Cloud Functions
 ◯ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
 ◯ Emulators: Set up local emulators for Firebase features

#既存のプロジェクトを使用
? Please select an option:
Use an existing project

#先ほどFirebaseで作ったプロジェクトを選択
? Select a default Firebase project for this directory:
{先ほど作成したプロジェクト名}

#言語を聞かれるのでTypeScriptを選択
? What language would you like to use to write Cloud Functions? 
TypeScript

#あとは大体エンターを押すだけですが、一応ちゃんと何を聞かれてるか要確認してください
...

✔  Firebase initialization complete!
```

一通りの設定が完了するとportfolio_botがこのようなディレクトリ構造になると思います。

```
.
├── firebase.json
└── functions
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── src
    |   └── index.ts
    ├── tsconfig.json
    └── tslint.json
```

index.tsを書き換えることでLINE Botの挙動を変更することができます。
index.tsを書き換える前に必要なライブラリをインストールしてください。

```
cd functions
npm install @line/bot-sdk
npm install express
```

index.tsを以下のように書き換えてください。
```index.ts
import * as functions from 'firebase-functions';
import * as express from 'express'
import * as line from '@line/bot-sdk'

// LINE bot
const config = {
  channelSecret: "xxxxxxxxxxxxx......." ,//チャンネルシークレット
  channelAccessToken: "yyyyyyyyyyyyyyyyyyyyyyyyyyy......" //アクセストークン
};
const client = new line.Client(config);
const app = express();
app.post('/', line.middleware(config), (req, res) => {
  Promise.all(req.body.events.map(handleEvent))
    .then(() => res.status(200).end())
    .catch((err) => {
      console.error(err);
      res.status(500).end()
    })
});
//メッセージがきたらおうむ返しでメッセージを返す
async function handleEvent(event: any) {
  if (event.type === "message" && event.message.type === "text") {
    return client.replyMessage(event.replyToken, {type: "text", text: event.message.text})
  }
}
export const lineBot = functions.region("asia-northeast1").https.onRequest(app);
```

:::note alert
 チャンネルシークレットやアクセストークンが知られると、誰でもLINE Botを操作できるようになってしまうので、Githubのパブリックリポジトリなどオープンな場に載せないでください。
:::

index.tsを書き換えたらfirebaseにデプロイしてみましょう。
```
firebase deploy
```

少し待てばデプロイが完了します。
無事にデプロイできていれば、firebaseプロジェクト > functions から確認できます。

![firebase_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741818/7b73ba20-f2c1-9c1a-09e5-eee6ce8a4fc1.png)

あとは、LINE公式アカウントのWebhookにデプロイした関数のURLを設定するだけです。
MessagingAPI設定 > WebhookURL からFunctionsのURLを設定してください。

ここまでが終われば無事に「おうむ返しBot」の開発が完了しました。
実際に自分のLINE公式アカウントを触ってみて動作を確認してみましょう。

# おわりに
LINE Botでポートフォリオを作るための第一歩として、LINE Botについての説明や「おうむ返しBot」の実装を解説しました。
これで、LINE Bot開発についておおよそ理解できたもらえていたら幸いです。
次回からは、今回作ったBotを改造してポートフォリオBotを作っていきます。

### LINEBotでポートフォリオを作ろうシリーズ
未完成なのでお待ちください