janis-ai 0.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.
Files changed (7) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +180 -0
  3. data/Rakefile +8 -0
  4. data/bin/janis +3 -0
  5. data/lib/janis.rb +121 -0
  6. data/test/test_janis.rb +6 -0
  7. metadata +58 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e04e6c4ecd67a77265012befba5150dc07fe1982
4
+ data.tar.gz: d2c490087a5eaeba9eaf58aec6da55f885280ce8
5
+ SHA512:
6
+ metadata.gz: 118faf0fa01509910b0666d63c21232ab9b85e311e63736c509e58e25b858d8c8db79cdc68d87445aa20a86e1964ad8f6fd679861001cff531bb162bef8daa0a
7
+ data.tar.gz: e583ec062aeab59b0c8a7d1bd2b4510a0ee118c59150c8516e3b378bcb2a5ba3bdae3a9299805dfc053e942184a357d73ad9624e3a96e58f4f4d7891b3203e11
@@ -0,0 +1,180 @@
1
+ # [janis](https://www.janis.ai) - SDK For Human + AI Conversational Experiences
2
+ ## For Bots Built in Ruby
3
+
4
+ Bots enable businesses to respond to customers immediately but they often fail to understand user intent. According to Facebook, bots fail 70% of the time. janis helps solve this problem with a toolkit to easily keep humans in the loop when AI fails your customers. The solution includes an SDK for bot developers to connect their bots to Slack, and a Slack app to get alerts, then pause and take over a bot.
5
+
6
+ ![Solution](https://cloud.githubusercontent.com/assets/7429980/22609969/491afe58-ea31-11e6-8928-27e1a1f1d6bd.png)
7
+
8
+
9
+
10
+ You can integrate janis in minutes and it begins working immediately, enabling you to deliver exceptional human + AI conversational experiences.
11
+ This module has been tested with Messenger, Slack, Skype, and Microsoft Webchat. Please see our [examples](./examples/).
12
+ It supports bot developers working in Node, Python and Ruby.
13
+
14
+ ### What you can do with janis:
15
+ You can view a full list of features at (https://www.janis.ai). It's core purpose can be explained with this single GIF
16
+
17
+ ![Takeover](https://cloud.githubusercontent.com/assets/7429980/22609935/22e39740-ea31-11e6-8286-e5a3ae545565.gif)
18
+
19
+ ### What you need to get started:
20
+ * [A Slack Account](http://www.slack.com)
21
+ * [janis for Slack](https://slack.com/oauth/authorize?scope=users:read,users:read.email,commands,chat:write:bot,chat:write:user,channels:read,channels:history,files:write:user,channels:write,bot&client_id=23850726983.39760486257)
22
+ * [A Chatbot built in Ruby](./examples/)
23
+
24
+ ##### Operational Dependencies:
25
+ 1. You'll need an API key from janis and for each Chatbot a Bot Token. You can get both of those (free) when you add janis to Slack and through a conversation with janis.
26
+ 2. If you're building a Messenger Chatbot, you'll need to setup a Facebook App, Facebook Page, get the Page Access Token from Facebook and link the Facebook App to the Facebook Page for janis to work.
27
+
28
+
29
+ ### Installation
30
+
31
+ ```bash
32
+ $ gem install janis
33
+ ```
34
+
35
+
36
+ ### Usage
37
+
38
+ Set your environmental variables for `JANIS_API_KEY`, `JANIS_CLIENT_KEY`, `ACCESS_TOKEN`.
39
+
40
+ ```bash
41
+ $ export JANIS_API_KEY=xxxxxxxxxxxxxxxxxxxx
42
+ $ export JANIS_CLIENT_KEY=xxxxxxxxxxxxxxxxxxxx
43
+ $ export ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
44
+ ```
45
+
46
+ Add the janis class to your code and set the required parameter values.
47
+ ```ruby
48
+ require 'janis'
49
+
50
+ # janis Api Key
51
+ janis.apikey = ENV['JANIS_API_KEY']
52
+ # Unique janis Client Key for your bot
53
+ janis.clientkey = ENV['JANIS_CLIENT_KEY']
54
+ # possible values: "messenger" or "slack"
55
+ janis.platform = "messenger"
56
+ # Page Access Token (only required for Messenger bots)
57
+ janis.token = ENV['ACCESS_TOKEN']
58
+ ```
59
+ ##### Incoming Message Schema:
60
+ Throughout this documentation, you will see references to `incomingMessage`. Depending on whether you have a Messenger or Slack bot, the schema will be different. The value of `incomingMessage` should be equal to the message you receive directly from either the Messenger webhook response, or from the Slack RTM event response.
61
+
62
+ ```python
63
+ # Example of a Slack Incoming Message
64
+ {
65
+ "type": "message",
66
+ "channel": "D024BE91L",
67
+ "user": "U2147483697",
68
+ "text": "Hello world",
69
+ "ts": "1355517523.000005"
70
+ }
71
+
72
+ # Example of a Messenger Incoming Message
73
+ {
74
+ "sender":{
75
+ "id":"USER_ID"
76
+ },
77
+ "recipient":{
78
+ "id":"PAGE_ID"
79
+ },
80
+ "timestamp":1458692752478,
81
+ "message":{
82
+ "mid":"mid.1457764197618:41d102a3e1ae206a38",
83
+ "seq":73,
84
+ "text":"hello, world!",
85
+ "quick_reply": {
86
+ "payload": "DEVELOPER_DEFINED_PAYLOAD"
87
+ }
88
+ }
89
+ }
90
+ ```
91
+
92
+ ##### Outgoing Message Schema:
93
+ Throughout this documentation, you will see references to `outgoingMessage`. Depending on whether you have a Messenger or Slack bot, the schema, as defined by each platform, will be different. Every time you track an outgoing message, the schema requirements match the respective platform.
94
+
95
+ ```python
96
+ # Example of Slack Outgoing Message
97
+ {
98
+ "channel": "C024BE91L",
99
+ "text": "Hello world"
100
+ }
101
+
102
+ # Exmaple of Messenger Outgoing Message
103
+ {
104
+ "recipient":{
105
+ "id":"USER_ID"
106
+ },
107
+ "message":{
108
+ "text":"hello, world!"
109
+ }
110
+ }
111
+ ```
112
+
113
+ ##### Tracking received messages:
114
+
115
+ When your bot receives an incoming message, you'll need to log the data with janis by calling to `janis.hopIn`.
116
+ __Note__: janis can pause your bot so that it doesn't auto response while a human has taken over. The server response from your `hopIn` request will pass the `paused` state. Use that to stop your bot from responding to an incoming message. Here is an example:
117
+
118
+ ```ruby
119
+ hopInResponse = janis.hopIn(incomingMessage)
120
+ if hopInResponse['paused'] != true
121
+ # proceed to process incoming message
122
+ ...
123
+ ```
124
+
125
+ ##### Tracking sent messages:
126
+
127
+ Each time your bot sends a message, make sure to log that with janis by calling to `janis.hopOut`. Here is an example of a function that we're calling `sendIt` that tracks an outgoing message and at the same time, has the bot say the message:
128
+ ```ruby
129
+ def sendIt(channel, text)
130
+ # schema matches Messenger
131
+ outgoingMessage = {recipient: {id: channel},message: {text: text}}
132
+ janis.hopOut(outgoingMessage)
133
+ client.say({'text': text, 'channel': channel}) # <= example of bot sending reply
134
+ ...
135
+ ```
136
+
137
+ ##### Log Unknown Intents:
138
+
139
+ Find the spot in your code your bot processes incoming messages it does not understand. Within that block of code, call to `janis.logUnkownIntent` to capture these conversational ‘dead-ends’. Here's an example:
140
+
141
+ ```ruby
142
+ # let the user know that the bot does not understand
143
+ sendIt(recipient_id, 'Huh?')
144
+ # capture conversational dead-ends.
145
+ janis.logUnknownIntent(incomingMessage)
146
+ ```
147
+ ##### Dial 0 to Speak With a Live Human Being:
148
+
149
+ janis can trigger alerts to suggest when a human should take over for your Chatbot. To enable this, create an intent such as when a customer explicitly requests live assistance, and then include the following lines of code where your bot listens for this intent:
150
+
151
+ ```ruby
152
+ # match an intent to talk to a real human
153
+ if text == 'help'
154
+ # let the user know that they are being routed to a human
155
+ sendIt(recipient_id, 'Hang tight. Let me see what I can do.')
156
+ # send a janis alert to your slack channel
157
+ # that the user could use assistance
158
+ janis.assistanceRequested(incomingMessage);
159
+ ```
160
+
161
+ ##### Human Take Over:
162
+
163
+ To enable the ability to have a human take over your bot, add the code below to subscribe to the 'chat response' event. Alternatively, if you'd prefer to use a webhook to receive the payload, please get in touch with us at support@janis.ai and we can enable that for you.
164
+
165
+ ```ruby
166
+ # Handle forwarding the messages sent by a human through your bot
167
+ janis.on :'chat response' do |data|
168
+ text = data['text']
169
+ channel = data['channel']
170
+ client.say({'text': text, 'channel': channel}) # <= example of bot sending message
171
+ end
172
+ ```
173
+
174
+ Go back to Slack and wait for alerts. That's it!
175
+ [Be sure to check out our examples.](./examples/)
176
+
177
+
178
+ ### Looking for something we don't yet support?
179
+ * [Join our mailing list and we'll notifiy you](https://www.janis.ai/contact.html)
180
+ * [Contact Support](mailto:support@janis.ai)
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'janis'
@@ -0,0 +1,121 @@
1
+ require 'rubygems'
2
+ require 'socket.io-client-simple'
3
+ require 'httparty'
4
+
5
+ module janis
6
+
7
+
8
+ class Partay
9
+ include HTTParty
10
+ base_uri 'https://janisapi.herokuapp.com/api/v1'
11
+ end
12
+
13
+ EVENTS = [:'chat response', :'socket_id_set', :'channel update'].freeze
14
+
15
+ class << self
16
+
17
+ attr_accessor :apikey, :clientkey, :token, :platform
18
+
19
+ def initialize
20
+ @apikey
21
+ @clientkey
22
+ @token
23
+ @platform
24
+ end
25
+
26
+ def new(*args, &block)
27
+ obj = allocate
28
+ obj.initialize(*args, &block)
29
+ obj
30
+ end
31
+
32
+ # Return a Hash of hooks.
33
+ def apikey
34
+ @apikey ||= ENV['JANIS_API_KEY']
35
+ end
36
+
37
+ def clientkey
38
+ @clientkey ||= ENV['JANIS_CLIENT_KEY']
39
+ end
40
+
41
+ def token
42
+ @token ||= ENV['ACCESS_TOKEN'] ||= ''
43
+ end
44
+
45
+ def platform
46
+ @platform ||= "messenger"
47
+ end
48
+
49
+ def headers
50
+ @headers = {'apikey':apikey,'clientkey':clientkey,'platform':platform, 'token': token}
51
+ end
52
+
53
+ def hooks
54
+ @hooks ||= {}
55
+ end
56
+
57
+ socket = SocketIO::Client::Simple.connect 'https://janis-socket-server.herokuapp.com'
58
+
59
+ socket.on :socket_id_set do |data|
60
+ socket_id = data
61
+ x = {'socket_id': socket_id, 'clientkey': JANIS_CLIENT_KEY}
62
+ options = {
63
+ body: x,
64
+ headers: headers
65
+ }
66
+ Partay.post('/update_bot_socket_id', options)
67
+ end
68
+
69
+ socket.on :'chat response' do |data|
70
+ channel = data['channel']
71
+ text = data['text']
72
+ messageData = {'recipient': {'id': channel},'message': {'text': text}}
73
+ janis.hopOut(messageData)
74
+ janis.trigger(:'chat response', messageData)
75
+ end
76
+
77
+ socket.on :'channel update' do |data|
78
+ janis.trigger(:'channel update', data)
79
+ end
80
+
81
+ def on(event, &block)
82
+ unless EVENTS.include? event
83
+ raise ArgumentError,
84
+ "#{event} is not a valid event; " \
85
+ "available events are #{EVENTS.join(',')}"
86
+ end
87
+ hooks[event] = block
88
+ end
89
+
90
+ def trigger(event, *args)
91
+ hooks.fetch(event).call(*args)
92
+ rescue KeyError
93
+ $stderr.puts "Ignoring #{event} (no hook registered)"
94
+ end
95
+
96
+ def hopIn(x)
97
+ puts 'hopIn'
98
+ options = {'body':x, 'headers':headers}
99
+ return Partay.post('/in', options)
100
+ end
101
+
102
+ def hopOut(x)
103
+ puts 'hopOut'
104
+ options = {'body':x, 'headers':headers}
105
+ return Partay.post('/out', options)
106
+ end
107
+
108
+ def logUnknownIntent(x)
109
+ puts 'logUnknownIntent'
110
+ options = {'body':x, 'headers':headers}
111
+ return Partay.post('/unknown', options)
112
+ end
113
+
114
+ def assistanceRequested(x)
115
+ puts 'assistanceRequested'
116
+ options = {'body':x, 'headers':headers}
117
+ return Partay.post('/human', options)
118
+ end
119
+ end
120
+ end
121
+
@@ -0,0 +1,6 @@
1
+ require 'test/unit'
2
+ require 'janis'
3
+
4
+ class janisTest < Test::Unit::TestCase
5
+
6
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: janis-ai
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Michael Nathanson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-04-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: "Chatbots allow you scale your customer communications through messaging,
14
+ \n \tautomating tasks and enabling transactions, but they can't empathize like
15
+ humans, reliably \n \tinterpret intent, or solve overly complex customer problems.
16
+ With janis, you can monitor your \n \tChatbot for friction in your conversational
17
+ experience, and fix problems in in real-time. \n \tSimply drop in a couple of lines
18
+ of code into your Chatbot and add janis to Slack. \n \tCollaborate with your Slack
19
+ team to identify bottlenecks and take over for your bot at just \n \tthe right
20
+ time to engage your users and produce business results. With our reports, you'll
21
+ gain \n \tactionable insights that help you train your bot, train your people,
22
+ and optimize your conversational experience."
23
+ email: nick@quaran.to
24
+ executables: []
25
+ extensions: []
26
+ extra_rdoc_files: []
27
+ files:
28
+ - README.md
29
+ - Rakefile
30
+ - bin/janis
31
+ - lib/janis.rb
32
+ - test/test_janis.rb
33
+ homepage: http://rubygems.org/gems/janis
34
+ licenses:
35
+ - MIT
36
+ metadata: {}
37
+ post_install_message:
38
+ rdoc_options: []
39
+ require_paths:
40
+ - lib
41
+ required_ruby_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ requirements: []
52
+ rubyforge_project:
53
+ rubygems_version: 2.5.1
54
+ signing_key:
55
+ specification_version: 3
56
+ summary: A toolkit for creating a hybrid Chatbot + Human UX
57
+ test_files:
58
+ - test/test_janis.rb