LoginSignup
18
21

More than 5 years have passed since last update.

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

Posted at

やりたいこと

写真はよくスマホで取るので溜まっていくけど、数が増えてくると過去の写真って埋もれていくよね. 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で毎朝一枚送信、あとはリクエストしたら適宜送ってくれるような感じにして使っている. なかなか楽しい.

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

18
21
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
18
21