nuntius 0.1.1 → 1.0.27
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +199 -63
- data/Rakefile +62 -1
- data/app/controllers/nuntius/admin/campaigns_controller.rb +56 -0
- data/app/controllers/nuntius/admin/layouts/attachments_controller.rb +32 -0
- data/app/controllers/nuntius/admin/layouts_controller.rb +50 -0
- data/app/controllers/nuntius/admin/lists/subscribers_controller.rb +50 -0
- data/app/controllers/nuntius/admin/lists_controller.rb +46 -0
- data/app/controllers/nuntius/admin/locales_controller.rb +46 -0
- data/app/controllers/nuntius/admin/messages_controller.rb +24 -0
- data/app/controllers/nuntius/admin/templates_controller.rb +56 -0
- data/app/controllers/nuntius/api/events_controller.rb +16 -0
- data/app/controllers/nuntius/application_admin_controller.rb +11 -0
- data/app/controllers/nuntius/application_controller.rb +12 -0
- data/app/controllers/nuntius/callbacks_controller.rb +21 -0
- data/app/controllers/nuntius/dashboard_controller.rb +12 -0
- data/app/controllers/nuntius/feedback_controller.rb +17 -0
- data/app/controllers/nuntius/inbound_messages/twilio_inbound_smses_controller.rb +56 -0
- data/app/controllers/nuntius/messages_controller.rb +13 -0
- data/app/drops/nuntius/application_drop.rb +17 -0
- data/app/drops/nuntius/campaign_drop.rb +7 -0
- data/app/drops/nuntius/layout_drop.rb +11 -0
- data/app/drops/nuntius/message_drop.rb +11 -0
- data/app/drops/nuntius/template_drop.rb +7 -0
- data/app/exceptions/nuntius/base_exception.rb +4 -0
- data/app/exceptions/nuntius/missing_messenger_exception.rb +4 -0
- data/app/helpers/nuntius/application_helper.rb +78 -0
- data/app/jobs/nuntius/application_job.rb +9 -0
- data/app/jobs/nuntius/deliver_inbound_message_job.rb +10 -0
- data/app/jobs/nuntius/messenger_job.rb +17 -0
- data/app/jobs/nuntius/process_inbound_message_job.rb +10 -0
- data/app/jobs/nuntius/purge_message_job.rb +13 -0
- data/app/jobs/nuntius/retrieve_mail_job.rb +18 -0
- data/app/jobs/nuntius/transport_delivery_job.rb +32 -0
- data/app/jobs/nuntius/transport_refresh_job.rb +22 -0
- data/app/message_boxes/nuntius/base_message_box.rb +75 -0
- data/app/messengers/nuntius/base_messenger.rb +193 -0
- data/app/messengers/nuntius/custom_messenger.rb +6 -0
- data/app/models/nuntius/application_record.rb +11 -0
- data/app/models/nuntius/attachment.rb +13 -0
- data/app/models/nuntius/campaign.rb +75 -0
- data/app/models/nuntius/concerns/metadata_scoped.rb +31 -0
- data/app/models/nuntius/concerns/yamlify.rb +23 -0
- data/app/models/nuntius/inbound_message.rb +14 -0
- data/app/models/nuntius/layout.rb +13 -0
- data/app/models/nuntius/list.rb +10 -0
- data/app/models/nuntius/locale.rb +11 -0
- data/app/models/nuntius/message.rb +148 -0
- data/app/models/nuntius/subscriber.rb +12 -0
- data/app/models/nuntius/template.rb +102 -0
- data/app/presenters/application_presenter.rb +28 -0
- data/app/presenters/template_presenter.rb +17 -0
- data/app/providers/nuntius/apnotic_push_provider.rb +44 -0
- data/app/providers/nuntius/base_provider.rb +72 -0
- data/app/providers/nuntius/firebase_push_provider.rb +26 -0
- data/app/providers/nuntius/houston_push_provider.rb +40 -0
- data/app/providers/nuntius/message_bird_sms_provider.rb +39 -0
- data/app/providers/nuntius/slack_slack_provider.rb +36 -0
- data/app/providers/nuntius/smtp_mail_provider.rb +80 -0
- data/app/providers/nuntius/twilio_sms_provider.rb +37 -0
- data/app/providers/nuntius/twilio_voice_provider.rb +70 -0
- data/app/reportlets/nuntius/application_reportlet.rb +35 -0
- data/app/reportlets/nuntius/daily_messages_per_template_reportlet.rb +50 -0
- data/app/runners/nuntius/application_runner.rb +6 -0
- data/app/runners/nuntius/basic_application_runner.rb +15 -0
- data/app/runners/nuntius/timebased_events_runner.rb +15 -0
- data/app/services/nuntius/application_service.rb +7 -0
- data/app/services/nuntius/aws_sns_processor_service.rb +81 -0
- data/app/services/nuntius/deliver_inbound_message_service.rb +14 -0
- data/app/services/nuntius/retrieve_inbound_mail_service.rb +36 -0
- data/app/tables/nuntius_campaigns_table.rb +21 -0
- data/app/tables/nuntius_layouts_table.rb +24 -0
- data/app/tables/nuntius_lists_table.rb +19 -0
- data/app/tables/nuntius_locales_table.rb +18 -0
- data/app/tables/nuntius_messages_table.rb +36 -0
- data/app/tables/nuntius_subscribers_table.rb +19 -0
- data/app/tables/nuntius_templates_table.rb +30 -0
- data/app/transports/nuntius/base_transport.rb +36 -0
- data/app/transports/nuntius/mail_transport.rb +35 -0
- data/app/transports/nuntius/push_transport.rb +15 -0
- data/app/transports/nuntius/slack_transport.rb +6 -0
- data/app/transports/nuntius/sms_transport.rb +6 -0
- data/app/transports/nuntius/voice_transport.rb +6 -0
- data/app/validators/liquid_validator.rb +11 -0
- data/app/views/nuntius/admin/campaigns/edit.html.slim +49 -0
- data/app/views/nuntius/admin/campaigns/index.html.slim +2 -0
- data/app/views/nuntius/admin/layouts/attachments/_attachments.html.slim +28 -0
- data/app/views/nuntius/admin/layouts/attachments/_index.html.slim +2 -0
- data/app/views/nuntius/admin/layouts/attachments/create.json.jbuilder +5 -0
- data/app/views/nuntius/admin/layouts/edit.html.slim +24 -0
- data/app/views/nuntius/admin/layouts/index.html.slim +2 -0
- data/app/views/nuntius/admin/lists/edit.html.slim +14 -0
- data/app/views/nuntius/admin/lists/index.html.slim +2 -0
- data/app/views/nuntius/admin/lists/subscribers/edit.html.slim +14 -0
- data/app/views/nuntius/admin/locales/edit.html.slim +14 -0
- data/app/views/nuntius/admin/locales/index.html.slim +2 -0
- data/app/views/nuntius/admin/messages/index.html.slim +2 -0
- data/app/views/nuntius/admin/messages/show.html.slim +56 -0
- data/app/views/nuntius/admin/templates/edit.html.slim +81 -0
- data/app/views/nuntius/admin/templates/index.html.slim +2 -0
- data/app/views/nuntius/dashboard/show.html.slim +7 -0
- data/app/views/nuntius/messages/show.html.slim +7 -0
- data/config/locales/en.yml +22 -0
- data/config/locales/nl.yml +22 -0
- data/config/routes.rb +38 -0
- data/config/webpack/development.js +5 -0
- data/config/webpack/environment.js +4 -0
- data/config/webpack/production.js +5 -0
- data/config/webpack/test.js +5 -0
- data/config/webpacker.yml +119 -0
- data/db/migrate/20190301201541_create_nuntius_templates.rb +27 -0
- data/db/migrate/20190301202436_create_nuntius_messages.rb +30 -0
- data/db/migrate/20190322112815_create_nuntius_lists.rb +12 -0
- data/db/migrate/20190322114340_create_nuntius_campaigns.rb +18 -0
- data/db/migrate/20190322121338_create_nuntius_subscribers.rb +17 -0
- data/db/migrate/20190327123535_add_metadata_to_models.rb +8 -0
- data/db/migrate/20190327124407_create_nuntius_layouts.rb +24 -0
- data/db/migrate/20190327143921_add_campaign_to_message.rb +7 -0
- data/db/migrate/20190327155112_add_state_to_campaign.rb +7 -0
- data/db/migrate/20190412103335_add_enabled_to_templates.rb +7 -0
- data/db/migrate/20190417125153_change_message_status_default.rb +9 -0
- data/db/migrate/20190417144554_add_nuntiable_to_subscriber.rb +7 -0
- data/db/migrate/20190521135011_add_payload_to_nuntius_messages.rb +7 -0
- data/db/migrate/20190522122657_add_metadata_to_nuntius_message.rb +7 -0
- data/db/migrate/20190825080757_update_nuntius_message_sending_to_sent.rb +11 -0
- data/db/migrate/20200220154927_change_nuntius_templates_payload_type.rb +7 -0
- data/db/migrate/20200224132337_create_nuntius_locales.rb +13 -0
- data/db/migrate/20200318095339_create_nuntius_attachments.rb +12 -0
- data/db/migrate/20200407050646_add_interval_to_nuntius_template.rb +5 -0
- data/db/migrate/20200430131219_make_html_processing_optional.rb +6 -0
- data/db/migrate/20200430154032_make_html_processing_optional_revert.rb +6 -0
- data/db/migrate/20201121185718_create_nuntius_inbound_messages.rb +21 -0
- data/db/migrate/20220412114148_add_last_sent_to_message.rb +5 -0
- data/lib/nuntius/active_record_helpers.rb +28 -0
- data/lib/nuntius/active_storage_helpers.rb +8 -0
- data/lib/nuntius/configuration.rb +97 -0
- data/lib/nuntius/deprecator.rb +8 -0
- data/lib/nuntius/devise.rb +19 -0
- data/lib/nuntius/engine.rb +46 -0
- data/lib/nuntius/i18n_store.rb +100 -0
- data/lib/nuntius/liquid/tags/attach_tag.rb +44 -0
- data/lib/nuntius/mail_allow_list.rb +23 -0
- data/lib/nuntius/nuntiable.rb +24 -0
- data/lib/nuntius/state_machine.rb +19 -0
- data/lib/nuntius/transactio.rb +30 -0
- data/lib/nuntius/version.rb +3 -1
- data/lib/nuntius.rb +74 -8
- data/lib/preamble.rb +87 -0
- data/lib/tasks/nuntius_tasks.rake +27 -0
- metadata +532 -67
- data/.gitignore +0 -4
- data/Gemfile +0 -4
- data/lib/nuntius/encodings/url_safe_base64.rb +0 -26
- data/lib/nuntius/encodings.rb +0 -9
- data/lib/nuntius/envelope.rb +0 -45
- data/lib/nuntius/key.rb +0 -47
- data/lib/nuntius/messenger.rb +0 -37
- data/nuntius.gemspec +0 -23
- data/spec/keys/alice.pem +0 -27
- data/spec/keys/alice.pub +0 -9
- data/spec/keys/bob.pem +0 -27
- data/spec/keys/bob.pub +0 -9
- data/spec/nuntius/encodings/url_safe_base64_spec.rb +0 -36
- data/spec/nuntius/envelope_spec.rb +0 -6
- data/spec/nuntius/key_spec.rb +0 -12
- data/spec/nuntius/messenger_spec.rb +0 -26
- data/spec/spec_helper.rb +0 -9
- data/spec/support/keys.rb +0 -3
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateNuntiusInboundMessages < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :nuntius_inbound_messages, id: :uuid do |t|
|
4
|
+
t.string :status, default: 'pending'
|
5
|
+
t.string :transport
|
6
|
+
t.string :provider
|
7
|
+
t.string :provider_id
|
8
|
+
t.string :from
|
9
|
+
t.string :to
|
10
|
+
t.string :cc
|
11
|
+
t.string :subject
|
12
|
+
t.text :html
|
13
|
+
t.text :text
|
14
|
+
t.jsonb :payload
|
15
|
+
t.jsonb :metadata
|
16
|
+
t.string :digest
|
17
|
+
|
18
|
+
t.timestamps
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'nuntiable'
|
4
|
+
require_relative 'devise'
|
5
|
+
require_relative 'state_machine'
|
6
|
+
require_relative 'transactio'
|
7
|
+
|
8
|
+
module Nuntius::ActiveRecordHelpers
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
delegate :nuntiable?, to: :class
|
13
|
+
end
|
14
|
+
|
15
|
+
class_methods do
|
16
|
+
def nuntiable(options = {})
|
17
|
+
@_nuntius_nuntiable_options = options
|
18
|
+
include Nuntius::Nuntiable
|
19
|
+
include Nuntius::StateMachine if options[:use_state_machine]
|
20
|
+
include Nuntius::Devise if options[:override_devise]
|
21
|
+
include Nuntius::Transactio
|
22
|
+
end
|
23
|
+
|
24
|
+
def nuntiable?
|
25
|
+
included_modules.include?(Nuntius::Nuntiable)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :admin_authentication_module, :base_controller, :base_runner, :layout, :admin_layout, :jobs_queue_name, :visible_scope, :add_metadata, :metadata_fields, :default_template_scope, :allow_custom_events, :active_storage_service
|
6
|
+
attr_writer :logger, :host, :metadata_humanize, :default_params
|
7
|
+
|
8
|
+
attr_reader :transports, :providers
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
@logger = Logger.new(STDOUT)
|
12
|
+
@logger.level = Logger::INFO
|
13
|
+
@base_controller = '::ApplicationController'
|
14
|
+
@base_runner = 'Nuntius::BasicApplicationRunner'
|
15
|
+
@nuntiable_classes = []
|
16
|
+
@nuntiable_class_names = []
|
17
|
+
@transports = []
|
18
|
+
@providers = {}
|
19
|
+
@jobs_queue_name = :message
|
20
|
+
@visible_scope = -> { all }
|
21
|
+
@add_metadata = -> {}
|
22
|
+
@metadata_fields = {}
|
23
|
+
@metadata_humanize = ->(data) { data.inspect }
|
24
|
+
@default_template_scope = ->(_object) { all }
|
25
|
+
@allow_custom_events = false
|
26
|
+
@layout = 'application'
|
27
|
+
@admin_layout = 'application'
|
28
|
+
@active_storage_service = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# logger [Object].
|
32
|
+
def logger
|
33
|
+
@logger.is_a?(Proc) ? instance_exec(&@logger) : @logger
|
34
|
+
end
|
35
|
+
|
36
|
+
def host(message)
|
37
|
+
@host.is_a?(Proc) ? instance_exec(message, &@host) : @host
|
38
|
+
end
|
39
|
+
|
40
|
+
# Make the part that is important for visible readable for humans
|
41
|
+
def metadata_humanize(metadata)
|
42
|
+
@metadata_humanize.is_a?(Proc) ? instance_exec(metadata, &@metadata_humanize) : @metadata_humanize
|
43
|
+
end
|
44
|
+
|
45
|
+
# admin_mount_point [String].
|
46
|
+
def admin_mount_point
|
47
|
+
@admin_mount_point ||= '/nuntius'
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_nuntiable_class(klass)
|
51
|
+
@nuntiable_class_names = []
|
52
|
+
@nuntiable_classes << klass.to_s unless @nuntiable_classes.include?(klass.to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
def nuntiable_class_names
|
56
|
+
return @nuntiable_class_names if @nuntiable_class_names.present?
|
57
|
+
|
58
|
+
compile_nuntiable_class_names!
|
59
|
+
end
|
60
|
+
|
61
|
+
def provider(provider, transport:, priority: 1, timeout: 0, settings: {})
|
62
|
+
if @transports.include? transport
|
63
|
+
@providers[transport.to_sym] ||= []
|
64
|
+
@providers[transport.to_sym].push(provider: provider, priority: priority, timeout: timeout, settings: settings)
|
65
|
+
else
|
66
|
+
Nuntius.logger.warn "provider #{provider} not enabled as transport #{transport} is not enabled"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def transport(transport)
|
71
|
+
@transports.push(transport) if transport
|
72
|
+
end
|
73
|
+
|
74
|
+
def default_params(transaction_log_entry)
|
75
|
+
@default_params.is_a?(Proc) ? instance_exec(transaction_log_entry, &@default_params) : @default_params
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def compile_nuntiable_class_names
|
81
|
+
names = []
|
82
|
+
names << 'Custom' if allow_custom_events
|
83
|
+
|
84
|
+
@nuntiable_classes.each do |klass_name|
|
85
|
+
klass = klass_name.constantize
|
86
|
+
names << klass.name
|
87
|
+
names += klass.descendants.map(&:name)
|
88
|
+
end
|
89
|
+
|
90
|
+
names.sort!
|
91
|
+
end
|
92
|
+
|
93
|
+
def compile_nuntiable_class_names!
|
94
|
+
@nuntiable_class_names = compile_nuntiable_class_names
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
module Devise
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
raise "#{name} must be nuntiable" unless nuntiable?
|
9
|
+
|
10
|
+
orchestrator = Evento::Orchestrator.new(self)
|
11
|
+
orchestrator.define_event_methods_on(messenger, devise: true) { |object, options = {}| }
|
12
|
+
|
13
|
+
orchestrator.override_devise_notification do |notification, *devise_params|
|
14
|
+
# All notifications have either a token as the first param, or nothing
|
15
|
+
Nuntius.event(notification, self, { token: devise_params.first })
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
class Engine < ::Rails::Engine
|
5
|
+
isolate_namespace Nuntius
|
6
|
+
|
7
|
+
initializer 'nuntius.config' do |_app|
|
8
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), '.', 'liquid', '{tags,filters}', '*.rb'))
|
9
|
+
Dir.glob(path).each do |c|
|
10
|
+
require_dependency(c)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer :append_migrations do |app|
|
15
|
+
unless app.root.to_s.match? root.to_s
|
16
|
+
config.paths['db/migrate'].expanded.each do |expanded_path|
|
17
|
+
app.config.paths['db/migrate'] << expanded_path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
initializer 'active_storage.attached' do
|
23
|
+
config.after_initialize do
|
24
|
+
ActiveSupport.on_load(:active_record) do
|
25
|
+
Nuntius::Attachment.include(Nuntius::ActiveStorageHelpers)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# initializer "webpacker.proxy" do |app|
|
32
|
+
# insert_middleware = begin
|
33
|
+
# Nuntius.webpacker.config.dev_server.present?
|
34
|
+
# rescue
|
35
|
+
# nil
|
36
|
+
# end
|
37
|
+
# next unless insert_middleware
|
38
|
+
#
|
39
|
+
# app.middleware.insert_before(
|
40
|
+
# 0, Webpacker::DevServerProxy, # "Webpacker::DevServerProxy" if Rails version < 5
|
41
|
+
# ssl_verify_none: true,
|
42
|
+
# webpacker: Nuntius.webpacker
|
43
|
+
# )
|
44
|
+
# end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'i18n/core_ext/hash'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
begin
|
7
|
+
require 'oj'
|
8
|
+
class JSON
|
9
|
+
class << self
|
10
|
+
def encode(value)
|
11
|
+
Oj::Rails.encode(value)
|
12
|
+
end
|
13
|
+
|
14
|
+
def decode(value)
|
15
|
+
Oj.load(value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
require 'active_support/json'
|
21
|
+
JSON = ActiveSupport::JSON
|
22
|
+
end
|
23
|
+
|
24
|
+
class I18nStore
|
25
|
+
def initialize; end
|
26
|
+
|
27
|
+
def keys
|
28
|
+
return [] unless template
|
29
|
+
|
30
|
+
result = []
|
31
|
+
locales.each do |locale|
|
32
|
+
result += flat_hash(locale.data).keys
|
33
|
+
end
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
def [](key)
|
38
|
+
return unless template
|
39
|
+
|
40
|
+
result = {}
|
41
|
+
locales.each do |locale|
|
42
|
+
hash = flat_hash(locale.data).transform_values { |v| JSON.encode(v) }
|
43
|
+
result.merge! hash
|
44
|
+
end
|
45
|
+
result[key]
|
46
|
+
end
|
47
|
+
|
48
|
+
def []=(key, value)
|
49
|
+
# NOOP
|
50
|
+
end
|
51
|
+
|
52
|
+
def with(template)
|
53
|
+
with_custom_backend do
|
54
|
+
self.template = template
|
55
|
+
yield(template)
|
56
|
+
self.template = nil
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def template
|
61
|
+
Thread.current[:nuntius_i18n_store_template]
|
62
|
+
end
|
63
|
+
|
64
|
+
def template=(template)
|
65
|
+
Thread.current[:nuntius_i18n_store_template] = template
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def with_custom_backend
|
71
|
+
Thread.current[:nuntius_i18n_store_old_backend] = I18n.backend
|
72
|
+
I18n.backend = I18n::Backend::Chain.new(custom_i18n_backend, I18n.backend)
|
73
|
+
|
74
|
+
yield
|
75
|
+
|
76
|
+
I18n.backend = Thread.current[:nuntius_i18n_store_old_backend]
|
77
|
+
end
|
78
|
+
|
79
|
+
def locales
|
80
|
+
Nuntius::Locale.all
|
81
|
+
end
|
82
|
+
|
83
|
+
def flat_hash(hash = {})
|
84
|
+
(hash || {}).reduce({}) do |a, (k, v)|
|
85
|
+
tmp = v.is_a?(Hash) ? flat_hash(v).map { |k2, v2| ["#{k}.#{k2}", v2] }.to_h : { k => v }
|
86
|
+
a.merge(tmp)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Yield our own custom backend
|
91
|
+
def custom_i18n_backend
|
92
|
+
return @custom_i18n_backend if @custom_i18n_backend
|
93
|
+
|
94
|
+
@custom_i18n_backend = I18n::Backend::KeyValue.new(Nuntius.i18n_store)
|
95
|
+
@custom_i18n_backend.class.send(:include, I18n::Backend::Cascade)
|
96
|
+
|
97
|
+
@custom_i18n_backend
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Attaches files (from URL)
|
4
|
+
#
|
5
|
+
# == Basic usage:
|
6
|
+
# {%attach 'https://www.boxture.com/assets/images/logo.png'%}
|
7
|
+
#
|
8
|
+
class AttachTag < LiquidumTag
|
9
|
+
def render(context)
|
10
|
+
super
|
11
|
+
|
12
|
+
return unless argv1
|
13
|
+
|
14
|
+
message = context.registers['message']
|
15
|
+
|
16
|
+
if argv1.is_a? String
|
17
|
+
message.add_attachment({ url: argv1 })
|
18
|
+
elsif argv1.instance_of?(ActiveStorageAttachedOneDrop) || argv1.instance_of?(ActiveStorage::AttachmentDrop)
|
19
|
+
|
20
|
+
io = StringIO.new(argv1.download)
|
21
|
+
io.rewind
|
22
|
+
content_type = argv1.content_type
|
23
|
+
filename = argv1.filename
|
24
|
+
|
25
|
+
if arg(:convert) == 'pdf' && content_type != 'application/pdf'
|
26
|
+
content_type = 'application/pdf'
|
27
|
+
pdf = Labelary::Label.render(zpl: io.read,
|
28
|
+
content_type: content_type,
|
29
|
+
dpmm: 8,
|
30
|
+
width: arg(:width).blank? ? 4 : arg(:width),
|
31
|
+
height: arg(:height).blank? ? 6 : arg(:height))
|
32
|
+
|
33
|
+
io = StringIO.new(pdf)
|
34
|
+
filename = "#{filename}.pdf"
|
35
|
+
end
|
36
|
+
|
37
|
+
message.add_attachment({ content: io, filename: filename, content_type: content_type })
|
38
|
+
end
|
39
|
+
|
40
|
+
''
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Liquid::Template.register_tag('attach', AttachTag)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'mail'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
class MailAllowList
|
7
|
+
def initialize(allow_list = [])
|
8
|
+
allow_list = [] if allow_list.blank?
|
9
|
+
@allow_list = allow_list.map(&:downcase)
|
10
|
+
end
|
11
|
+
|
12
|
+
def allowed?(email)
|
13
|
+
return true if @allow_list.blank?
|
14
|
+
|
15
|
+
mail_to = Mail::Address.new(email.downcase)
|
16
|
+
allow_list_match = @allow_list.detect do |allow|
|
17
|
+
allow == (allow.include?('@') ? mail_to.to_s : mail_to.domain)
|
18
|
+
end
|
19
|
+
|
20
|
+
allow_list_match.present?
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
module Nuntiable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def nuntiable_options
|
9
|
+
@_nuntius_nuntiable_options || {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def messenger
|
13
|
+
Nuntius::BaseMessenger.messenger_for_class(name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
included do
|
18
|
+
raise "Nuntius Messenger has not been implemented for class #{name}" unless messenger
|
19
|
+
|
20
|
+
Nuntius.config.add_nuntiable_class(self)
|
21
|
+
has_many :messages, as: :nuntiable, class_name: 'Nuntius::Message'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
module StateMachine
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
raise "#{name} must be nuntiable" unless nuntiable?
|
9
|
+
|
10
|
+
orchestrator = Evento::Orchestrator.new(self)
|
11
|
+
orchestrator.define_event_methods_on(messenger, state_machine: true) { |object, options = {}| }
|
12
|
+
|
13
|
+
orchestrator.after_audit_trail_commit(:nuntius) do |resource_state_transition|
|
14
|
+
resource = resource_state_transition.resource
|
15
|
+
Nuntius.event(event, resource) if resource.nuntiable? && event.present?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
module Transactio
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
raise "#{name} must be nuntiable" unless nuntiable?
|
9
|
+
|
10
|
+
orchestrator = Evento::Orchestrator.new(self)
|
11
|
+
if nuntiable_options[:life_cycle]
|
12
|
+
orchestrator.define_event_methods_on(messenger, life_cycle: true) do |object, options = {}|
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
orchestrator = Evento::Orchestrator.new(self)
|
17
|
+
orchestrator.after_transaction_log_commit(:nuntius) do |transaction_log_entry|
|
18
|
+
resource = transaction_log_entry.transaction_loggable
|
19
|
+
event = transaction_log_entry.event
|
20
|
+
|
21
|
+
if resource.present? && event.present? && resource.nuntiable?
|
22
|
+
params = Nuntius.config.default_params(transaction_log_entry)
|
23
|
+
|
24
|
+
Nuntius.event(event, resource, params)
|
25
|
+
Nuntius.event('save', resource, params) if %w[create update].include?(event)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/nuntius/version.rb
CHANGED
data/lib/nuntius.rb
CHANGED
@@ -1,11 +1,77 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'auxilium'
|
4
|
+
require 'inky'
|
5
|
+
require 'httpclient'
|
6
|
+
require 'liquidum'
|
7
|
+
require 'premailer'
|
8
|
+
require 'state_machines-activerecord'
|
9
|
+
require 'servitium'
|
10
|
+
|
11
|
+
require 'nuntius/deprecator'
|
12
|
+
require 'nuntius/engine'
|
13
|
+
require 'nuntius/configuration'
|
14
|
+
require 'nuntius/active_record_helpers'
|
15
|
+
require 'nuntius/active_storage_helpers'
|
16
|
+
require 'nuntius/i18n_store'
|
17
|
+
require 'nuntius/mail_allow_list'
|
2
18
|
|
3
19
|
module Nuntius
|
4
|
-
|
5
|
-
|
20
|
+
ROOT_PATH = Pathname.new(File.join(__dir__, '..'))
|
21
|
+
|
22
|
+
class Error < StandardError; end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_reader :config
|
26
|
+
|
27
|
+
def setup
|
28
|
+
@config = Configuration.new
|
29
|
+
yield config
|
30
|
+
end
|
31
|
+
|
32
|
+
def i18n_store
|
33
|
+
@i18n_store ||= Nuntius::I18nStore.new
|
34
|
+
end
|
6
35
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
36
|
+
#
|
37
|
+
# Fires an event for use with templates with the object
|
38
|
+
#
|
39
|
+
# Nuntius.event(:your_event, car)
|
40
|
+
#
|
41
|
+
# When custom events are enabled you can also do the following:
|
42
|
+
#
|
43
|
+
# Nuntius.event('shipped', { shipped: { to: 'test@example.com', ref: 'Test-123'} }, attachments: [ { url: 'http://example.com' } ])
|
44
|
+
#
|
45
|
+
def event(event, obj, params = {})
|
46
|
+
return unless event
|
47
|
+
return unless obj.is_a?(Hash) || obj.nuntiable?
|
48
|
+
return unless templates?(obj, event)
|
49
|
+
|
50
|
+
options = params[:options] || {}
|
51
|
+
|
52
|
+
if options[:perform_now] == true
|
53
|
+
Nuntius::MessengerJob.perform_now(obj, event.to_s, params)
|
54
|
+
else
|
55
|
+
job = Nuntius::MessengerJob
|
56
|
+
job.set(wait: options[:wait]) if options[:wait]
|
57
|
+
job.perform_later(obj, event.to_s, params)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def active_storage_enabled?
|
62
|
+
ActiveRecord::Base.connection.table_exists? 'active_storage_attachments'
|
63
|
+
end
|
64
|
+
|
65
|
+
def templates?(obj, event)
|
66
|
+
Nuntius::Template.where(klass: Nuntius::BaseMessenger.class_names_for(obj),
|
67
|
+
event: Nuntius::BaseMessenger.event_name_for(
|
68
|
+
obj, event
|
69
|
+
)).where(enabled: true).count.positive?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Include helpers
|
74
|
+
ActiveSupport.on_load(:active_record) do
|
75
|
+
include Nuntius::ActiveRecordHelpers
|
76
|
+
end
|
77
|
+
end
|
data/lib/preamble.rb
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Preamble
|
4
|
+
DEFAULTS = {
|
5
|
+
external_encoding: Encoding.default_external
|
6
|
+
}.freeze
|
7
|
+
|
8
|
+
attr_accessor :metadata, :content
|
9
|
+
|
10
|
+
def initialize(metadata, content)
|
11
|
+
@metadata = metadata
|
12
|
+
@content = content
|
13
|
+
end
|
14
|
+
|
15
|
+
def metadata_with_content
|
16
|
+
@metadata.to_yaml + "---\n" + @content
|
17
|
+
end
|
18
|
+
|
19
|
+
def dump
|
20
|
+
metadata_with_content
|
21
|
+
end
|
22
|
+
|
23
|
+
def save(path, options = {})
|
24
|
+
options = DEFAULTS.merge(options)
|
25
|
+
|
26
|
+
open(path, "w:#{options[:external_encoding]}") do |f|
|
27
|
+
f.write metadata_with_content
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.parse(data)
|
32
|
+
preamble_lines = +''
|
33
|
+
content_lines = +''
|
34
|
+
|
35
|
+
state = :before_preamble
|
36
|
+
|
37
|
+
f = StringIO.new(data)
|
38
|
+
f.each do |line|
|
39
|
+
stripped = line.strip
|
40
|
+
|
41
|
+
case state
|
42
|
+
when :before_preamble
|
43
|
+
|
44
|
+
new_state = case stripped
|
45
|
+
when '---'
|
46
|
+
:preamble
|
47
|
+
when ''
|
48
|
+
:before_preamble
|
49
|
+
else
|
50
|
+
content_lines << line
|
51
|
+
:after_preamble
|
52
|
+
end
|
53
|
+
|
54
|
+
when :preamble
|
55
|
+
|
56
|
+
new_state = case stripped
|
57
|
+
when '---'
|
58
|
+
:after_preamble
|
59
|
+
else
|
60
|
+
preamble_lines << line
|
61
|
+
:preamble
|
62
|
+
end
|
63
|
+
|
64
|
+
when :after_preamble
|
65
|
+
new_state = :after_preamble
|
66
|
+
content_lines << line
|
67
|
+
|
68
|
+
else
|
69
|
+
raise "Invalid State: #{state}"
|
70
|
+
end
|
71
|
+
|
72
|
+
state = new_state
|
73
|
+
end
|
74
|
+
|
75
|
+
new(YAML.safe_load(preamble_lines), content_lines)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.load(path, options = {})
|
79
|
+
f = open(path, "r:#{options[:external_encoding]}")
|
80
|
+
parse(f.read)
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.load_multiple(*paths)
|
84
|
+
options = paths.last.is_a?(Hash) ? paths.pop : {}
|
85
|
+
paths.map { |path| Preamble.load(path, options) }
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
desc 'Release a new version'
|
4
|
+
namespace :nuntius do
|
5
|
+
task :release do
|
6
|
+
version_file = './lib/nuntius/version.rb'
|
7
|
+
File.open(version_file, 'w') do |file|
|
8
|
+
file.puts <<~EOVERSION
|
9
|
+
# frozen_string_literal: true
|
10
|
+
|
11
|
+
module Nuntius
|
12
|
+
VERSION = '#{Nuntius::VERSION.split('.').map(&:to_i).tap { |parts| parts[2] += 1 }.join('.')}'
|
13
|
+
end
|
14
|
+
EOVERSION
|
15
|
+
end
|
16
|
+
module Nuntius
|
17
|
+
remove_const :VERSION
|
18
|
+
end
|
19
|
+
load version_file
|
20
|
+
puts "Updated version to #{Nuntius::VERSION}"
|
21
|
+
|
22
|
+
`git commit lib/nuntius/version.rb -m "Version #{Nuntius::VERSION}"`
|
23
|
+
`git push`
|
24
|
+
`git tag #{Nuntius::VERSION}`
|
25
|
+
`git push --tags`
|
26
|
+
end
|
27
|
+
end
|