アルパカログ

Webエンジニア兼マネージャーがプログラミングやマネジメント、読んだ本のまとめを中心に書いてます。

GCP Compute Engine(GCE)の無料枠でLINE Botを作る方法

f:id:otoyo0122:20200919173802p:plain:w300

GCPのCompute Engine(GCE)を使えば無料枠の範囲内でLINE Botを作ることができます。

このエントリでは、GCEを使ってLINE Botを作る方法を説明します。

※Cloud Functionsを使ってサーバーレスで作る方法は下記で紹介しています。

GCP Cloud Functions(GCF)を使ってサーバーレスでLINE Botを作る方法 - アルパカログ

システム構成

システム構成は下記の通りです。一般的なWebサービスと同じような構成で、特に変わったところはないかと思います。

f:id:otoyo0122:20180111183004p:plain:w600

設定と手順

GCPの設定は、下記のサイトを参考にするとわかりやすいです。

今回はSinatraを使うためRubyをインストールします。おおまかには次のような手順です。

  1. GCEでusリージョンにf1-microインスタンスを立てる
  2. SSHのポート変更 (ネットワークタグ)
  3. IPアドレスの固定
  4. Ruby & RubyGemsのインストール

DNS設定

所有しているドメインから、固定したGCEのIPアドレスが引けるようにAレコードを設定します。

無料クレジットを使うものの、GCPのDNSサービス(CLOUD DNS)が使えます。

SSL証明書取得

SSL証明書は無料のLet's Encryptを使います。

有効期間は90日と短めですが、証明書はCertbotと呼ばれるクライアントを使って簡単に取得、更新することができます。

さらにDebianだと、Certbotインストール時に証明書更新のCRONジョブを自動で追加してくれるので便利です。

証明書の更新コマンドcertbot renewは動作確認のため一度は実行しておきましょう。

パーミッションエラーになってしまう場合は、、パーミッションを付与して実行できることを確認しておきましょう。

Nginxの設定

NginxにSSL証明書を設定します。

セキュリティのために「NginxでSSLの評価をA+にする手順」を参考に、SSLv3の無効化など対応しておきましょう。

下記は今回の設定例です。Unicornを使うためupstreamディレクティブでソケットファイルを指定しています。

/etc/nginx/conf.d/ssl.conf

upstream linebot {
    server unix:/tmp/linebot.sock;
}

server {
    listen                     443;
    server_name                example.com;
    ssl                        on;
    ssl_certificate            /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key        /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols              TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers  on;
    ssl_ciphers                ECDHE+RSAGCM:ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!aNULL!eNull:!EXPORT:!DES:!3DES:!MD5:!DSS;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /linebot/ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_pass http://linebot;
        proxy_redirect http:// https://;
    }
}

SinatraをUnicornで動かす

下記ページが参考になります。

LINE Messaging APIの使い方はLINE Bot SDKに言語ごとにまとめられています。そのままで動くようになっています。

今回作ったLINE Botのコードの抜粋を掲載しておきます。

config.ru

require './app.rb'
run Linebot

app.rb

class Linebot < Sinatra::Base
  def client
    @client ||= Line::Bot::Client.new do |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    end
  end

  post '/linebot/callback' do
    body = request.body.read

    signature = request.env['HTTP_X_LINE_SIGNATURE']
    unless client.validate_signature(body, signature)
      error 400 do 'Bad Request' end
    end

    events = client.parse_events_from(body)
    events.each do |event|
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          reply_text = build_reply_text event.message['text']
          if !reply_text.nil? && reply_text != ""
            client.reply_message(event['replyToken'], type: 'text', text: reply_text)
          end
        when Line::Bot::Event::MessageType::Image, Line::Bot::Event::MessageType::Video
          response = client.get_message_content(event.message['id'])
          tf = Tempfile.open("content")
          tf.write(response.body)
        end
      end
    end

    "OK"
  end
end

LINE Botの様子

f:id:otoyo0122:20180128094952p:plain:w300

以上です。

このエントリでは、GCEを使ってLINE Botを作る方法を説明しました。

参考になった方は、ぜひ「はてブ」やSNSでシェアしていただけると嬉しいです。