chatroid 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +1 -1
- data/chatroid.gemspec +1 -0
- data/lib/chatroid/adapter/hip_chat.rb +131 -0
- data/lib/chatroid/adapter/twitter/event.rb +55 -0
- data/lib/chatroid/adapter/twitter.rb +5 -11
- data/lib/chatroid/adapter.rb +1 -0
- data/lib/chatroid/version.rb +1 -1
- data/spec/chatroid/adapter/hip_chat_spec.rb +66 -0
- data/spec/chatroid/adapter/twitter/event_spec.rb +97 -0
- data/spec/chatroid_spec.rb +4 -15
- metadata +25 -8
data/README.md
CHANGED
@@ -10,7 +10,7 @@ $ gem "chatroid"
|
|
10
10
|
## Example
|
11
11
|
You can create your own bot working in a chat service.
|
12
12
|
The following example creates a bot,
|
13
|
-
which responds to tweets
|
13
|
+
which responds to tweets including the word "yunotti" or any replies to it.
|
14
14
|
|
15
15
|
```ruby
|
16
16
|
require "chatroid"
|
data/chatroid.gemspec
CHANGED
@@ -0,0 +1,131 @@
|
|
1
|
+
require "avalon"
|
2
|
+
require "xmpp4r"
|
3
|
+
require "xmpp4r/muc/helper/simplemucclient"
|
4
|
+
require "logger"
|
5
|
+
|
6
|
+
class Chatroid
|
7
|
+
module Adapter
|
8
|
+
module HipChat
|
9
|
+
REQUIRED_CONFIG_KEYS = [
|
10
|
+
:jid,
|
11
|
+
:room,
|
12
|
+
:nick,
|
13
|
+
:password,
|
14
|
+
].freeze
|
15
|
+
|
16
|
+
EVENT_NAMES = [
|
17
|
+
:join,
|
18
|
+
:leave,
|
19
|
+
:message,
|
20
|
+
:private_message,
|
21
|
+
:room_message,
|
22
|
+
:self_leave,
|
23
|
+
:subject,
|
24
|
+
].freeze
|
25
|
+
|
26
|
+
def self.extended(chatroid)
|
27
|
+
REQUIRED_CONFIG_KEYS.each do |key|
|
28
|
+
Avalon.validate(chatroid.config[key], String)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def say(text)
|
33
|
+
room.say(text)
|
34
|
+
end
|
35
|
+
|
36
|
+
def invite(jid, reason = nil)
|
37
|
+
room.invite(jid => reason)
|
38
|
+
end
|
39
|
+
|
40
|
+
def kick(nick, reason = nil)
|
41
|
+
room.kick(nick, reason)
|
42
|
+
end
|
43
|
+
|
44
|
+
def ban(jid, reason = nil)
|
45
|
+
room.ban(jid, reason)
|
46
|
+
end
|
47
|
+
|
48
|
+
def unban(jid)
|
49
|
+
room.unban(jid)
|
50
|
+
end
|
51
|
+
|
52
|
+
def promote(nick)
|
53
|
+
room.prompt(nick)
|
54
|
+
end
|
55
|
+
|
56
|
+
def demote(nick)
|
57
|
+
room.demote(nick)
|
58
|
+
end
|
59
|
+
|
60
|
+
def join(jid, password = nil)
|
61
|
+
room.join(jid, password)
|
62
|
+
end
|
63
|
+
|
64
|
+
def exit(reason = nil)
|
65
|
+
room.exit(reason)
|
66
|
+
end
|
67
|
+
|
68
|
+
def subject=(text)
|
69
|
+
room.subject = text
|
70
|
+
end
|
71
|
+
|
72
|
+
def subject
|
73
|
+
room.subject
|
74
|
+
end
|
75
|
+
|
76
|
+
def nick
|
77
|
+
room.nick
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def connect
|
83
|
+
use_logger
|
84
|
+
bind_callbacks
|
85
|
+
join_room
|
86
|
+
persist
|
87
|
+
end
|
88
|
+
|
89
|
+
def persist
|
90
|
+
trap(:INT) { Kernel.exit }
|
91
|
+
loop { sleep 1 }
|
92
|
+
end
|
93
|
+
|
94
|
+
def client
|
95
|
+
@client ||= begin
|
96
|
+
jabber_client = Jabber::Client.new(config[:jid])
|
97
|
+
jabber_client.connect
|
98
|
+
jabber_client.auth(config[:password])
|
99
|
+
jabber_client
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def room
|
104
|
+
@room ||= Jabber::MUC::SimpleMUCClient.new(client)
|
105
|
+
end
|
106
|
+
|
107
|
+
def join_room
|
108
|
+
room.join(room_key)
|
109
|
+
end
|
110
|
+
|
111
|
+
def room_key
|
112
|
+
config[:room] + "/" + config[:nick]
|
113
|
+
end
|
114
|
+
|
115
|
+
def use_logger
|
116
|
+
if config[:logger]
|
117
|
+
Jabber.logger = config[:logger]
|
118
|
+
Jabber.debug = true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def bind_callbacks
|
123
|
+
EVENT_NAMES.each do |name|
|
124
|
+
room.__send__("on_#{name}") do |*args|
|
125
|
+
__send__("trigger_#{name}", *args)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
class Chatroid
|
4
|
+
module Adapter
|
5
|
+
module Twitter
|
6
|
+
class Event
|
7
|
+
TYPES = %w[
|
8
|
+
favorite
|
9
|
+
unfavorite
|
10
|
+
follow
|
11
|
+
unfollow
|
12
|
+
list_member_added
|
13
|
+
list_member_removed
|
14
|
+
list_user_subscribed
|
15
|
+
list_user_unsubscribed
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
attr_reader :params
|
19
|
+
|
20
|
+
def initialize(json, user_id)
|
21
|
+
@params = JSON.parse(json)
|
22
|
+
@user_id = user_id
|
23
|
+
end
|
24
|
+
|
25
|
+
def type
|
26
|
+
if has_event_type? && targeted_to_me?
|
27
|
+
@params["event"]
|
28
|
+
elsif reply_to_me?
|
29
|
+
"reply"
|
30
|
+
elsif tweet?
|
31
|
+
"tweet"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def targeted_to_me?
|
38
|
+
@params["target"] && @params["target"]["id"] == @user_id
|
39
|
+
end
|
40
|
+
|
41
|
+
def has_event_type?
|
42
|
+
@params["event"] && TYPES.include?(@params["event"])
|
43
|
+
end
|
44
|
+
|
45
|
+
def reply_to_me?
|
46
|
+
@params["in_reply_to_user_id"] && @params["in_reply_to_user_id"] == @user_id
|
47
|
+
end
|
48
|
+
|
49
|
+
def tweet?
|
50
|
+
@params["text"]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require "chatroid/adapter/twitter/event"
|
1
2
|
require "twitter/json_stream"
|
2
3
|
require "twitter_oauth"
|
3
4
|
require "json"
|
@@ -9,10 +10,7 @@ class Chatroid
|
|
9
10
|
|
10
11
|
def connect
|
11
12
|
EventMachine::run do
|
12
|
-
stream.each_item
|
13
|
-
event = JSON.parse(json)
|
14
|
-
on_each_event(event)
|
15
|
-
end
|
13
|
+
stream.each_item &method(:on_each_item)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
|
@@ -63,13 +61,9 @@ class Chatroid
|
|
63
61
|
@user_info ||= client.info
|
64
62
|
end
|
65
63
|
|
66
|
-
def
|
67
|
-
|
68
|
-
|
69
|
-
trigger_reply(event)
|
70
|
-
when event["text"]
|
71
|
-
trigger_tweet(event)
|
72
|
-
end
|
64
|
+
def on_each_item(json)
|
65
|
+
event = Event.new(json, user_info["id"])
|
66
|
+
send("trigger_#{event.type}", event.params)
|
73
67
|
end
|
74
68
|
end
|
75
69
|
end
|
data/lib/chatroid/adapter.rb
CHANGED
data/lib/chatroid/version.rb
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chatroid::Adapter::HipChat do
|
4
|
+
let(:chatroid) do
|
5
|
+
Chatroid.new do
|
6
|
+
set :service, "HipChat"
|
7
|
+
set :jid, "jid"
|
8
|
+
set :room, "room@example.com"
|
9
|
+
set :nick, "nick"
|
10
|
+
set :password, "password"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".extended" do
|
15
|
+
context "when chatroid has jid" do
|
16
|
+
it do
|
17
|
+
expect do
|
18
|
+
chatroid.extend(Chatroid::Adapter::HipChat)
|
19
|
+
end.to_not raise_error(Avalon::ValidationError)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when chatroid has no jid" do
|
24
|
+
before do
|
25
|
+
chatroid.config.delete(:jid)
|
26
|
+
end
|
27
|
+
|
28
|
+
it do
|
29
|
+
expect do
|
30
|
+
chatroid.extend(Chatroid::Adapter::HipChat)
|
31
|
+
end.to raise_error(Avalon::ValidationError)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#connect" do
|
37
|
+
before do
|
38
|
+
Jabber::Client.stub(:new).and_return(client)
|
39
|
+
Jabber::MUC::SimpleMUCClient.stub(:new).and_return(room)
|
40
|
+
chatroid.stub(:persist)
|
41
|
+
end
|
42
|
+
|
43
|
+
let(:client) do
|
44
|
+
mock.as_null_object
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:room) do
|
48
|
+
mock.as_null_object
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should call Jabber::Client#connect" do
|
52
|
+
client.should_receive(:connect)
|
53
|
+
chatroid.run!
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should call Jabber::Client#auth" do
|
57
|
+
client.should_receive(:auth)
|
58
|
+
chatroid.run!
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should call Jabber::MUC::SimpleMUCClient#join" do
|
62
|
+
room.should_receive(:join)
|
63
|
+
chatroid.run!
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Chatroid::Adapter::Twitter::Event do
|
4
|
+
describe "#type" do
|
5
|
+
subject do
|
6
|
+
Chatroid::Adapter::Twitter::Event.new(args.to_json, user_id).type
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:args) do
|
10
|
+
{}
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:user_id) do
|
14
|
+
1
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when favorited" do
|
18
|
+
let(:args) do
|
19
|
+
{ "event" => "favorite", "target" => { "id" => user_id } }
|
20
|
+
end
|
21
|
+
|
22
|
+
it do
|
23
|
+
should == "favorite"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when unfavorited" do
|
28
|
+
let(:args) do
|
29
|
+
{ "event" => "unfavorite", "target" => { "id" => user_id } }
|
30
|
+
end
|
31
|
+
|
32
|
+
it do
|
33
|
+
should == "unfavorite"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when user's list is subscribed" do
|
38
|
+
let(:args) do
|
39
|
+
{ "event" => "list_user_subscribed", "target" => { "id" => user_id } }
|
40
|
+
end
|
41
|
+
|
42
|
+
it do
|
43
|
+
should == "list_user_subscribed"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when user's list is unsubscribed" do
|
48
|
+
let(:args) do
|
49
|
+
{ "event" => "list_user_unsubscribed", "target" => { "id" => user_id } }
|
50
|
+
end
|
51
|
+
|
52
|
+
it do
|
53
|
+
should == "list_user_unsubscribed"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when user is added to list" do
|
58
|
+
let(:args) do
|
59
|
+
{ "event" => "list_member_added", "target" => { "id" => user_id } }
|
60
|
+
end
|
61
|
+
|
62
|
+
it do
|
63
|
+
should == "list_member_added"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when user is removed from list" do
|
68
|
+
let(:args) do
|
69
|
+
{ "event" => "list_member_removed", "target" => { "id" => user_id } }
|
70
|
+
end
|
71
|
+
|
72
|
+
it do
|
73
|
+
should == "list_member_removed"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when replied" do
|
78
|
+
let(:args) do
|
79
|
+
{ "in_reply_to_user_id" => user_id }
|
80
|
+
end
|
81
|
+
|
82
|
+
it do
|
83
|
+
should == "reply"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when tweeted" do
|
88
|
+
let(:args) do
|
89
|
+
{ "text" => "foo" }
|
90
|
+
end
|
91
|
+
|
92
|
+
it do
|
93
|
+
should == "tweet"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
data/spec/chatroid_spec.rb
CHANGED
@@ -41,23 +41,12 @@ describe Chatroid do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
context "when specified service is supported" do
|
44
|
-
|
45
|
-
|
46
|
-
def initialize(chatroid)
|
47
|
-
end
|
48
|
-
|
49
|
-
def connect
|
50
|
-
end
|
51
|
-
end.new(mock)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should find adapter and call #connect of it" do
|
44
|
+
it "should find adapter and call #connect extended from it" do
|
45
|
+
adapter = mock
|
55
46
|
chatroid = Chatroid.new
|
56
|
-
chatroid.stub(:
|
57
|
-
chatroid.stub(:has_adapter?).and_return(true)
|
58
|
-
chatroid.stub(:adapter_class)
|
59
|
-
chatroid.stub(:extend)
|
47
|
+
chatroid.stub(:validate_connection)
|
60
48
|
chatroid.stub(:adapter).and_return(adapter)
|
49
|
+
chatroid.should_receive(:extend).with(adapter)
|
61
50
|
chatroid.should_receive(:connect)
|
62
51
|
chatroid.run!
|
63
52
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: chatroid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: twitter-stream
|
16
|
-
requirement: &
|
16
|
+
requirement: &70201732417940 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70201732417940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: twitter_oauth
|
27
|
-
requirement: &
|
27
|
+
requirement: &70201732417360 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,21 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70201732417360
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: avalon
|
38
|
+
requirement: &70201732416700 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70201732416700
|
36
47
|
- !ruby/object:Gem::Dependency
|
37
48
|
name: rspec
|
38
|
-
requirement: &
|
49
|
+
requirement: &70201732416060 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
@@ -43,7 +54,7 @@ dependencies:
|
|
43
54
|
version: '0'
|
44
55
|
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *70201732416060
|
47
58
|
description: Chatroid is a gem for quickly creating chatterbot in Ruby
|
48
59
|
email:
|
49
60
|
- r7kamura@gmail.com
|
@@ -59,9 +70,13 @@ files:
|
|
59
70
|
- chatroid.gemspec
|
60
71
|
- lib/chatroid.rb
|
61
72
|
- lib/chatroid/adapter.rb
|
73
|
+
- lib/chatroid/adapter/hip_chat.rb
|
62
74
|
- lib/chatroid/adapter/twitter.rb
|
75
|
+
- lib/chatroid/adapter/twitter/event.rb
|
63
76
|
- lib/chatroid/callback.rb
|
64
77
|
- lib/chatroid/version.rb
|
78
|
+
- spec/chatroid/adapter/hip_chat_spec.rb
|
79
|
+
- spec/chatroid/adapter/twitter/event_spec.rb
|
65
80
|
- spec/chatroid/adapter/twitter_spec.rb
|
66
81
|
- spec/chatroid/adapter_spec.rb
|
67
82
|
- spec/chatroid/callback_spec.rb
|
@@ -92,6 +107,8 @@ signing_key:
|
|
92
107
|
specification_version: 3
|
93
108
|
summary: Chatterbot builder
|
94
109
|
test_files:
|
110
|
+
- spec/chatroid/adapter/hip_chat_spec.rb
|
111
|
+
- spec/chatroid/adapter/twitter/event_spec.rb
|
95
112
|
- spec/chatroid/adapter/twitter_spec.rb
|
96
113
|
- spec/chatroid/adapter_spec.rb
|
97
114
|
- spec/chatroid/callback_spec.rb
|