bobot 1.0.53 → 2.1.0

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +18 -8
  3. data/app/controllers/bobot/webhook_controller.rb +54 -30
  4. data/config/routes.rb +1 -2
  5. data/lib/bobot.rb +15 -1
  6. data/lib/bobot/commander.rb +9 -8
  7. data/lib/bobot/configuration.rb +149 -186
  8. data/lib/bobot/engine.rb +0 -4
  9. data/lib/bobot/events/common.rb +4 -4
  10. data/lib/bobot/events/delivery.rb +0 -1
  11. data/lib/bobot/events/message.rb +4 -0
  12. data/lib/bobot/events/message_echo.rb +3 -2
  13. data/lib/bobot/events/message_request.rb +9 -0
  14. data/lib/bobot/graph_facebook.rb +4 -4
  15. data/lib/bobot/profile.rb +2 -6
  16. data/lib/bobot/version.rb +3 -3
  17. data/lib/generators/bobot/templates/app/bobot/workflow.rb +9 -11
  18. data/lib/generators/bobot/templates/config/bobot.yml +41 -32
  19. data/lib/generators/bobot/templates/config/initializers/bobot.rb +25 -9
  20. data/lib/generators/bobot/templates/config/locales/bobot.en.yml +29 -28
  21. data/lib/generators/bobot/templates/config/locales/bobot.fr.yml +28 -27
  22. data/lib/generators/bobot/utils.rb +0 -9
  23. data/spec/bobot/bobot_spec.rb +18 -12
  24. data/spec/bobot/event/common_spec.rb +3 -1
  25. data/spec/bobot/event/message_spec.rb +7 -0
  26. data/spec/bobot/profile_spec.rb +3 -1
  27. data/spec/bobot/subscription_spec.rb +4 -2
  28. data/spec/bobot/user_spec.rb +4 -2
  29. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  30. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  31. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  32. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  33. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  34. data/spec/dummy/bin/setup +0 -8
  35. data/spec/dummy/bin/update +0 -3
  36. data/spec/dummy/config/application.rb +3 -2
  37. data/spec/dummy/config/cable.yml +10 -0
  38. data/spec/dummy/config/environments/development.rb +5 -3
  39. data/spec/dummy/config/environments/production.rb +5 -3
  40. data/spec/dummy/config/environments/test.rb +6 -2
  41. data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -4
  42. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -5
  43. data/spec/dummy/config/routes.rb +1 -1
  44. data/spec/dummy/config/secrets.yml +2 -2
  45. data/spec/dummy/log/development.log +0 -0
  46. data/spec/dummy/log/test.log +2 -0
  47. data/spec/dummy/tmp/generator/app/bobot/workflow.rb +15 -0
  48. data/spec/dummy/tmp/generator/config/bobot.yml +48 -0
  49. data/spec/dummy/tmp/generator/config/initializers/bobot.rb +46 -0
  50. data/spec/dummy/tmp/generator/config/locales/bobot.en.yml +31 -0
  51. data/spec/dummy/tmp/generator/config/locales/bobot.fr.yml +30 -0
  52. data/spec/dummy/tmp/generator/config/routes.rb +0 -0
  53. data/spec/rails_helper.rb +8 -10
  54. metadata +43 -34
  55. data/app/mailers/bobot/application_mailer.rb +0 -6
  56. data/app/models/bobot/application_record.rb +0 -5
  57. data/lib/generators/bobot/templates/app/bobot/message.rb +0 -3
  58. data/lib/generators/bobot/templates/app/bobot/postback.rb +0 -22
  59. data/spec/dummy/app/bobot/workflow.rb +0 -17
  60. data/spec/dummy/app/models/application_record.rb +0 -3
  61. data/spec/dummy/config/bobot.yml +0 -27
  62. data/spec/dummy/config/database.yml +0 -19
  63. data/spec/dummy/config/initializers/bobot.rb +0 -30
  64. data/spec/dummy/config/locales/bobot.en.yml +0 -28
  65. data/spec/dummy/config/locales/bobot.fr.yml +0 -27
  66. data/spec/dummy/db/schema.rb +0 -15
@@ -37,7 +37,9 @@ RSpec.describe Bobot::Dummy do
37
37
  let(:access_token) { 'access_token' }
38
38
 
39
39
  before do
40
- Bobot.page_access_token = access_token
40
+ Bobot.config.pages << Bobot::Configuration::Page.new(
41
+ page_access_token: access_token,
42
+ )
41
43
  end
42
44
 
43
45
  subject { described_class.new(payload) }
@@ -248,11 +248,18 @@ RSpec.describe Bobot::Event::Message do
248
248
  )
249
249
  end
250
250
  end
251
+
251
252
  describe '.app_id' do
252
253
  it 'returns the app_id from which the message was sent' do
253
254
  expect(subject.app_id).to eq(payload['message']['app_id'])
254
255
  end
255
256
  end
257
+
258
+ describe '.nlp' do
259
+ it 'returns the nlp from which the message was sent' do
260
+ expect(subject.nlp).to eq(payload['message']['nlp'])
261
+ end
262
+ end
256
263
 
257
264
  describe '.quick_reply' do
258
265
  context 'when a quick reply was used' do
@@ -13,7 +13,9 @@ RSpec.describe Bobot::Profile do
13
13
  end
14
14
 
15
15
  before do
16
- Bobot.page_access_token = access_token
16
+ Bobot.config.pages << Bobot::Configuration::Page.new(
17
+ page_access_token: access_token,
18
+ )
17
19
  end
18
20
 
19
21
  describe '.set' do
@@ -15,8 +15,10 @@ RSpec.describe Bobot::Subscription do
15
15
  end
16
16
 
17
17
  before do
18
- Bobot.page_access_token = access_token
19
- Bobot.page_id = page_id
18
+ Bobot.config.pages << Bobot::Configuration::Page.new(
19
+ page_access_token: access_token,
20
+ page_id: page_id,
21
+ )
20
22
  end
21
23
 
22
24
  describe '.set' do
@@ -16,8 +16,10 @@ RSpec.describe Bobot::User do
16
16
  end
17
17
 
18
18
  before do
19
- Bobot.page_access_token = access_token
20
- Bobot.page_id = page_id
19
+ Bobot.config.pages << Bobot::Configuration::Page.new(
20
+ page_access_token: access_token,
21
+ page_id: page_id,
22
+ )
21
23
  end
22
24
 
23
25
  describe '.get_profile' do
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Connection < ActionCable::Connection::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ class ApplicationMailer < ActionMailer::Base
2
+ default from: 'from@example.com'
3
+ layout 'mailer'
4
+ end
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <style>
6
+ /* Email styles need to be inline */
7
+ </style>
8
+ </head>
9
+
10
+ <body>
11
+ <%= yield %>
12
+ </body>
13
+ </html>
@@ -0,0 +1 @@
1
+ <%= yield %>
@@ -19,14 +19,6 @@ chdir APP_ROOT do
19
19
  system('bundle check') || system!('bundle install')
20
20
 
21
21
 
22
- # puts "\n== Copying sample files =="
23
- # unless File.exist?('config/database.yml')
24
- # cp 'config/database.yml.sample', 'config/database.yml'
25
- # end
26
-
27
- puts "\n== Preparing database =="
28
- system! 'bin/rails db:setup'
29
-
30
22
  puts "\n== Removing old logs and tempfiles =="
31
23
  system! 'bin/rails log:clear tmp:clear'
32
24
 
@@ -18,9 +18,6 @@ chdir APP_ROOT do
18
18
  system! 'gem install bundler --conservative'
19
19
  system('bundle check') || system!('bundle install')
20
20
 
21
- puts "\n== Updating database =="
22
- system! 'bin/rails db:migrate'
23
-
24
21
  puts "\n== Removing old logs and tempfiles =="
25
22
  system! 'bin/rails log:clear tmp:clear'
26
23
 
@@ -1,10 +1,10 @@
1
1
  require_relative 'boot'
2
2
 
3
3
  # Pick the frameworks you want:
4
- require "active_record/railtie"
4
+ # require "active_record/railtie"
5
5
  require "action_controller/railtie"
6
6
  require "action_view/railtie"
7
- # require "action_mailer/railtie"
7
+ require "action_mailer/railtie"
8
8
  require "active_job/railtie"
9
9
  # require "action_cable/engine"
10
10
  # require "rails/test_unit/railtie"
@@ -28,3 +28,4 @@ module Dummy
28
28
  config.api_only = true
29
29
  end
30
30
  end
31
+
@@ -0,0 +1,10 @@
1
+ development:
2
+ adapter: async
3
+
4
+ test:
5
+ adapter: async
6
+
7
+ production:
8
+ adapter: redis
9
+ url: redis://localhost:6379/1
10
+ channel_prefix: dummy_production
@@ -26,12 +26,14 @@ Rails.application.configure do
26
26
  config.cache_store = :null_store
27
27
  end
28
28
 
29
+ # Don't care if the mailer can't send.
30
+ config.action_mailer.raise_delivery_errors = false
31
+
32
+ config.action_mailer.perform_caching = false
33
+
29
34
  # Print deprecation notices to the Rails logger.
30
35
  config.active_support.deprecation = :log
31
36
 
32
- # Raise an error on page load if there are pending migrations.
33
- config.active_record.migration_error = :page_load
34
-
35
37
 
36
38
  # Raises error for missing translations
37
39
  # config.action_view.raise_on_missing_translations = true
@@ -52,6 +52,11 @@ Rails.application.configure do
52
52
  # Use a real queuing backend for Active Job (and separate queues per environment)
53
53
  # config.active_job.queue_adapter = :resque
54
54
  # config.active_job.queue_name_prefix = "dummy_#{Rails.env}"
55
+ config.action_mailer.perform_caching = false
56
+
57
+ # Ignore bad email addresses and do not raise email delivery errors.
58
+ # Set this to true and configure the email server for immediate delivery to raise delivery errors.
59
+ # config.action_mailer.raise_delivery_errors = false
55
60
 
56
61
  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
57
62
  # the I18n.default_locale when a translation cannot be found).
@@ -72,7 +77,4 @@ Rails.application.configure do
72
77
  logger.formatter = config.log_formatter
73
78
  config.logger = ActiveSupport::TaggedLogging.new(logger)
74
79
  end
75
-
76
- # Do not dump schema after migrations.
77
- config.active_record.dump_schema_after_migration = false
78
80
  end
@@ -27,12 +27,16 @@ Rails.application.configure do
27
27
 
28
28
  # Disable request forgery protection in test environment.
29
29
  config.action_controller.allow_forgery_protection = false
30
+ config.action_mailer.perform_caching = false
31
+
32
+ # Tell Action Mailer not to deliver emails to the real world.
33
+ # The :test delivery method accumulates sent emails in the
34
+ # ActionMailer::Base.deliveries array.
35
+ config.action_mailer.delivery_method = :test
30
36
 
31
37
  # Print deprecation notices to the stderr.
32
38
  config.active_support.deprecation = :stderr
33
39
 
34
40
  # Raises error for missing translations
35
41
  # config.action_view.raise_on_missing_translations = true
36
-
37
- config.active_job.queue_adapter = :test
38
42
  end
@@ -1,6 +1,8 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- # ApplicationController.renderer.defaults.merge!(
4
- # http_host: 'example.org',
5
- # https: false
6
- # )
3
+ # ActiveSupport::Reloader.to_prepare do
4
+ # ApplicationController.renderer.defaults.merge!(
5
+ # http_host: 'example.org',
6
+ # https: false
7
+ # )
8
+ # end
@@ -7,8 +7,3 @@
7
7
  ActiveSupport.on_load(:action_controller) do
8
8
  wrap_parameters format: [:json]
9
9
  end
10
-
11
- # To enable root element in JSON for ActiveRecord objects.
12
- # ActiveSupport.on_load(:active_record) do
13
- # self.include_root_in_json = true
14
- # end
@@ -1,3 +1,3 @@
1
1
  Rails.application.routes.draw do
2
- mount Bobot::Engine => '/bobot', as: 'bobot'
2
+ mount Bobot::Engine => "/bobot", as: "bobot"
3
3
  end
@@ -18,10 +18,10 @@
18
18
  # Environmental secrets are only available for that specific environment.
19
19
 
20
20
  development:
21
- secret_key_base: 4bacd5b4c06821a6d4ede98c4580cb3107a5b0da461805673af89b4bdbffa32ccbf6cf28af193a6084e7a7fa2d20e9a72ced26d1562ef8683382cac3e4de9bd5
21
+ secret_key_base: f4f2ac74911f4d6de200718f3c152e218936381f52e7ec705d2b644307c7e9e26fd1acc729cb0e67f1fc371aec3b053dd8cba1b02c2cf036c783f5e7b95d6685
22
22
 
23
23
  test:
24
- secret_key_base: 5b1c674644a5f68b2e25bfee83235783496908ef0344dc80d2f523a3632bede3e9d5cda162f5aaef120f8ad12f7a250e320daf46216eaa261ded978f24ca952e
24
+ secret_key_base: e6a624b1245f7ece0682019b0d33da8cb7055c7e22ef6358e943fcc0bb502ab9f12d722ca413058c3fed6e71e1057fbc91daaec3c94843691ee20a8302a64654
25
25
 
26
26
  # Do not keep production secrets in the unencrypted secrets file.
27
27
  # Instead, either read values from the environment.
File without changes
@@ -0,0 +1,2 @@
1
+ [ActiveJob] Enqueued Bobot::CommanderJob (Job ID: 8a80c687-421f-4bd4-8bba-a022b265e12f) to Test(default) with arguments: {"sender"=>{"id"=>"2"}, "recipient"=>{"id"=>"3"}, "timestamp"=>1457764197627, "message"=>{"mid"=>"mid.1457764197618:41d102a3e1ae206a38", "seq"=>73, "text"=>"Hello, bot!"}}
2
+ [ActiveJob] Enqueued Bobot::CommanderJob (Job ID: e295aa69-c9c8-4900-8409-e43a19b6a500) to Test(default) with arguments: {"sender"=>{"id"=>"2"}, "recipient"=>{"id"=>"3"}, "timestamp"=>1457764197627, "message"=>{"mid"=>"mid.1457764197618:41d102a3e1ae206a38", "seq"=>73, "text"=>"Hello, bot!"}}
@@ -0,0 +1,15 @@
1
+ # message received or quick replies
2
+ Bobot::Commander.on :message do |message|
3
+ end
4
+
5
+ # get started and click on any buttons
6
+ Bobot::Commander.on :postback do |postback|
7
+ end
8
+
9
+ # referral by m.me/XXX?ref=
10
+ Bobot::Commander.on :referral do |referral|
11
+ end
12
+
13
+ # referral by param ref into send to messenger plugin
14
+ Bobot::Commander.on :optin do |optin|
15
+ end
@@ -0,0 +1,48 @@
1
+ development:
2
+ app_id: "123"
3
+ app_secret: "456"
4
+ verify_token: "your token"
5
+ domains: "whitelisted-domain.com,second-whitelisted-domain.com"
6
+ debug_log: true
7
+ async: false
8
+ pages:
9
+ - slug: "facebook_1"
10
+ language: "fr"
11
+ page_id: "789"
12
+ page_access_token: "abc"
13
+
14
+ test:
15
+ app_id: "123"
16
+ app_secret: "456"
17
+ verify_token: "your token"
18
+ domains: "whitelisted-domain.com,second-whitelisted-domain.com"
19
+ debug_log: true
20
+ async: false
21
+ pages:
22
+ - slug: "facebook_1"
23
+ page_id: "789"
24
+ page_access_token: "abc"
25
+
26
+ staging:
27
+ app_id: <%= ENV["STAGING_BOBOT_APP_ID"] %>
28
+ app_secret: <%= ENV["STAGING_BOBOT_APP_SECRET"] %>
29
+ verify_token: <%= ENV["STAGING_BOBOT_VERIFY_TOKEN"] %>
30
+ domains: <%= ENV["STAGING_BOBOT_DOMAINS"] %>
31
+ debug_log: <%= ENV["STAGING_BOBOT_DEBUG_LOG"] %>
32
+ async: <%= ENV["STAGING_BOBOT_ASYNC"] %>
33
+ pages:
34
+ - slug: <%= ENV["STAGING_BOBOT_PAGE_SLUG"] %>
35
+ page_id: <%= ENV["STAGING_BOBOT_PAGE_ID"] %>
36
+ page_access_token: <%= ENV["STAGING_BOBOT_PAGE_ACCESS_TOKEN"] %>
37
+
38
+ production:
39
+ app_id: <%= ENV["PRODUCTION_BOBOT_APP_ID"] %>
40
+ app_secret: <%= ENV["PRODUCTION_BOBOT_APP_SECRET"] %>
41
+ verify_token: <%= ENV["PRODUCTION_BOBOT_VERIFY_TOKEN"] %>
42
+ domains: <%= ENV["PRODUCTION_BOBOT_DOMAINS"] %>
43
+ debug_log: <%= ENV["PRODUCTION_BOBOT_DEBUG_LOG"] %>
44
+ async: <%= ENV["PRODUCTION_BOBOT_ASYNC"] %>
45
+ pages:
46
+ - slug: <%= ENV["PRODUCTION_BOBOT_PAGE_SLUG"] %>
47
+ page_id: <%= ENV["PRODUCTION_BOBOT_PAGE_ID"] %>
48
+ page_access_token: <%= ENV["PRODUCTION_BOBOT_PAGE_ACCESS_TOKEN"] %>
@@ -0,0 +1,46 @@
1
+ bobot_config_path = Rails.root.join("config", "bobot.yml")
2
+ bobot_config = YAML.safe_load(ERB.new(File.read(bobot_config_path)).result, [], [], true)[Rails.env]
3
+
4
+ if bobot_config.present?
5
+ unless bobot_config.key?("pages")
6
+ raise "Bobot: #{bobot_config_path} required an array key :pages (cf. https://github.com/navidemad/bobot)"
7
+ end
8
+ Bobot.configure do |config|
9
+ config.app_id = bobot_config["app_id"],
10
+ config.app_secret = bobot_config["app_secret"],
11
+ config.verify_token = bobot_config["verify_token"],
12
+ config.domains = bobot_config["domains"],
13
+ config.debug_log = bobot_config["debug_log"],
14
+ config.async = bobot_config["async"],
15
+ bobot_config["pages"].each do |page|
16
+ config.pages << Bobot::Configuration::Page.new(
17
+ name: page["name"],
18
+ language: page["language"],
19
+ page_access_token: page["page_access_token"],
20
+ page_id: page["page_id"],
21
+ )
22
+ end
23
+ end
24
+ else
25
+ warn "#{bobot_config_path} not configured yet in #{Rails.env} environment."
26
+ end
27
+
28
+ unless Rails.env.production?
29
+ bot_files = Dir[Rails.root.join("app", "bobot", "**", "*.rb")]
30
+ bot_reloader = ActiveSupport::FileUpdateChecker.new(bot_files) do
31
+ bot_files.each { |file| require_dependency file }
32
+ end
33
+
34
+ ActiveSupport::Reloader.to_prepare do
35
+ bot_reloader.execute_if_updated
36
+ end
37
+
38
+ bot_files.each { |file| require_dependency file }
39
+ end
40
+
41
+ if defined?(Rails::Server)
42
+ Rails.application.config.after_initialize do
43
+ Rails.application.config.paths.add File.join("app", "bobot"), glob: File.join("**", "*.rb")
44
+ Rails.application.config.autoload_paths += Dir[Rails.root.join("app", "bobot", "*")]
45
+ end
46
+ end
@@ -0,0 +1,31 @@
1
+ en:
2
+ bobot:
3
+ facebook_1:
4
+ config:
5
+ facebook_locales:
6
+ - "en_US"
7
+ - "en_UD"
8
+ - "en_GB"
9
+ greeting_text: "Bobot is an intelligent robot."
10
+ get_started:
11
+ payload: 'get_started'
12
+ persistent_menu:
13
+ composer_input_disabled: false
14
+ call_to_actions:
15
+ - title: "My Account"
16
+ type: "nested"
17
+ call_to_actions:
18
+ - title: "What is a chatbot?"
19
+ type: "postback"
20
+ payload: "WHAT_IS_A_CHATBOT"
21
+ - title: "History"
22
+ type: "postback"
23
+ payload: "HISTORY_PAYLOAD"
24
+ - title: "Contact Info"
25
+ type: "postback"
26
+ payload: "CONTACT_INFO_PAYLOAD"
27
+ - type: "web_url"
28
+ title: "Get some help"
29
+ url: "https://github.com/navidemad/bobot"
30
+ webview_height_ratio: "full"
31
+ what_is_a_chatbot: "A chatbot is a computer program which conducts a conversation via auditory or textual methods."
@@ -0,0 +1,30 @@
1
+ fr:
2
+ bobot:
3
+ facebook_1:
4
+ config:
5
+ facebook_locales:
6
+ - "fr_FR"
7
+ - "fr_CA"
8
+ greeting_text: 'Bobot est un robot intelligent.'
9
+ get_started:
10
+ payload: 'get_started'
11
+ persistent_menu:
12
+ composer_input_disabled: false
13
+ call_to_actions:
14
+ - title: "Mon compte"
15
+ type: "nested"
16
+ call_to_actions:
17
+ - title: "C'est quoi un chatbot ?"
18
+ type: "postback"
19
+ payload: "WHAT_IS_A_CHATBOT"
20
+ - title: "Historique"
21
+ type: "postback"
22
+ payload: "HISTORY_PAYLOAD"
23
+ - title: "Contact Info"
24
+ type: "postback"
25
+ payload: "CONTACT_INFO_PAYLOAD"
26
+ - type: "web_url"
27
+ title: "Obtenir de l'aide"
28
+ url: "https://github.com/navidemad/bobot"
29
+ webview_height_ratio: "full"
30
+ what_is_a_chatbot: "Un chatbot est un programme qui tente de converser avec une personne durant quelques minutes ou plus en lui donnant l'impression de converser elle-même avec une personne."