janis-ai 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +180 -0
- data/Rakefile +8 -0
- data/bin/janis +3 -0
- data/lib/janis.rb +121 -0
- data/test/test_janis.rb +6 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -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
|
data/README.md
ADDED
@@ -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)
|
data/Rakefile
ADDED
data/bin/janis
ADDED
data/lib/janis.rb
ADDED
@@ -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
|
+
|
data/test/test_janis.rb
ADDED
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
|