最速で!最短で!真っ直ぐに!Facebookグループの書き込みを監視する方法!
皆さん、こんにちは!WAというと Web Application ではなく、RPGの方を思い出す MUGENUP の osada です。
いきなりの個人的な話で恐縮ですが、私が初めて書いたWeb Application はPHP
でした。当時 Web というと、「SSI で include」したり、「perl で cgi」とか、少し大掛かりだと「Java Applet」?、程度しか知らなかった私には、HTMLの中にプログラムが書けるというのは衝撃的なことでした。PHPの真髄は、すぐに動くことにあるのではないかと思っています。そしてさらに個人的な意見で恐縮ですが、ソースコードで最も価値があるのは動くコードだと思っています。少し学術的に言えば、合目的性ですね。そう言う意味で、PHPは私の好きな言語の一つです。PHP、良い言語ですよね!
はい、ということで今回は、コードの美しさとか全くなし。動けばOK、ということで、Facebook Group への書き込みをウォッチして、新着があったらメールで知らせる ツールを作ってみたいと思います。
え、理由ですか?単に必要だったからです(笑)。
Facebook Developer に登録して、アプリを作成
facebook developer へ登録
app へ
新しいアプリを作成 ボタン
新しいアプリを作成
-
承認
こんな感じに
Graph APIエクスプローラーを使用する
アクセストークンを取得
user groups にチェック
friends groups にチェックして、[Get Access Token]
アクセストークンをコピー
Facebook にアクセスする
koala
と メール送信用にmail
をインストール
# Gemfile source 'https://rubygems.org' gem "koala", "~> 1.8.0rc1" gem "mail" group :test, :development do gem "pry" gem 'pry-byebug' end
$ bundle
14.書く
watch_facebook.rb
# -*- coding: utf-8 -*- require "koala" require "mail" ACCESS_TOKEN = ARGV[0] GROUP_ID = ARGV[1] USER_NAME = ARGV[2] PASSWORD = ARGV[3] EMAILS = ARGV[4..-1] SMTP_SETTINGS = { address: 'smtp.gmail.com', port: 587, domain: 'smtp.gmail.com', user_name: USER_NAME, password: PASSWORD } FROM = "hoge-report@mugenup.com" SUBJECT = 'Hoge Report' begin load "config.rb" rescue LoadError end puts "access facebook ..." graph = Koala::Facebook::API.new(ACCESS_TOKEN) feeds = graph.get_connections(GROUP_ID, "feed") puts "reject already feeds ..." already_feeds_file = open("already_feeds.txt", "a+") already_read_ids = already_feeds_file.readlines.map(&:chomp) new_feeds = feeds.reject{|f| already_read_ids.include?(f["id"]) } exit if new_feeds.size == 0 puts "create messages ..." messages = new_feeds.map do |f| <<-EOS #{f["from"]["name"]} #{f["message"][0..100]}... #{'-' * 50} EOS end messages << "https://www.facebook.com/groups/#{GROUP_ID}/" puts "send mail new feeds ..." mail = Mail.new do from FROM to EMAILS.join(",") subject SUBJECT body messages.join("\n") end mail.charset = 'utf-8' mail.delivery_method :smtp, SMTP_SETTINGS mail.deliver! puts "store feed_ids (#{new_feeds.size}) ..." already_feeds_file.puts(new_feeds.map{|f| f["id"]}) already_feeds_file.close
15.使う
$ bundle exec ruby watch_facebook.rb ACCESS_TOKEN GROUP_ID USER_NAME PASSWORD EMAILS
← 適宜読み替えて入力してください。
または、config.rb
というのを作って、
こんな感じに書いてから、
$ bundle exec ruby watch_facebook.rb
16.ACCESS_TOKENの長期化
このままだと、ACCESS_TOKEN の有効期間は1時間です。これを長期化します。
omniauth を入れる(心の)余裕は無いんです!
ということで、下記を参考に、(7)で確認した、app-idとapp-secret、および、アクセストークンを入力して、送信します。
https://graph.facebook.com/oauth/access_token? grant_type=fb_exchange_token& client_id={app-id}&client_secret={app-secret}&fb_exchange_token={short-lived-token}
Unable to get a long term access token using facebook graph api - Stack Overflow
17.長期化されたアクセストークンを使う
こんな感じで、新しく長期化されたアクセストークンが取得できます。
expires
が 5184000
になっていることが確認できます。約2ヶ月、使い続けられます。
18.後は cron で登録するなりなんなり!
あ、cron
でbundle
付きを呼ぶのはちょっと面倒ですが、頑張ってください!
ということで、Facebookのグループを監視するアプリが作れました!
ちょっと解説
設定を引数から受け取る部分
ACCESS_TOKEN = ARGV[0] GROUP_ID = ARGV[1] USER_NAME = ARGV[2] PASSWORD = ARGV[3] EMAILS = ARGV[4..-1] SMTP_SETTINGS = { address: 'smtp.gmail.com', port: 587, domain: 'smtp.gmail.com', user_name: USER_NAME, password: PASSWORD } FROM = "hoge-report@mugenup.com" SUBJECT = 'Hoge Report'
初めに、一番速いのはなんだろう?と思って、ACCESS_TOKEN
を直書きしたのですが、これをコミットしてはいけないとゴーストが囁いたので、引数で渡すことにしました。
設定をファイルから受け取る部分
begin load "config.rb" rescue LoadError end
そうこうしているうちに、毎回引数で渡すのが面倒くさい、ということになり、ファイルに格納することにしました。このconfig.rb
は .gitignore
で対象外にしました。
Facebook のグループからメッセージを獲得する部分
puts "access facebook ..." graph = Koala::Facebook::API.new(ACCESS_TOKEN) feeds = graph.get_connections(GROUP_ID, "feed")
特に解説することはありません
既に確認済みのメッセージを削除する部分
puts "reject already feeds ..." already_feeds_file = open("already_feeds.txt", "a+") already_read_ids = already_feeds_file.readlines.map(&:chomp) new_feeds = feeds.reject{|f| already_read_ids.include?(f["id"]) } exit if new_feeds.size == 0
……特に解説することはありません
メール送信用のメッセージを作る部分
puts "create messages ..." messages = new_feeds.map do |f| <<-EOS #{f["from"]["name"]} #{f["message"][0..100]}... #{'-' * 50} EOS end messages << "https://www.facebook.com/groups/#{GROUP_ID}/"
......……特に解説することはありません(まさか解説する箇所は出てこないのでしょうか?)
メールを送信する部分
puts "send mail new feeds ..." mail = Mail.new do from FROM to EMAILS.join(",") subject SUBJECT body messages.join("\n") end mail.charset = 'utf-8' mail.delivery_method :smtp, SMTP_SETTINGS mail.deliver!
当初mail
コマンドを使用していたのですが、
connect to aspmx3.googlemail.com[74.125.137.26]:25: Connection refused
ということで、mac
のsmtp
からダイレクトに送れなかったため、mail
gemを導入しました。
これがなければ、もっとシンプルでもっと速く作れたのに、と思うとちょっと残念です。
さて、Mail ですが、送信相手が複数居る時は、カンマで区切りましょう。
charaset
を utf-8
にしないと、Non US-ASCII detected and no charset defined.
という警告がでます。
(説明することが合って良かったぁ〜)
送信したメッセージのIDを記録しておく部分
puts "store feed_ids (#{new_feeds.size}) ..." already_feeds_file.puts(new_feeds.map{|f| f["id"]}) already_feeds_file.close
特に説明することはありません!
まとめ
以上が、Facebookの特定のグループの新着をメールで送信するツールです。
全くシンプルに、ただ動くことだけを考えて書いたコードですが、いかがだったでしょうか?
ついつい、「DBを使おう」とか「ActiveSuppoだけでも使おう」とか、「関数に分けよう」とか、「クラスを作ろう」とか色々考えてしまうのですが、問題を解決することだけに注目するというのも、また楽しいプログラミングですよね!
そうそうPHPが好きだと言いましたが、単に作成者のRasmus Lerdorf
氏が好きなだけかもしれません。彼の発言は一読の価値があると思いますので、宜しければ一度、Rasmus Lerdorf - Google 検索してみてください!
宣伝
MUGENUP では、rails を使いたいエンジニアを募集中です。 無限流開発、ご一緒しませんか?
大きな裁量で自社サービス開発!Rubyエンジニアをウォンテッド! - 株式会社MUGENUPの求人 - Wantedly
あ、WAでビンタしあう方を思い出す方は友達になりましょう。