connfu-client 0.1
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/.rspec +3 -0
- data/.rvmrc +2 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +120 -0
- data/LICENSE.txt +661 -0
- data/README.rdoc +398 -0
- data/Rakefile +38 -0
- data/bin/.DS_Store +0 -0
- data/bin/connfu-client +94 -0
- data/connfu-client.gemspec +41 -0
- data/examples/conference/application.rb +68 -0
- data/examples/conference/conference.rb +33 -0
- data/examples/conference/conference_app.rb +25 -0
- data/examples/conference/connfu.log +5 -0
- data/examples/conference/wall.rb +11 -0
- data/examples/provisioning/app/get.rb +29 -0
- data/examples/provisioning/channels/get.rb +34 -0
- data/examples/provisioning/rss/create.rb +28 -0
- data/examples/provisioning/rss/delete.rb +27 -0
- data/examples/provisioning/rss/get.rb +32 -0
- data/examples/provisioning/rss/put.rb +29 -0
- data/examples/provisioning/setup.rb +2 -0
- data/examples/provisioning/twitter/create.rb +31 -0
- data/examples/provisioning/twitter/delete.rb +27 -0
- data/examples/provisioning/twitter/get.rb +32 -0
- data/examples/provisioning/twitter/put.rb +29 -0
- data/examples/provisioning/voice/create.rb +26 -0
- data/examples/provisioning/voice/delete.rb +27 -0
- data/examples/provisioning/voice/get.rb +36 -0
- data/examples/provisioning/voice/phones/create.rb +26 -0
- data/examples/provisioning/voice/phones/delete.rb +28 -0
- data/examples/provisioning/voice/phones/get.rb +38 -0
- data/examples/provisioning/voice/put.rb +38 -0
- data/examples/provisioning/voice/whitelist/create.rb +26 -0
- data/examples/provisioning/voice/whitelist/delete.rb +27 -0
- data/examples/provisioning/voice/whitelist/get.rb +36 -0
- data/examples/provisioning/voice/whitelist/put.rb +27 -0
- data/lib/connfu.rb +134 -0
- data/lib/connfu/cli/generator.rb +71 -0
- data/lib/connfu/connfu_logger.rb +88 -0
- data/lib/connfu/connfu_message_formatter.rb +134 -0
- data/lib/connfu/connfu_stream.rb +182 -0
- data/lib/connfu/dispatcher.rb +164 -0
- data/lib/connfu/dsl.rb +84 -0
- data/lib/connfu/events.rb +32 -0
- data/lib/connfu/listener.rb +85 -0
- data/lib/connfu/listener_channel.rb +100 -0
- data/lib/connfu/message.rb +74 -0
- data/lib/connfu/provisioning.rb +12 -0
- data/lib/connfu/provisioning/application.rb +374 -0
- data/lib/connfu/provisioning/base.rb +95 -0
- data/lib/connfu/provisioning/channel.rb +79 -0
- data/lib/connfu/provisioning/phone.rb +55 -0
- data/lib/connfu/provisioning/rss.rb +21 -0
- data/lib/connfu/provisioning/twitter.rb +28 -0
- data/lib/connfu/provisioning/voice.rb +89 -0
- data/lib/connfu/provisioning/whitelist.rb +62 -0
- data/lib/connfu/version.rb +6 -0
- data/lib/rdoc/generator/template/connfu/_context.rhtml +209 -0
- data/lib/rdoc/generator/template/connfu/_head.rhtml +7 -0
- data/lib/rdoc/generator/template/connfu/class.rhtml +38 -0
- data/lib/rdoc/generator/template/connfu/file.rhtml +36 -0
- data/lib/rdoc/generator/template/connfu/index.rhtml +13 -0
- data/lib/rdoc/generator/template/connfu/resources/apple-touch-icon.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/css/github.css +129 -0
- data/lib/rdoc/generator/template/connfu/resources/css/main.css +339 -0
- data/lib/rdoc/generator/template/connfu/resources/css/panel.css +389 -0
- data/lib/rdoc/generator/template/connfu/resources/css/reset.css +53 -0
- data/lib/rdoc/generator/template/connfu/resources/favicon.ico +0 -0
- data/lib/rdoc/generator/template/connfu/resources/i/arrows.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/i/results_bg.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/i/tree_bg.png +0 -0
- data/lib/rdoc/generator/template/connfu/resources/js/highlight.pack.js +1 -0
- data/lib/rdoc/generator/template/connfu/resources/js/jquery-1.3.2.min.js +19 -0
- data/lib/rdoc/generator/template/connfu/resources/js/jquery-effect.js +593 -0
- data/lib/rdoc/generator/template/connfu/resources/js/main.js +20 -0
- data/lib/rdoc/generator/template/connfu/resources/js/searchdoc.js +628 -0
- data/lib/rdoc/generator/template/connfu/resources/panel/index.html +72 -0
- data/lib/rdoc/generator/template/connfu/se_index.rhtml +8 -0
- data/spec/connfu_message_formatter_spec.rb +88 -0
- data/spec/connfu_spec.rb +51 -0
- data/spec/connfu_stream_spec.rb +84 -0
- data/spec/dispatcher_spec.rb +227 -0
- data/spec/dsl_spec.rb +159 -0
- data/spec/listener_channel_spec.rb +130 -0
- data/spec/listener_spec.rb +67 -0
- data/spec/provisioning/application_spec.rb +47 -0
- data/spec/provisioning/channel_shared_examples.rb +52 -0
- data/spec/provisioning/channel_spec.rb +13 -0
- data/spec/provisioning/phone_spec.rb +88 -0
- data/spec/provisioning/voice_spec.rb +138 -0
- data/spec/provisioning_spec.rb +500 -0
- data/spec/spec_helper.rb +51 -0
- metadata +298 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module Connfu
|
|
2
|
+
##
|
|
3
|
+
# This module helps a client to manage connFu applications
|
|
4
|
+
module Cli
|
|
5
|
+
module Generator
|
|
6
|
+
|
|
7
|
+
APPLICATION_TEMPLATE=<<END
|
|
8
|
+
|
|
9
|
+
require 'connfu'
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# This application is an example of how to create a connFu application
|
|
13
|
+
|
|
14
|
+
token = "YOUR-VALID-CONNFU-TOKEN"
|
|
15
|
+
|
|
16
|
+
Connfu.logger = STDOUT
|
|
17
|
+
Connfu.log_level = Logger::DEBUG
|
|
18
|
+
|
|
19
|
+
Connfu.application(token) {
|
|
20
|
+
|
|
21
|
+
listen(:voice) do |conference|
|
|
22
|
+
conference.on(:join) do |call|
|
|
23
|
+
puts "New inbound call from \#{call[:from]} on number \#{call[:to]}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
conference.on(:leave) do |call|
|
|
27
|
+
puts "\#{call[:from]} has left the conference \#{call[:channel_name]}"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
conference.on(:new_topic) do |topic|
|
|
31
|
+
puts "New topic in the conference \#{topic[:channel_name]}: \#{topic[:content]}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
listen(:twitter) do |twitter|
|
|
36
|
+
twitter.on(:new) do |tweet|
|
|
37
|
+
puts "\#{tweet[:channel_name]} just posted a new tweet in the conference room: \#{tweet.content}"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
listen(:sms) do |sms|
|
|
42
|
+
sms.on(:new) do |message|
|
|
43
|
+
puts "New inbound sms from \#{message[:from]}: \#{message[:content]}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
END
|
|
50
|
+
|
|
51
|
+
class << self
|
|
52
|
+
##
|
|
53
|
+
#
|
|
54
|
+
# ==== Parameters
|
|
55
|
+
# * **name** application name
|
|
56
|
+
# * **channels** channels the application should listen to
|
|
57
|
+
# * **file_name** main file that will hold the application logic
|
|
58
|
+
#
|
|
59
|
+
# ==== Return
|
|
60
|
+
def run(name, channels = nil, file_name = "application.rb")
|
|
61
|
+
Dir.mkdir(name)
|
|
62
|
+
Dir.chdir(name) do
|
|
63
|
+
File.open(file_name, 'w') do |f|
|
|
64
|
+
f.write(APPLICATION_TEMPLATE)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end # end:run
|
|
68
|
+
end # end class level
|
|
69
|
+
end # end module Generator
|
|
70
|
+
end # end module Cli
|
|
71
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'logger'
|
|
2
|
+
|
|
3
|
+
module Connfu
|
|
4
|
+
##
|
|
5
|
+
# This module defines a mixin to be used in any class that needs to log messages.
|
|
6
|
+
#
|
|
7
|
+
module ConnfuLogger
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Nice way to include the Module methods when including it in a class/module
|
|
11
|
+
#
|
|
12
|
+
# ==== Parameters
|
|
13
|
+
# * +base+ class that includes the mixin
|
|
14
|
+
def self.included(base)
|
|
15
|
+
base.extend(ClassMethods)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# This internal module acts as a wrapper to include the class/module level methods
|
|
20
|
+
module ClassMethods
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# logger setter
|
|
24
|
+
#
|
|
25
|
+
# ==== Parameters
|
|
26
|
+
# * +value+ should be:
|
|
27
|
+
# * a valid IO object (STDOUT, string representing a valid filename, File object)
|
|
28
|
+
# * a ::Logger instance
|
|
29
|
+
#
|
|
30
|
+
# ==== Return
|
|
31
|
+
# new ::Logger object created
|
|
32
|
+
def logger=(value)
|
|
33
|
+
# _logger must be static var and not class var to be shared between objects/classes
|
|
34
|
+
if value.is_a?(String) or value.is_a?(IO)
|
|
35
|
+
@@_logger = Logger.new(value)
|
|
36
|
+
else
|
|
37
|
+
@@_logger = value
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
##
|
|
42
|
+
# logger getter
|
|
43
|
+
#
|
|
44
|
+
# ==== Return
|
|
45
|
+
# ::Logger object
|
|
46
|
+
def logger
|
|
47
|
+
@@_logger ||= create_logger
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Change logger level
|
|
52
|
+
#
|
|
53
|
+
# ==== Parameters
|
|
54
|
+
# * +level+ valid Logger level constant (::Logger::DEBUG, etc)
|
|
55
|
+
def log_level=(level)
|
|
56
|
+
logger.level = level
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Creates a new Logger object and defines the level and format
|
|
61
|
+
#
|
|
62
|
+
# ==== Parameters
|
|
63
|
+
# * +output+ valid IO object
|
|
64
|
+
# ==== Return
|
|
65
|
+
# Logger object
|
|
66
|
+
def create_logger(output = nil)
|
|
67
|
+
output.nil? and output = STDOUT
|
|
68
|
+
logger = Logger.new(output)
|
|
69
|
+
logger.level = Logger::ERROR
|
|
70
|
+
#logger.formatter = proc { |severity, datetime, progname, msg|
|
|
71
|
+
# "#{severity} on #{datetime} at #{progname}: #{msg}\n"
|
|
72
|
+
#}
|
|
73
|
+
logger.datetime_format = "%Y-%m-%d %H:%M:%S"
|
|
74
|
+
logger
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# Instance method that wraps the class method
|
|
80
|
+
#
|
|
81
|
+
# ==== Return
|
|
82
|
+
# * see ClassMethods.logger
|
|
83
|
+
def logger
|
|
84
|
+
self.class.logger
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
require 'connfu/connfu_logger'
|
|
3
|
+
require 'connfu/message'
|
|
4
|
+
require 'uri'
|
|
5
|
+
|
|
6
|
+
module Connfu
|
|
7
|
+
|
|
8
|
+
##
|
|
9
|
+
# This class is in charge of formatting the incoming messages
|
|
10
|
+
# It's used by any connFu listener to format a raw message got from the streaming API to a
|
|
11
|
+
# Connfu::Message instance
|
|
12
|
+
#
|
|
13
|
+
class ConnfuMessageFormatter
|
|
14
|
+
include Connfu::ConnfuLogger # application logger
|
|
15
|
+
|
|
16
|
+
class << self
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# Convert an inbound twitter/RSS event to a Message instance.
|
|
20
|
+
#
|
|
21
|
+
# ==== Parameters
|
|
22
|
+
#
|
|
23
|
+
# * +message+ raw JSON decoded message
|
|
24
|
+
# ==== Return
|
|
25
|
+
# Array of Connfu::Message instances
|
|
26
|
+
def format_message(message)
|
|
27
|
+
message.is_a?(String) and message = ActiveSupport::JSON.decode(message)
|
|
28
|
+
values = []
|
|
29
|
+
|
|
30
|
+
# internal method that process the message
|
|
31
|
+
fetch_values = lambda { |msg|
|
|
32
|
+
begin
|
|
33
|
+
if msg.is_a?(Hash)
|
|
34
|
+
sender = msg["actor"]["id"]
|
|
35
|
+
recipients = nil
|
|
36
|
+
user_mentions = msg["object"]["entities"]["user_mentions"]
|
|
37
|
+
logger.debug(user_mentions)
|
|
38
|
+
if user_mentions.is_a?(Array) && user_mentions.length > 0
|
|
39
|
+
recipients = []
|
|
40
|
+
user_mentions.each { |recipient|
|
|
41
|
+
recipients << recipient
|
|
42
|
+
}
|
|
43
|
+
if recipients.length.eql?(1)
|
|
44
|
+
recipients = recipients[0]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
channel_info = msg["backchat"]["bare_uri"].split(":")
|
|
48
|
+
logger.debug(channel_info)
|
|
49
|
+
params = {
|
|
50
|
+
:id => msg["object"]["id"],
|
|
51
|
+
:content => msg["object"]["content"],
|
|
52
|
+
:message_type => "new",
|
|
53
|
+
:channel_type => channel_info[0],
|
|
54
|
+
:channel_name => channel_info[1][2..-2],
|
|
55
|
+
:from => sender,
|
|
56
|
+
:to => recipients
|
|
57
|
+
}
|
|
58
|
+
params
|
|
59
|
+
else
|
|
60
|
+
logger.error("Invalid message format: #{msg}")
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
63
|
+
rescue => ex
|
|
64
|
+
logger.error("Unable to fetch values from message #{msg}. Caught exception #{ex}")
|
|
65
|
+
nil
|
|
66
|
+
end
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if message.is_a?(Array)
|
|
70
|
+
message.each { |msg|
|
|
71
|
+
params = fetch_values.call(msg)
|
|
72
|
+
# include the message if valid params
|
|
73
|
+
params.nil? or values << Connfu::Message.new(params)
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
params = fetch_values.call(message)
|
|
77
|
+
# include the message if valid params
|
|
78
|
+
params.nil? or values << Connfu::Message.new(params)
|
|
79
|
+
end
|
|
80
|
+
values
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Convert the inbound voice/sms event to a Message instance
|
|
85
|
+
# ==== Parameters
|
|
86
|
+
# * +message+ raw JSON decoded message
|
|
87
|
+
#
|
|
88
|
+
# ==== Return
|
|
89
|
+
# * Array of one Connfu::Message instance
|
|
90
|
+
# * Empty array if the message is invalid
|
|
91
|
+
def format_voice_sms(message)
|
|
92
|
+
if message.is_a?(Array) and message.length.eql?(2)
|
|
93
|
+
if Connfu::Message.is_voice?(message[0])
|
|
94
|
+
logger.debug("Format the new voice message")
|
|
95
|
+
conference_id = URI.parse(message[1]["conferenceId"]).host
|
|
96
|
+
params = {
|
|
97
|
+
:id => 1234,
|
|
98
|
+
:content => message[1]["newTopic"],
|
|
99
|
+
:from => message[1]["from"],
|
|
100
|
+
:to => message[1]["to"],
|
|
101
|
+
:message_type => message[0],
|
|
102
|
+
:channel_type => "voice",
|
|
103
|
+
:channel_name => conference_id
|
|
104
|
+
}
|
|
105
|
+
logger.debug(params)
|
|
106
|
+
|
|
107
|
+
[Connfu::Message.new(params)]
|
|
108
|
+
elsif Connfu::Message.is_sms?(message[0])
|
|
109
|
+
logger.debug("Format the new sms message")
|
|
110
|
+
params = {
|
|
111
|
+
:id => 1234,
|
|
112
|
+
:content => message[1]["message"],
|
|
113
|
+
:from => message[1]["from"],
|
|
114
|
+
:to => message[1]["to"],
|
|
115
|
+
:message_type => "new",
|
|
116
|
+
:channel_type => "sms",
|
|
117
|
+
:channel_name => message[1]["appId"]
|
|
118
|
+
}
|
|
119
|
+
[Connfu::Message.new(params)]
|
|
120
|
+
else
|
|
121
|
+
logger.error("Unexpected message type")
|
|
122
|
+
logger.error(message)
|
|
123
|
+
[]
|
|
124
|
+
end
|
|
125
|
+
else
|
|
126
|
+
logger.error("Unexpected message format")
|
|
127
|
+
logger.error(message)
|
|
128
|
+
[]
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
require 'active_support'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'net/https'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'thread'
|
|
6
|
+
require 'connfu/connfu_logger'
|
|
7
|
+
require 'connfu/message'
|
|
8
|
+
require 'connfu/connfu_message_formatter'
|
|
9
|
+
|
|
10
|
+
module Connfu
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Open an HTTP connection to connFu and start listening to any incoming event
|
|
14
|
+
# This is the entry point to execute any proc in a connFu application
|
|
15
|
+
# based on external events.
|
|
16
|
+
class ConnfuStream
|
|
17
|
+
include Connfu::ConnfuLogger # application logger
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# ConnfuStream initializer.
|
|
21
|
+
# ==== Parameters
|
|
22
|
+
#
|
|
23
|
+
# * +app_stream+ valid HTTP stream url to connect and listen events
|
|
24
|
+
# * +api_key+ valid Token to get access to a Connfu Stream
|
|
25
|
+
# * +uri+ HTTP endpoint to open the connection
|
|
26
|
+
def initialize(app_stream, api_key, uri)
|
|
27
|
+
|
|
28
|
+
@app_stream = app_stream
|
|
29
|
+
@api_key = api_key
|
|
30
|
+
|
|
31
|
+
_uri = URI.parse(uri)
|
|
32
|
+
@port = _uri.port
|
|
33
|
+
@host = _uri.host
|
|
34
|
+
@path = _uri.path.concat(app_stream)
|
|
35
|
+
@scheme = _uri.scheme
|
|
36
|
+
|
|
37
|
+
@formatter = Connfu::ConnfuMessageFormatter
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Open a HTTP connection to connFu and start listening new events
|
|
42
|
+
def start_listening
|
|
43
|
+
|
|
44
|
+
begin
|
|
45
|
+
# http client instantiation and configuration
|
|
46
|
+
http_client = Net::HTTP.new(@host, @port)
|
|
47
|
+
logger.debug("#{self.class} opening connection to #{@host}:#{@port}")
|
|
48
|
+
http_client.use_ssl = @scheme.eql?("https")
|
|
49
|
+
if @scheme.eql?("https")
|
|
50
|
+
http_client.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
logger.debug("#{self.class} start listening to stream #{@path}")
|
|
54
|
+
|
|
55
|
+
http_client.read_timeout = 60*6 # double the timeout connFu is configured
|
|
56
|
+
|
|
57
|
+
# open connection
|
|
58
|
+
http_client.start do |http|
|
|
59
|
+
req = Net::HTTP::Get.new(
|
|
60
|
+
@path,
|
|
61
|
+
headers)
|
|
62
|
+
|
|
63
|
+
# send GET request
|
|
64
|
+
http.request(req) do |res|
|
|
65
|
+
logger.debug "#{self.class} Request to the endpoint...."
|
|
66
|
+
# read chunk data
|
|
67
|
+
logger.debug "#{self.class} Waiting for a new event...."
|
|
68
|
+
res.read_body do |chunk|
|
|
69
|
+
unless chunk.chomp.strip.empty?
|
|
70
|
+
# format data retrieved
|
|
71
|
+
events = handle_data(chunk)
|
|
72
|
+
# Insert message(s) in the queue
|
|
73
|
+
events.nil? or message(events)
|
|
74
|
+
else
|
|
75
|
+
logger.debug "#{self.class} got an empty data"
|
|
76
|
+
end
|
|
77
|
+
logger.debug "#{self.class} Waiting for a new event...."
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
rescue Exception => ex
|
|
82
|
+
logger.error "[#{Time.now} | #{ex.class}] #{ex.message}\n#{ex.backtrace.join("\n")}"
|
|
83
|
+
# loop again
|
|
84
|
+
start_listening
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
# This method should be called by the class that instantiates the ConnfuStream to fetch inbound events.
|
|
90
|
+
# It stops the execution waiting for an inbound event.
|
|
91
|
+
#
|
|
92
|
+
# ==== Return
|
|
93
|
+
# Connfu::Message instance
|
|
94
|
+
def get
|
|
95
|
+
queue.pop
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
private
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Internal Queue to send Message instances to the listener
|
|
102
|
+
#
|
|
103
|
+
# ==== Return
|
|
104
|
+
# Queue instance
|
|
105
|
+
def queue
|
|
106
|
+
@queue ||= Queue.new
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
##
|
|
110
|
+
# Process the data retrieved, formatting the raw data into one or more Connfu::Message instances
|
|
111
|
+
#
|
|
112
|
+
# ==== Parameters
|
|
113
|
+
# * +chunk+ data got from the HTTP stream
|
|
114
|
+
#
|
|
115
|
+
# ==== Return
|
|
116
|
+
# * Array of Connfu::Message instances
|
|
117
|
+
# * nil if invalid data
|
|
118
|
+
def handle_data(chunk)
|
|
119
|
+
if chunk.nil?
|
|
120
|
+
logger.info("Unable to process nil data")
|
|
121
|
+
return nil
|
|
122
|
+
end
|
|
123
|
+
logger.debug("raw data #{chunk}")
|
|
124
|
+
chunk = chunk.split("\n") # more than one event can be retrieved separated by '\n'
|
|
125
|
+
if chunk.is_a?(Array)
|
|
126
|
+
events = []
|
|
127
|
+
temp_events = []
|
|
128
|
+
chunk.each { |value|
|
|
129
|
+
json = ActiveSupport::JSON.decode(value)
|
|
130
|
+
if json
|
|
131
|
+
unless json.is_a?(Array) # Twitter - RSS message
|
|
132
|
+
unless json.nil?
|
|
133
|
+
logger.debug("#{self.class} Got a twitter message")
|
|
134
|
+
temp_events << @formatter.format_message(json)
|
|
135
|
+
temp_events.nil? or events << temp_events.flatten
|
|
136
|
+
else
|
|
137
|
+
logger.debug("#{self.class} Invalid data received")
|
|
138
|
+
events = nil
|
|
139
|
+
end
|
|
140
|
+
else # Voice - SMS message
|
|
141
|
+
logger.debug("#{self.class} Got a voice/sms message")
|
|
142
|
+
logger.debug(json)
|
|
143
|
+
temp_events = @formatter.format_voice_sms(json)
|
|
144
|
+
temp_events.nil? or events << temp_events.flatten
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
}
|
|
148
|
+
events.flatten
|
|
149
|
+
else
|
|
150
|
+
logger.info("#{self.class} Invalid data received #{chunk}")
|
|
151
|
+
nil
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
##
|
|
156
|
+
# Insert an array of messages in the queue
|
|
157
|
+
# ==== Parameters
|
|
158
|
+
# * +events+ array of incoming events
|
|
159
|
+
def message(events)
|
|
160
|
+
if events.is_a?(Array)
|
|
161
|
+
events.each { |msg|
|
|
162
|
+
if msg.is_a?(Connfu::Message)
|
|
163
|
+
logger.debug("#{self.class} Inserting message in the queue")
|
|
164
|
+
logger.debug msg.to_s
|
|
165
|
+
queue << msg
|
|
166
|
+
else
|
|
167
|
+
logger.info("Invalid message type #{msg.class}")
|
|
168
|
+
end
|
|
169
|
+
}
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
##
|
|
174
|
+
# Headers to send to authenticate
|
|
175
|
+
def headers
|
|
176
|
+
{"accept" => "application/json",
|
|
177
|
+
"authorization" => "Backchat #{@api_key}",
|
|
178
|
+
"Connection" => "Keep-Alive"}
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
end
|