LoginSignup
50
46

More than 5 years have passed since last update.

Slack BotとLINE BOTをとりあえず連携させてみた

Last updated at Posted at 2016-04-08

SlackBotが参加しているチャンネルに届いたメッセージをLINEBOT経由で送信
またLINEBOTに返信した場合もSlackの特定のチャンネルにメッセージが送信されるようにした

※ 現在LINE BOTはLINEグループに参加させることができないため、LINEグループとの連携はできない

環境変数

  • LINE_CHANNEL_ID
  • LINE_CHANNEL_SECRET
  • LINE_CHANNEL_MID

  • SLACK_TOKEN

  • SLACK_CHANNEL_NAME

Gemfile
# Gemfile
source 'https://rubygems.org'

gem 'sinatra'
gem 'httpclient'
gem 'activerecord'
gem 'ridgepole', '0.5.2'
gem 'sqlite3'
gem 'slack-api'
app.rb
require 'bundler/setup'
require 'sinatra'
require 'json'
require 'httpclient'
require 'certified'
require 'active_record'
require 'slack'

set :bind, '0.0.0.0'

ActiveRecord::Base.configurations = {
  "production" => {
    adapter: "sqlite3",
    database: "bot.db"
  }
}

ActiveRecord::Base.establish_connection(:production)

LINE_HTTP_HEADERS = {
  'Content-Type' => 'application/json; charset=UTF-8',
  'X-Line-ChannelID' => ENV["LINE_CHANNEL_ID"],
  'X-Line-ChannelSecret' => ENV["LINE_CHANNEL_SECRET"],
  'X-Line-Trusted-User-With-ACL' => ENV["LINE_CHANNEL_MID"]
}

class User < ActiveRecord::Base
  def generate_token!
    self.token = Digest::SHA256.hexdigest("BOT_#{line_user_id}")
  end

  def send_message_with_line(message)
    HTTPClient.new.post_content('https://trialbot-api.line.me/v1/events',
      { to: [line_user_id],
        toChannel: 1383378250, # Fixed value
        eventType: "138311608800106203", # Fixed value
        content: { toType: 1, contentType: 1, text: message }
      }.to_json, LINE_HTTP_HEADERS)
  end
end

Slack.configure {|config| config.token = ENV["SLACK_TOKEN"] }
slack = Slack.realtime

post '/linebot/callback' do
  params = JSON.parse(request.body.read)

  params['result'].each do |message|
    user = User.find_or_create_by(line_user_id: message['content']['from'])

    if user.slack_user_id.blank?
      response = HTTPClient.new.get_content('https://trialbot-api.line.me/v1/profiles',
                                            { mids: message['content']['from'] },
                                            LINE_HTTP_HEADERS)

      json = JSON.parse(response)

      user.line_display_name = json["contacts"][0]["displayName"]
      user.generate_token!
      user.save

      user.send_message_with_line("ようこそ #{user.line_display_name} さん\n本人確認のため、SlackのBotに\ntoken[#{user.token}]\nを送信してください")
    else
      Slack::Client.new.chat_postMessage(text: message["content"]["text"],
                                         channel: ENV["SLACK_CHANNEL_NAME"],
                                         username: user.line_display_name)
    end
  end

  "OK"
end

get '/elb-status' do
 "OK"
end

slack.on :hello do
  puts 'Successfully connected.'
end

slack.on :message do |data|
  p data
  if token = data["text"][/token\[(.*?)\]/, 1]
    p token
    if user = User.find_by(token: token)
      user.slack_user_id = data["user"]
      user.save
      user.send_message_with_line("slackとの接続が確認できました")
    end
  end

  if data["type"] == "message" and not data["bot_id"]
    User.where.not(slack_user_id: nil).each do |user|
      user.send_message_with_line("#{user.line_display_name}: #{data["text"]}")
    end
  end
end

Thread.new do
  slack.start
end
Schemafile
create_table "users", force: :cascade do |t|
  t.string :line_display_name
  t.string :slack_display_name

  t.string :slack_user_id
  t.string :line_user_id

  t.string :token
end

マイグレーション

ridgepole.yml
adapter: sqlite3
database: bot.db
ridgepole -c ridgepole.yml --apply

簡単な流れ

  1. LINEBOTに適当に挨拶を送る
  2. LINEBOTから本人確認用のトークンを送信
  3. 2のトークンをSlackのBotに送信
  4. 連携完了!

参考

http://qiita.com/betchi/items/8e5417dbf20a62f2239d
http://qiita.com/betchi/items/8e5417dbf20a62f2239d

50
46
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
50
46