1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# frozen-string-literal: true
# client/twitter.rb
# Twitter の User stream に(現在はサーバーが非対応のため)HTTP/1.1 を使用して接続する。
# 「にゃーん」を含むツイートを受信したら、REST API で HTTP/2 を使用して返信する。
$LOAD_PATH.unshift File.expand_path("../../../lib", __FILE__)
require "plum"
require "json"
require "cgi"
require "simple_oauth"
credentials = { consumer_key: "",
consumer_secret: "",
token: "",
token_secret: "" }
rest = Plum::Client.start("api.twitter.com", 443)
Plum::Client.start("userstream.twitter.com", 443) { |streaming|
streaming.get("/1.1/user.json",
headers: { "authorization" => SimpleOAuth::Header.new(:get, "https://userstream.twitter.com/1.1/user.json", {}, credentials).to_s,
"accept-encoding" => "gzip, deflate" }) { |res|
if res.status != "200"
puts "failed userstream"
exit
end
buf = String.new
res.on_chunk { |chunk| # when received DATA frame
next if chunk.empty?
buf << chunk
*msgs, buf = buf.split("\r\n", -1)
msgs.each do |msg|
next if msg.empty?
json = JSON.parse(msg)
next unless json["user"] # unless it is a tweet
puts "@#{json["user"]["screen_name"]}: #{json["text"]}"
if /にゃーん/ =~ json["text"]
args = { "status" => "@#{json["user"]["screen_name"]} にゃーん",
"in_reply_to_status_id" => json["id"].to_s }
rest.post(
"/1.1/statuses/update.json",
args.map { |k, v| "#{k}=#{CGI.escape(v)}" }.join("&"),
headers: { "authorization" => SimpleOAuth::Header.new(:post, "https://api.twitter.com/1.1/statuses/update.json", args, credentials).to_s,
"content-type" => "application/x-www-form-urlencoded" }
).join
end
end
}
}
}
rest.close
|