Line
bot

LINE Messaging APIを使ってランダムな写真を送信する

More than 1 year has passed since last update.


やりたいこと

写真はよくスマホで取るので溜まっていくけど、数が増えてくると過去の写真って埋もれていくよね. botが適当な写真を選んで送ってくれたりすると楽しいのでは.

ということで、Googleフォトの特定のアルバムからランダムに写真を選んで、LINEのトークに送信する、という機能をbotに実装した. ルーム内の発言に反応して送ったり、定期的にルームに投稿したりする.

LINE_photo_mosaic.png


準備


実装

rubyでやる. LINE, Googleともに色々な言語でライブラリが出ているので、好きなものを使えば良いと思う.


Googleフォトからランダムに写真を取得

Picasa Web Album Data API を使う. rubyから使うので、https://github.com/morgoth/picasa を使用した.

こんな感じ. get_random_photo_url を呼ぶと、アルバム中写真から、どれか一枚のURLが返る.

require 'signet/oauth_2/client'

require 'picasa'
require 'dotenv'

Dotenv.load

class PicasaClient

def initialize
@client = nil
end

def client
@client ||= Picasa::Client.new(user_id: ENV['GOOGLE_USER_ID'], access_token: access_token)
end

def access_token
signet = Signet::OAuth2::Client.new(
client_id: ENV['GOOGLE_CLIENT_ID'],
client_secret: ENV['GOOGLE_CLIENT_SECRET'],
token_credential_uri: "https://www.googleapis.com/oauth2/v3/token",
refresh_token: ENV['GOOGLE_REFRESH_TOKEN']
)
signet.refresh!

# Use access token with picasa gem
puts "access_token:" + signet.access_token
signet.access_token
end

def get_random_photo_url
album = client.album.list.entries.find{ |a| a.title == ENV['GOOGLE_PHOTO_ALBUM_NAME'] }
photo = client.album.show(album.id).entries.sample
photo.content.src
end
end


LINE Botから画像を送る

一方的に写真を送るようなコマンドを作ってみる. こんな感じ. ENV['LINE_SEND_TARGET']の部分は、送信先のユーザまたはグループのID. 前者は"U...", 後者は"C..."みたいな形をしている. (これはどこから取るのが楽なんだろう. 自分は、webhook用に立てたサーバで、受信したイベントを出力して取得した)

require 'line/bot'

require 'dotenv'

Dotenv.load

def line_send_image(target, image_url)
line_client = Line::Bot::Client.new { |config|
config.channel_secret = ENV['LINE_CHANNEL_SECRET']
config.channel_token = ENV['LINE_CHANNEL_TOKEN']
}
message = {
type: "image",
originalContentUrl: image_url,
previewImageUrl: image_url
}
line_client.push_message(target, message)
end

log = Logger.new(STDOUT) # !> assigned but unused variable - log
picasa = PicasaClient.new
line = LineClient.new
photo_url = picasa.get_random_photo_url
res = line.send_image(ENV['LINE_SEND_TARGET'], photo_url)


会話に反応して画像を送る

Botのwebhook URLで指定したURLにWebサーバを立てることになる. ここでは、トーク内で'p' (photoのこと) と発言されたら、上と同じ要領でランダムな画像をピックアップして返すようにする.

require "sinatra/base"

require 'line/bot'
require 'dotenv'

module MyBotserver
class Server < Sinatra::Base
Dotenv.load

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

post '/line' do
request.body.rewind
body = request.body.read
events = client.parse_events_from(body)
events.each do |event|
case event
when Line::Bot::Event::Message
when Line::Bot::Event::MessageType::Text
message = {}
case event.message['text']
when /^p$/
logger.info "Sending photo"
picasa = PicasaClient.new
photo_url = picasa.get_random_photo_url
message = {
type: 'image',
originalContentUrl: photo_url,
previewImageUrl: photo_url
}
res = client.reply_message(event['replyToken'], message)
logger.warn "Message send error: " + res.body unless res.is_a?(Net::HTTPOK)
end
unless message.empty?
logger.info "Sending message #{message}"
client.reply_message(event['replyToken'], message)
end
end
end
end
end
end


まとめ

LINE Messaging APIを使って、Googleフォトからランダムな写真をLINEトークに送信する機能を実装してみた. 自分は、cronで毎朝一枚送信、あとはリクエストしたら適宜送ってくれるような感じにして使っている. なかなか楽しい.

子供の昔の写真を送るとか、空腹な時間を狙って飯画像を送るとか、遊ぶと良いと思う.