【やってみた】Google Cloud RunとNode.jsで作る オウム返し LINE Bot 構築ガイド

# 🎈はじめに

簡単な LINE Bot を構築する機会をいただきました。
せっかくなのでナレッジ残してみました。

# 📖この記事について

**Google Cloud Run** と **Node.js** を使って、簡単にLINE Botを開発する手順を解説します。

# 🤖作成するBot

ユーザーが送信したメッセージを、そのままオウム返しするシンプルなBotです。

## 技術スタック

  * **バックエンド**: Google Cloud Run
  * **言語**: Node.js
  * **機密情報管理**: Google Secret Manager
  * **Botプラットフォーム**: LINE Messaging API

## 全体的な流れ

![2025-05-25_221738.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331618/8594b299-7a51-4a9b-8a90-085e06f81382.png)

# 🏗️構築手順

## Step 1: 【LINE】チャネルの準備と2種類のキー取得

まず、LINE Botの本体となる「チャネル」を用意します。
現在のLINEの仕様では、先にLINE公式アカウントを作成してから、Bot機能（Messaging API）を有効化します。

1.  **LINE Developersにログインとプロバイダー作成**
    [LINE Developersコンソール](https://developers.line.biz/console/)にログインし、任意の名前で「プロバイダー」を作成します。

2.  **LINE公式アカウントの作成**
    プロバイダーを選択し、チャネル作成画面に進むと、「Messaging APIチャネルを直接作成することはできなくなりました」と表示されます。
    画面の指示に従い、「**Create a LINE Official Account**」ボタンからLINE公式アカウントを作成してください 。

3.  **Messaging APIの有効化**
    LINE公式アカウントの管理画面（LINE Official Account Manager）に移動したら、「設定」\>「**Messaging API**」を開き、APIの利用を有効化します。

4.  **2種類のキーを取得する**
    Botをプログラムから操作するには、役割の違う2つのキーが必要です。
    [LINE Developersコンソール](https://developers.line.biz/console/)に戻り、作成したチャネルを開いて取得します。

      **① Channel Secret（合言葉的なやつ）**
        LINEからの通信が本物か検証するためのキーです。
          * **場所**: 「Basic settings」タブ
          * **取得方法**: ページ中ほどの「Channel secret」に表示されている文字列をコピー。

      **② Channel Access Token（許可証みたいなもの）**
        Botがユーザーにメッセージを返信するために使うキーです。
          * **場所**: **「Messaging API」**タブ
          * **取得方法**: ページ最下部の「Channel access token」にある「**Issue**」ボタンを押して、表示された長い文字列をコピーします。

## Step 2: 【Google Cloud】プロジェクト準備とAPI有効化

1.  [Google Cloudコンソール](https://console.cloud.google.com/)でプロジェクトを作成または選択します。
2.  ナビゲーションメニュー `☰` \>「APIとサービス」\>「ライブラリ」で、以下の**4つのAPI**を検索し、すべて「有効にする」をクリックします。
      * `Cloud Run API`
      * `Secret Manager API`
      * `Cloud Build API`
      * `Artifact Registry API`

## Step 3: 【Google Cloud】機密情報の安全な保管

Step 1で取得した2つのキーを、安全な金庫である「Secret Manager」に保管します。

ナビゲーションメニュー `☰` \>「セキュリティ」\>「**Secret Manager**」を開き、「シークレットを作成」から以下の2つを作成します。

  * **名前**: `line-channel-secret`
      * **シークレットの値**: 取得した「Channel Secret」の文字列を貼り付けます。
  * **名前**: `line-channel-access-token`
      * **シークレットの値**: 取得した「Channel Access Token」の文字列を貼り付けます。

## Step 4: 【Google Cloud】Botプログラムの作成

ブラウザ上の開発環境「Cloud Shell」（コンソール右上の `>_` アイコン）を起動し、Botのプログラムを作成します。

1.  Cloud Shellのターミナルで、作業ディレクトリを作成します。

    ```bash
    mkdir line-bot-app && cd line-bot-app
    ```

2.  Cloud Shellの「エディタを開く」ボタンを押し、以下の3つのファイルを `line-bot-app` ディレクトリ内に作成します。

    ```dockerfile:Dockerfile
    # Node.js v20 の公式イメージをベースに使用
    FROM node:20-slim

    # アプリケーション用のディレクトリを作成
    WORKDIR /usr/src/app

    # アプリケーションの依存関係をインストール
    COPY package*.json ./
    RUN npm install --production

    # アプリケーションのソースコードをコピー
    COPY . .

    # コンテナ起動時にアプリケーションを実行
    CMD [ "npm", "start" ]
    ```
    ```json:package.json
    {
      "name": "line-bot-express",
      "version": "1.0.0",
      "description": "LINE Bot echo server on Cloud Run",
      "main": "index.js",
      "scripts": {
        "start": "node index.js"
      },
      "dependencies": {
        "@line/bot-sdk": "^9.2.0",
        "express": "^4.19.2"
      }
    }
    ```

    
    ```javascript:index.js
     // 「厳格モード」有効
    'use strict';

    // 必要なライブラリをインポート
    const express = require('express');    // Webサーバーを構築するためのフレームワーク
    const line = require('@line/bot-sdk'); // LINE Messaging APIを簡単に利用するための公式ライブラリ

    // Google Cloud Runによって設定された環境変数から、アクセストークンとチャネルシークレットを読み込み
    const config = {
      channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN,
      channelSecret: process.env.LINE_CHANNEL_SECRET,
    };

    const app = express();

    // '/callback' というパスにPOSTリクエストが来たときに、この部分が実行される
    app.post('/callback', line.middleware(config), (req, res) => {
      // 署名検証が成功した場合、以下の処理実行
      // Webhookリクエストには複数のイベントが含まれることがあるらしく、Promise.allですべてのイベントを処理
      Promise
        .all(req.body.events.map(handleEvent))
        .then((result) => res.json(result))
        .catch((err) => {
          console.error(err);    // コンソールにエラーログを出力。
          res.status(500).end(); // LINE Platformに対して「500 Internal Server Error」を返す。
        });
    });

    // 個々のイベントを処理する非同期関数
    function handleEvent(event) {
      // イベントが「メッセージ」であり、かつ「テキストメッセージ」でなければ、何もしないで処理を終了
      // スタンプや画像は無視
      if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
      }
      const client = new line.Client(config);                  // LINE SDKのクライアントを作成
      const echo = { type: 'text', text: event.message.text }; // オウム返しするメッセージを作成
      return client.replyMessage(event.replyToken, echo);      // 作成したメッセージをユーザーに返信
    }

    const port = process.env.PORT || 8080;
    app.listen(port, () => {
      console.log(`listening on ${port}`);
    });
    ```

## Step 5: 【Google Cloud】Cloud Runへのデプロイ

### 5-1. IAM権限の事前設定

デプロイ時には、裏側で2人の担当者（サービスアカウント）が動きます。
この2人にあらかじめ適切な権限を与えておきましょう。

1.  ナビゲーションメニュー `☰` \>「**IAMと管理**」\>「**IAM**」を開きます。

2.  ページの右上にある「**Google 提供のロール付与を含める**」に**必ずチェックを入れます**。
※これをしないと、担当者が見えません。

3.  プリンシパル（担当者）の一覧から、以下の2つのアカウントを探し、それぞれの行の右端にある**鉛筆アイコン**をクリックして、指定のロールを追加・保存します。

      **① ビルド担当者への権限付与**
          **【対象アカウント】**:
          `[数字]@cloudbuild.gserviceaccount.com`
          **【追加するロール】**:
            1.  `Cloud Build サービスエージェント`
            2.  `サービス アカウント ユーザー`

      **② 実行担当者への権限付与**
          **【対象アカウント】**: 
          `[数字]-compute@developer.gserviceaccount.com` (Default compute service account)
          **【追加するロール】**:
            1.  `Secret Manager シークレット アクセサー`

### 5-2. デプロイコマンドの実行

権限設定が完了したら、Cloud Shellに戻り、デプロイを実行します。

1.  プロジェクトIDなどを変数に設定します。（`your-project-id`はご自身のGCPプロジェクトIDに書き換えてください）
    ```bash
    PROJECT_ID="your-project-id"
    REGION="asia-northeast1"
    SERVICE_NAME="line-bot-service"
    ```
2.  デプロイコマンドを実行します。
    ```bash
    gcloud run deploy $SERVICE_NAME \
      --source . \
      --platform managed \
      --region $REGION \
      --allow-unauthenticated \
      --set-secrets="LINE_CHANNEL_SECRET=line-channel-secret:latest" \
      --set-secrets="LINE_CHANNEL_ACCESS_TOKEN=line-channel-access-token:latest" \
      --project=$PROJECT_ID
    ```
3.  デプロイが成功すると、`Service URL:` が表示されます。
この**URLをコピー**してください。
    ```bash
    Service URL: https://XXXXXXXXXXXXXXXXXXXXXXXXX.asia-northeast1.run.app
    ```
## Step 6: 【LINE & Google Cloud】Webhook設定による連携

最後に、LINEに「ユーザーからメッセージが来たら、このURLに知らせてね」と教えます。

1.  [LINE Developersコンソール](https://developers.line.biz/console/)の「Messaging API」タブに戻ります。
2.  「Webhook settings」にある「Webhook URL」の「Edit」ボタンを押します。
3.  Step 5でコピーしたCloud RunのURLを貼り付け、**末尾に `/callback` と追記**するのを忘れないでください。
      * 例: `https://XXXXXXXXXXXXXXXXXXXXXXXXX.asia-northeast1.run.app/callback`
4.  「Update」をクリックし、その下にある「Use webhook」のスイッチをON（緑色）にします。

## Step 7: 動作確認

LINE Developersコンソールの「Messaging API」タブにあるQRコードをスマートフォンで読み取り、作成したBotを友だち追加して、メッセージを送ってみましょう。
メッセージがそのまま返ってきたら成功です✅

# 🙇‍♀️おわりに

ここまで読んでいただいてありがとうございます🙇‍♀️
だれかの参考になっていたらうれしいです。