LoginSignup
1
0

More than 3 years have passed since last update.

VPSを借りる [Ruby、Sinatra、Puma、LINE Bot] #5

Posted at

line-bot-sdk-ruby @LINE Corp

NAME=yourname

LINE_CHANNEL_ID=yourid
LINE_CHANNEL_SECRET=yoursecret
LINE_CHANNEL_TOKEN=yourtoken

DOMAIN=yourdomain

sudo dnf install @ruby ruby-devel make

sudo gem install rubygems-update --no-document --install-dir=/usr/share/gems
sudo gem update --system --no-document
sudo gem install bundler -n /usr/local/bin --no-document
sudo gem list

sudo mkdir /var/www/app
sudo chown -R $NAME: /var/www/app
cd /var/www/app

bundle init

tee -a Gemfile << EOF
gem "nio4r"
gem "sinatra"
gem "puma"
gem 'line-bot-api'
EOF

bundle config set --local path 'vendor/bundle'

bundle install

tee /var/www/app/app.rb << EOF
# app.rb
require 'sinatra'
require 'line/bot'

def client
  @client ||= Line::Bot::Client.new { |config|
    config.channel_id = ENV["LINE_CHANNEL_ID"]
    config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
    config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
  }
end

post '/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
        message = {
          type: 'text',
          text: event.message['text']
        }
        client.reply_message(event['replyToken'], message)
      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

  # Don't forget to return a successful response
  "OK"
end
EOF

sudo tee /etc/sysconfig/linebot.conf << EOF
LINE_CHANNEL_ID="$LINE_CHANNEL_ID"
LINE_CHANNEL_SECRET="$LINE_CHANNEL_SECRET"
LINE_CHANNEL_TOKEN="$LINE_CHANNEL_TOKEN"
EOF

tee config.ru << EOF
require_relative "app"
run Sinatra::Application
EOF

mkdir config

tee config/puma.rb << EOF
require "fileutils"

#root path
app_path = File.expand_path("..", __dir__)
tmp_dirs = ["tmp/pids","tmp/sockets" ,"log"]

tmp_dirs.each do |path|
  mk_path = File.join(app_path, path)
  FileUtils.mkdir_p(mk_path) unless Dir.exist?(mk_path)
end

#default directory
directory app_path
#env mode
environment 'production'

#service daemon
#daemonize

#process id file
pidfile "#{app_path}/tmp/pids/puma.pid"

#puma status file
state_path "#{app_path}/tmp/pids/puma.state"

#stdout, stderr put file
stdout_redirect "#{app_path}/log/app.log", "#{app_path}/log/app_err.log", true

#thread settting low, high
threads 0, 16

#socket type
#bind 'tcp://0.0.0.0:9292' #=> tcp socket
bind "unix:///#{app_path}/tmp/sockets/puma.sock"

#pumactl
activate_control_app
EOF

sudo tee /etc/nginx/conf.d/$DOMAIN.conf << EOF
server {
    listen 80;
    listen [::]:80;

    server_name www.$DOMAIN $DOMAIN;

    include snippets/letsencrypt.conf;

    location / {
        return 301 https://\$host\$request_uri;
    }
}

server {
    listen 443 ssl http2;

    server_name www.$DOMAIN $DOMAIN;

    ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/$DOMAIN/chain.pem;

    include snippets/ssl.conf;

    root /var/www/$DOMAIN/public_html;

    index index.php;

    access_log /var/log/nginx/$DOMAIN.access.log;
    error_log /var/log/nginx/$DOMAIN.error.log;

    location /app/ {
        rewrite /app/(.*) /\$1 break; 

        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header Host \$http_host;

        proxy_pass http://unix://var/www/app/tmp/sockets/puma.sock;
    }

    location ~ \.php\$ {
        try_files \$uri =404;
        fastcgi_pass unix:/run/php-fpm/www.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME \$document_root\$fastcgi_script_name;
        include fastcgi_params;
    }
}
EOF

sudo nginx -t

#sudo cat /var/log/audit/audit.log | grep nginx | audit2allow -m nginx
#sudo cat /var/log/audit/audit.log | grep nginx | audit2allow -M nginx

tee nginx.te << EOF
module nginx 1.0;

require {
        type http_port_t;
        type httpd_sys_content_t;
        type httpd_t;
        class tcp_socket name_connect;
        class sock_file write;
}

#============= httpd_t ==============

#!!!! This avc is allowed in the current policy
allow httpd_t http_port_t:tcp_socket name_connect;
allow httpd_t httpd_sys_content_t:sock_file write;
EOF

sudo checkmodule -M -m -o nginx.mod nginx.te
sudo semodule_package -o nginx.pp -m nginx.mod
sudo semodule -i nginx.pp

sudo tee /etc/systemd/system/puma.service << EOF
[Unit]
Description=Puma Application Server
After=network.target

[Service]
Type=simple
User=$NAME
EnvironmentFile=/etc/sysconfig/linebot.conf
WorkingDirectory=/var/www/app/
ExecStart=bundle exec pumactl start
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo chmod +x /etc/systemd/system/puma.service
sudo systemctl enable puma
sudo systemctl start puma
systemctl status puma

sudo systemctl restart puma
sudo systemctl restart nginx

image.png
VPSを借りる [VPS、SSH、Nginx] #1
VPSを借りる [HTTPS] #2
VPSを借りる [PHP] #3
VPSを借りる [PostgreSQL] #4

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0