wordhop 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.
- checksums.yaml +7 -0
- data/README.md +103 -0
- data/Rakefile +8 -0
- data/bin/wordhop +3 -0
- data/lib/wordhop.rb +117 -0
- data/test/test_wordhop.rb +6 -0
- metadata +58 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 87eb8237e9e3524b27c93961df3c70c0e3849ca7
|
4
|
+
data.tar.gz: c0a8cb15f9cf1c47139c2f706f9d8972c44b7187
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c446bc98b2ca88e108e099bc4ce551b3ce471f9dcb8d15dc8bb9d8e780cbadeb94dd10b1862128dd835a953b8dfbd6d84cabcbec7532c052a2e1dd9634d58e9e
|
7
|
+
data.tar.gz: ce950685d1bc65bde1464cbb9a01ebd40e993ff988206f80a3e89bf11618ef2ff5a14e6893612531cdabb8d24ba4bf7c76465d0dc0efd2210121f7ac6bad40d2
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# [Wordhop](https://www.wordhop.io) - Monitor and Optimize Your Conversational Experience
|
2
|
+
## For Chatbots Built in Python
|
3
|
+
|
4
|
+
With Wordhop you can sync up your Python-based Chatbot to Slack, so you can retain your users without ever leaving Slack. Wordhop monitors your Chatbot for friction in your conversational experience and alerts you on Slack in real-time. Simply add Wordhop to Slack and then drop in a couple of lines of code into your Chatbot. Wordhop integrates in minutes, not days, and begins working immediately. From Slack, you can pause and take over your bot, then hand the conversation back to your bot. Actionable analytics also show you and your Slack team where you can optimize your conversational experience and measure results.
|
5
|
+
|
6
|
+
### What you can do with Wordhop:
|
7
|
+
* [See Key Features](https://developer.wordhop.io)
|
8
|
+
* [Watch a Demo](https://www.youtube.com/watch?v=TAcwr3s9l4o)
|
9
|
+
|
10
|
+
### What you need to get started:
|
11
|
+
* [A Slack Account](http://www.slack.com)
|
12
|
+
* [Wordhop for Slack](https://slack.com/oauth/authorize?scope=users:read,users:read.email,commands,chat:write:bot,channels:read,channels:write,bot&client_id=23850726983.39760486257)
|
13
|
+
* [A Chatbot built in Ruby](https://github.com/hyperoslo/facebook-messenger)
|
14
|
+
|
15
|
+
### Installation
|
16
|
+
|
17
|
+
```bash
|
18
|
+
$ gem install facebook-messenger
|
19
|
+
```
|
20
|
+
|
21
|
+
|
22
|
+
### Usage
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
require 'wordhop'
|
26
|
+
|
27
|
+
# Wordhop Api Key
|
28
|
+
Wordhop.apikey = ENV['WORDHOP_API_KEY']
|
29
|
+
# Unique Wordhop Client Key for your bot
|
30
|
+
Wordhop.clientkey = ENV['WORDHOP_CLIENT_KEY']
|
31
|
+
# possible values: "messenger" or "slack"
|
32
|
+
Wordhop.platform = "messenger"
|
33
|
+
# Page Access Token (only required for Messenger bots)
|
34
|
+
Wordhop.token = ENV['ACCESS_TOKEN']
|
35
|
+
```
|
36
|
+
|
37
|
+
##### Tracking received messages:
|
38
|
+
|
39
|
+
When Messenger calls your receiving webhook, you'll need to log the data with Wordhop.
|
40
|
+
__Note__: Wordhop 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:
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
hopInResponse = Wordhop.hopIn(message.messaging)
|
44
|
+
if hopInResponse['paused'] != true
|
45
|
+
# proceed to process incoming message
|
46
|
+
...
|
47
|
+
```
|
48
|
+
|
49
|
+
##### Tracking sent messages:
|
50
|
+
|
51
|
+
Each time your bot sends a message, make sure to log that with Wordhop in the request's callback. Here is an example:
|
52
|
+
```ruby
|
53
|
+
def sendIt(message, data)
|
54
|
+
payload = {
|
55
|
+
recipient: message.sender,
|
56
|
+
message: data
|
57
|
+
}
|
58
|
+
message.reply(data)
|
59
|
+
Wordhop.hopOut(payload)
|
60
|
+
end
|
61
|
+
```
|
62
|
+
|
63
|
+
##### Human Take Over:
|
64
|
+
|
65
|
+
To enable the ability to have a human take over your bot, add the following code:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
# Handle forwarding the messages sent by a human through your bot
|
69
|
+
Wordhop.on :'chat response' do |data|
|
70
|
+
Bot.deliver(data, access_token: ENV['ACCESS_TOKEN']) # <= example of bot sending message
|
71
|
+
end
|
72
|
+
```
|
73
|
+
##### Log Unknown Intents:
|
74
|
+
|
75
|
+
Find the spot in your code your bot processes incoming messages it does not understand. You may have some outgoing fallback message there (i.e. "Oops I didn't get that!"). Within that block of code, call to `wordhop.logUnkownIntent` to capture these conversational ‘dead-ends’. Here's an example:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
# let the user know that the bot does not understand
|
79
|
+
sendIt(message, text: 'Huh?')
|
80
|
+
# capture conversational dead-ends.
|
81
|
+
Wordhop.logUnknownIntent(message.messaging)
|
82
|
+
```
|
83
|
+
##### Dial 0 to Speak With a Live Human Being:
|
84
|
+
|
85
|
+
Wordhop 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 line of code where your bot listens for this intent:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
# match an intent to talk to a real human
|
89
|
+
if text == 'help'
|
90
|
+
# let the user know that they are being routed to a human
|
91
|
+
sendIt(message, text: 'Hang tight. Let me see what I can do.')
|
92
|
+
# send a Wordhop alert to your slack channel
|
93
|
+
# that the user could use assistance
|
94
|
+
Wordhop.assistanceRequested(message.messaging)
|
95
|
+
```
|
96
|
+
|
97
|
+
Go back to Slack and wait for alerts. That's it!
|
98
|
+
[Be sure to check out our example.](examples/messenger/README.md)
|
99
|
+
|
100
|
+
|
101
|
+
### Looking for something we don't yet support?
|
102
|
+
* [Join our mailing list and we'll notifiy you](https://www.wordhop.io/contact.html)
|
103
|
+
* [Contact Support](mailto:support@wordhop.io)
|
data/Rakefile
ADDED
data/bin/wordhop
ADDED
data/lib/wordhop.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'socket.io-client-simple'
|
3
|
+
require 'httparty'
|
4
|
+
|
5
|
+
module Wordhop
|
6
|
+
|
7
|
+
|
8
|
+
class Partay
|
9
|
+
include HTTParty
|
10
|
+
base_uri 'https://wordhopapi.herokuapp.com/api/v1'
|
11
|
+
end
|
12
|
+
|
13
|
+
EVENTS = [:'chat response', :'socket_id_set'].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['WORDHOP_API_KEY']
|
35
|
+
end
|
36
|
+
|
37
|
+
def clientkey
|
38
|
+
@clientkey ||= ENV['WORDHOP_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://wordhop-socket-server.herokuapp.com'
|
58
|
+
|
59
|
+
socket.on :socket_id_set do |data|
|
60
|
+
socket_id = data
|
61
|
+
x = {'socket_id': socket_id, 'clientkey': WORDHOP_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
|
+
Wordhop.hopOut(messageData)
|
74
|
+
Wordhop.trigger(:'chat response', messageData)
|
75
|
+
end
|
76
|
+
|
77
|
+
def on(event, &block)
|
78
|
+
unless EVENTS.include? event
|
79
|
+
raise ArgumentError,
|
80
|
+
"#{event} is not a valid event; " \
|
81
|
+
"available events are #{EVENTS.join(',')}"
|
82
|
+
end
|
83
|
+
hooks[event] = block
|
84
|
+
end
|
85
|
+
|
86
|
+
def trigger(event, *args)
|
87
|
+
hooks.fetch(event).call(*args)
|
88
|
+
rescue KeyError
|
89
|
+
$stderr.puts "Ignoring #{event} (no hook registered)"
|
90
|
+
end
|
91
|
+
|
92
|
+
def hopIn(x)
|
93
|
+
puts 'hopIn'
|
94
|
+
options = {'body':x, 'headers':headers}
|
95
|
+
return Partay.post('/in', options)
|
96
|
+
end
|
97
|
+
|
98
|
+
def hopOut(x)
|
99
|
+
puts 'hopOut'
|
100
|
+
options = {'body':x, 'headers':headers}
|
101
|
+
return Partay.post('/out', options)
|
102
|
+
end
|
103
|
+
|
104
|
+
def logUnknownIntent(x)
|
105
|
+
puts 'logUnknownIntent'
|
106
|
+
options = {'body':x, 'headers':headers}
|
107
|
+
return Partay.post('/unknown', options)
|
108
|
+
end
|
109
|
+
|
110
|
+
def assistanceRequested(x)
|
111
|
+
puts 'assistanceRequested'
|
112
|
+
options = {'body':x, 'headers':headers}
|
113
|
+
return Partay.post('/human', options)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
metadata
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wordhop
|
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: 2016-12-08 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 Wordhop, 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 Wordhop to Slack. \n \tCollaborate with your
|
19
|
+
Slack team to identify bottlenecks and take over for your bot at just \n \tthe
|
20
|
+
right time to engage your users and produce business results. With our reports,
|
21
|
+
you'll 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/wordhop
|
31
|
+
- lib/wordhop.rb
|
32
|
+
- test/test_wordhop.rb
|
33
|
+
homepage: http://rubygems.org/gems/wordhop
|
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_wordhop.rb
|