hellostealth / stealth Goto Github PK
View Code? Open in Web Editor NEWAn open source Ruby framework for text and voice chatbots. ๐ค
Home Page: https://hellostealth.org
License: MIT License
An open source Ruby framework for text and voice chatbots. ๐ค
Home Page: https://hellostealth.org
License: MIT License
The bot should be able to send service-based replies. For example, if the bot is replying to a message via a state called hello
:
Facebook users would receive the reply in hello.yml+facebook.erb
Twilio SMS users would receive the reply in hello.yml+twilio.erb
Every other service would receive the reply in hello.yml.erb
Please, put a donation button on README. This project deserves donations!
Someone added a line to validate the content type of facebook request but that's failing because the content type is null, it's generating an exception.
code failing ->
Line 36 in 4f7f8e9
Hello my friends,
Anybody have a simple and practical example of catch all use with multiples levels?
Exist the possibility to get a rescued error in levels actions to customize messages?
Thanks :D
Once the the new models, flows and docs are done update the generators to reflect the most current state.
Things to verify:
boot.rb
Rakefile
db
folder and all associated filesThis may already be the case, but it needs to be tested.
Can we create our own service instead of facebook and twilio .?
Describe the bug
Generating a new flow adds a model file and a module that attempts to inherit (not allowed).
To Reproduce
Steps to reproduce the behavior:
stealth g flow <flow_name>
Expected behavior
The generator generates:
flow_map.rb
entry with only a single exampleDependabot can't evaluate your Ruby dependency files.
As a result, Dependabot couldn't check whether any of your dependencies are out-of-date.
The error Dependabot encountered was:
Bundler::Dsl::DSLError with message:
[!] There was an error parsing `Gemfile`:
[!] There was an error while loading `stealth.gemspec`: No such file or directory @ rb_sysopen - /home/dependabot/dependabot-updater/tmp/dependabot_20180921-6-1fq4h9t/VERSION. Bundler cannot continue.
# from /home/dependabot/dependabot-updater/tmp/dependabot_20180921-6-1fq4h9t/stealth.gemspec:3
# -------------------------------------------
#
> version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
#
# -------------------------------------------
. Bundler cannot continue.
# from /home/dependabot/dependabot-updater/tmp/dependabot_20180921-6-1fq4h9t/Gemfile:2
# -------------------------------------------
# source 'https://rubygems.org'
> gemspec
#
# -------------------------------------------
You can mention @dependabot in the comments below to contact the Dependabot team.
In Rails 5.x+, if migrations are pending, an error is raised and error page is shown in development.
Since we don't have an "error page" I was thinking we would just raise an error (when in development).
Is your feature request related to a problem? Please describe.
N/A
Describe the solution you'd like
I'm currently using stealth as a micro service. In my main app, a User has multiple Encounters with the bot I'm building. I'm currently using the Encounter's ID as the session id within Stealth. This was done for quite a few reasons.
I feel that 'current_session_id' would provide more flexibility over 'current_user_id' to refer to the id of the current session. Curious about your guys' thoughts on this.
Describe alternatives you've considered
Additional context
Is your feature request related to a problem? Please describe.
The backgrace showed when happens a error, are formatted like a array
Describe the solution you'd like
Can we join each line with a line break? is more readable.
https://github.com/hellostealth/stealth/blob/master/lib/stealth/controller/controller.rb#L66
How is it
[catch_all] ["/home/desenvolvimento/dev/riki/bot/controllers/hellos_controller.rb:5:in `say_hello'", "/home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:63:in `block in action'", "/home/desenvolvimento/.rvm/gems/ruby-2.5.1/gems/activesupport-5.2.0/lib/active_support/callbacks.rb:98:in `run_callbacks'", "/home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:61:in `action'", "/home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:118:in `step'", (...) ,"/home/desenvolvimento/.rvm/gems/ruby-2.5.1/gems/sidekiq-5.1.3/lib/sidekiq/processor.rb:73:in `run'", "/home/desenvolvimento/.rvm/gems/ruby-2.5.1/gems/sidekiq-5.1.3/lib/sidekiq/util.rb:16:in `watchdog'", "/home/desenvolvimento/.rvm/gems/ruby-2.5.1/gems/sidekiq-5.1.3/lib/sidekiq/util.rb:25:in `block in safe_thread'"]
14:40:05 sidekiq.1 | [catch_all] CatchAll level2 triggered for error-1540684789327149-hello-say_hello: undefined local variable or method `b' for #<HellosController:0x00007f6fb40086d0>
As for me, it would be more readable
[catch_all] /home/desenvolvimento/dev/riki/bot/controllers/hellos_controller.rb:5:in `say_hello'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:63:in `block in action'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:61:in `action'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:118:in `step'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/controller/controller.rb:96:in `step_to'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/bot/controllers/bot_controller.rb:12:in `route'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/dispatcher.rb:34:in `process'
14:42:19 sidekiq.1 | /home/desenvolvimento/dev/riki/vendor/gems/stealth/lib/stealth/services/jobs/handle_message_job.rb:17:in `perform'
(...)
14:27:40 sidekiq.1 | [catch_all] CatchAll level1 triggered for error-1540684789327149-hello-say_hello: undefined local variable or method `b' for #<HellosController:0x0000564c20188608>
Consider swapping out the Sinatra backend for https://github.com/ohler55/agoo.
Describe the bug
If an exception occurs in my hellosController, for instance, the message CatchAll level1 triggered for error
is showed, but leve1 action is never called. I investigate more deep and, for me, in lib/stealth/controller/catch_all.rb:16 CatchAllFlow
is not defined, and neve enter in if condition
.
To Reproduce
Steps to reproduce the behavior:
stealth new teste
1/0
class HellosController < BotController
def say_hello
1/0
send_replies
end
end
[catch_all] CatchAll level1 triggered for error-1540684789327149-hello-say_hello: divided by 0
Expected behavior
CatchAll->level1 action should be called?
Desktop (please complete the following information):
Additional context
The FlowMap generated
class FlowMap
include Stealth::Flow
flow :hello do
state :say_hello
end
flow :goodbye do
state :say_goodbye
end
flow :catch_all do
state :level1
end
end
Describe the bug
Running stealth generate flow <NAME>
generates wrong controller name . The name is not according to naming conventions. The name is generated in pluralised form but not in camel case.
To Reproduce
Steps to reproduce the behavior:
stealth generate flow camel_cased
Expected behavior
CamelCasedController < BotController
Current behaviour
camelCasedController < BotController
Additional Information
I am working on the issue, just wanted to inform about the bug which i came across while using the gem. Just awaiting for your response and I will be raising a PR once i get a response from your side .
Currently, step_to
and update_session_to
expect flows and states to specified as a string. However, the flow map expects them as symbols. Both should accept strings or symbols.
When a variant is named say_hello.yml+facebook.erb
it loads just fine. But say_hello.yml+facebook
is getting skipped.
Since we already require ActiveSupport
, the ideal implementation for this would mimic what is done by Rails via http://api.rubyonrails.org/classes/ActiveSupport/Reloader.html. That has the advantage of working on Mac, Linux, and Windows as well as only reloading files that have changed. I've looked at gems like shotgun
, but the Rails implementation of this seems to be the most robust.
Even though session keys are quite small, large scale bots might want these to be cleared out. If an expiration duration is specified, Stealth should purge sessions that are as old (or older) than the specified duration.
If a key is accessed, the TTL should be reset. This ensures active sessions are not purged.
Add an option for delay
reply types called dynamic
. It would look this within a reply:
- reply_type: text
text: "Hello World!"
- reply_type: delay
duration: dynamic
The calculated delay would be dynamic and based on the previous reply type and length. So for example, a short text like "Hello World!" would require a short delay of maybe 1 second. An image or a long paragraph would require a larger one.
A more power route system.
I not found a way to build several routes to evaluate content message and forward to specific flow/state. Like a Rails Routes or a Lita Chat Routes. Maybe this be a good idea to avoid many if's
in Controllers.
I Would like a config file to put my routes using regex
When message coming, try match with any route described in this file, and, if match, step_to the specific flow/state
.
Same like
Stealth.routes.draw do
match /^hello/, step_to: flow: 'hello', state: 'say_hello'
match /^bye/, step_to: flow: 'goodbye', state: 'say_goodbye'
end
How to write automatized tests to test my conversation flows?
Is your feature request related to a problem? Please describe.
would be extremely useful if we can pass to send_replies
method a specific yaml_reply
name in cases with expensive task or reuse a specific yaml_reply
, etc
Describe the solution you'd like
def say_meus_atendimentos
send_replies('wait_reply')
@data = Google.search('stealth chatbots')
send_replies
end
Or
def say_meus_atendimentos
@data = Google.search('stealth chatbots')
if @data
send_replies
else
send_replies('no_results')
end
end
and many others cases
In https://github.com/hellostealth/stealth/blob/master/lib/stealth/controller/replies.rb, something like this, maybe works.
(...)
def send_replies(yml_reply_file_name = nil)
yaml_reply, preprocessor = action_replies(yml_reply_file_name)
(...)
def action_replies(yml_reply_file_name=nil)
reply_dir = [*self._replies_path, replies_folder]
reply_filename = "#{yml_reply_file_name || current_session.state_string}.yml"
(...)
Describe the bug
Can not run stealth console in terminal.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expect after invoking stealth console in the terminal. I expect that a console prompt
for stealth will show.
Instead of a prompt, there is a stack trace that says that BotRecord is uninitialized.
However, there is a BotRecord file in the Bot/Models folder and my stealth generated flow named: Appointment Inherits from it.
Desktop (please complete the following information):
Additional context
Add any other context about the problem here.
Hello awesome Stealth Team, I'm using Stealth to make a chatbot to get information from a internal API.
How can I enable typing indicator before a slow task, send replies with results and after to disable typing indicator? Something like this:
class HellosController < BotController
def say_hello
# enable_typing_indicator
# Execute a expensive task
send_replies
# disable_typing_indicator
end
end
It's possible? make sense? another way?
A bot should be able to move a user into any state, thereby sending them out-of-context messages.
There is preliminary support for this, but it needs to be more polished.
activerecord
and railties
gems to Gemfile so the user can remove themDATABASE_URL
or database.yml
file should both detect the presence of ActiveRecord.there is bug in messageHandle job if message is empty then it gives error. if you take it as a bug then i will love to fix the issue
I think I found a load order issue for BotController
.
Take the following example: I have a controller named abouts_controller.rb
that looks like the following:
class AboutsController < BotController
def say_about_haven_life
send_replies
end
end
When I load the app I receive the following error:
12:45:18 web.1 | ! Unable to load application: NameError: uninitialized constant BotController
12:45:18 web.1 | bundler: failed to load command: puma (/Users/matthew/.rbenv/versions/2.4.1/bin/puma)
12:45:18 web.1 | NameError: uninitialized constant BotController
12:45:18 web.1 | /Users/matthew/Documents/Development/haven-chatbot/bot/controllers/abouts_controller.rb:1:in `<top (required)>'
However, when I rename the controller to contacts_controller.rb
it's able to find BotController
. Would this possibly be because AboutsController
starts with an A
and is loading before BotController
which starts with a B
?
https://github.com/brianmario/yajl-ruby claims to be ~4.5x faster when calling Yajl.load
.
Additionally, we should move this to stealth sessions:clear
A good idea would be a complete sample of chatbot using Stealth
Complete samples is a awesome way to start and learn fast.
Sample trivia, or weather reporter, or another.
PS: congratulations form this project this is fantastic, I'm very excited to use in my chatbot projects and help it grow.
It's possible that over a bot's lifecycle a state gets deleted from a flow. It's possible a past user may have previous session that still points to that state. If we simply delete the state, when the user re-engages the bot they will be sent to CatchAll.
Just like fails_to
, we should allow a state to specify a redirects_to
parameter. This allows the FlowMap to handle legacy states in a deliberate way.
Hello friends,
Exist any way to record all incoming and outgoing messages?
Example if I need store messages for analysis like a chatbase.com or botanalytics.co or to check if a message was read by user (I need store message before)
Thanks for help guys =)
Hello,
How does the integration API work? Details on how to write a custom integration is missing from the documentation. Currently the only way to write a custom driver seems to go through source code of existing integrations.
A guided example for getting started would be great!
Thanks.
The Gemfile
generated by stealth new <app>
hardcodes ruby version to be 2.5.1
, however, the gem itself doesn't specify 2.5.1
as the required_ruby_version
in the gemspec.
I was able to install the gem on 2.4.4p296
and then got the following error when running bundle install
:
Your Ruby version is 2.4.4, but your Gemfile specified 2.5.1
I have three suggestions to fix this:
Gemfile
required_ruby_version
in the gemspecGemfile
and set the ruby version dynamically when generating a new appWhat do you think?
These methods lead to brittle code and should be removed before GA.
When STEALTH_ENV
is set to production
, calling Stealth.env
still returns development
.
Describe the bug
I tried use before_action to handle messages in BotController.route
, but not work, I tried use in action of another Controller, and works. Why?
To Reproduce
class BotController < Stealth::Controller
helper :all
before_action :print_this, only: :route
def route
if current_session.present?
step_to session: current_session
else
step_to flow: 'hello', state: 'say_hello'
end
end
def print_this
puts "\n\n\n\n\n aaaaaaaaaaaaaaaaaaa \n\n\n\n"
end
end
Expected behavior
Show print_this
message in log
They're accessible in controllers, but not replies.
The stealth framework has support to referrals, payloads, attachments and normal messages. Have any chance to add a read
or another generic attribute in Stealth::ServiceMessage
to be possible to implement MessageReadsEvent
or another event?
Or maybe another strategy to solve this?
I implement this event in my fork, but I put the value in payload
attribute. :X
So, I can't send the pull request this feature!
Thanks =)
Dependabot can't evaluate your Ruby dependency files.
As a result, Dependabot couldn't check whether any of your dependencies are out-of-date.
The error Dependabot encountered was:
Bundler::Dsl::DSLError with message:
[!] There was an error parsing `Gemfile`:
[!] There was an error while loading `stealth.gemspec`: No such file or directory @ rb_sysopen - /home/dependabot/dependabot-updater/tmp/dependabot_20180921-6-ceoh69/VERSION. Bundler cannot continue.
# from /home/dependabot/dependabot-updater/tmp/dependabot_20180921-6-ceoh69/stealth.gemspec:3
# -------------------------------------------
#
> version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
#
# -------------------------------------------
. Bundler cannot continue.
# from /home/dependabot/dependabot-updater/tmp/dependabot_20180921-6-ceoh69/Gemfile:2
# -------------------------------------------
# source 'https://rubygems.org'
> gemspec
#
# -------------------------------------------
You can mention @dependabot in the comments below to contact the Dependabot team.
Currently step_to_in
expects to receive an ActiveSupport::Duration
as the delay. We should introduce step_to_at
which accepts a DateTime
.
Sidekiq and the generated environment.rb
file for a bot should support multiple Redis URLs for high availability environments. The URLs should be separated by commas like so:
REDIS_URL=redis://user:[email protected]:2341,redis://user:[email protected]:3491
Currently each .yml
reply is parsed through ERB. Only replies named .yml.erb
should run through the ERB processor.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.