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,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_admin_controller'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
module Admin
|
7
|
+
class MessagesController < ApplicationAdminController
|
8
|
+
def index
|
9
|
+
@messages = Nuntius::Message.visible.order(created_at: :desc)
|
10
|
+
@messages = @messages.where(template_id: params[:template_id]) if params[:template_id]
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
@message = Nuntius::Message.visible.find(params[:id])
|
15
|
+
end
|
16
|
+
|
17
|
+
def resend
|
18
|
+
@message = Nuntius::Message.visible.find(params[:id])
|
19
|
+
@message.resend
|
20
|
+
respond_with @message, success: t('.resend_success'), error: t('.resend_error')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_admin_controller'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
module Admin
|
7
|
+
class TemplatesController < ApplicationAdminController
|
8
|
+
before_action :set_objects, except: [:index]
|
9
|
+
|
10
|
+
def index
|
11
|
+
@templates = Nuntius::Template.visible.order(:description)
|
12
|
+
end
|
13
|
+
|
14
|
+
def new
|
15
|
+
@template = Nuntius::Template.new
|
16
|
+
render :edit
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
@template = Nuntius::Template.new(template_params)
|
21
|
+
@template.save
|
22
|
+
respond_with :admin, @template, action: :edit
|
23
|
+
end
|
24
|
+
|
25
|
+
def edit
|
26
|
+
@template = Nuntius::Template.visible.find(params[:id])
|
27
|
+
end
|
28
|
+
|
29
|
+
def show
|
30
|
+
redirect_to :edit_admin_template, status: :see_other
|
31
|
+
end
|
32
|
+
|
33
|
+
def update
|
34
|
+
@template = Nuntius::Template.visible.find(params[:id])
|
35
|
+
@template.update(template_params)
|
36
|
+
respond_with :admin, @template
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy
|
40
|
+
@template = Nuntius::Template.visible.find(params[:id])
|
41
|
+
@template.destroy
|
42
|
+
respond_with :admin, @template
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def set_objects
|
48
|
+
@layouts = Nuntius::Layout.visible
|
49
|
+
end
|
50
|
+
|
51
|
+
def template_params
|
52
|
+
params.require(:template).permit(:enabled, :klass, :event, :interval, :transport, :description, :metadata_yaml, :payload, :from, :to, :subject, :layout_id, :html, :text, :payload)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_controller'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
class Api::EventsController < ApplicationController
|
7
|
+
skip_before_action :verify_authenticity_token
|
8
|
+
|
9
|
+
layout false
|
10
|
+
|
11
|
+
def create
|
12
|
+
nuntius_params = params.except(:scope, :event, :context, :controller, :action).permit!.to_h
|
13
|
+
Nuntius.event(params[:event], { params[:scope] => params[:context].permit!.to_h }, nuntius_params)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_controller'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
class ApplicationAdminController < ApplicationController
|
7
|
+
include Nuntius.config.admin_authentication_module.constantize if Nuntius.config.admin_authentication_module
|
8
|
+
|
9
|
+
layout Nuntius.config.admin_layout
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
class ApplicationController < Nuntius.config.base_controller.constantize
|
5
|
+
self.responder = Auxilium::Responder
|
6
|
+
respond_to :html
|
7
|
+
|
8
|
+
protect_from_forgery with: :exception
|
9
|
+
|
10
|
+
layout Nuntius.config.layout
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_controller'
|
4
|
+
require 'preamble'
|
5
|
+
|
6
|
+
module Nuntius
|
7
|
+
class CallbacksController < ApplicationController
|
8
|
+
skip_before_action :verify_authenticity_token
|
9
|
+
|
10
|
+
layout false
|
11
|
+
|
12
|
+
def create
|
13
|
+
message = Nuntius::Message.find(params[:message_id])
|
14
|
+
response = message.nuntius_provider(message).callback(params)
|
15
|
+
|
16
|
+
render body: response[2].first,
|
17
|
+
content_type: response[1]['Content-Type'],
|
18
|
+
layout: false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_admin_controller'
|
4
|
+
|
5
|
+
module Nuntius
|
6
|
+
class DashboardController < ApplicationAdminController
|
7
|
+
def show
|
8
|
+
@templates = Nuntius::Template.visible.all
|
9
|
+
@messages = Nuntius::Message.visible.order(created_at: :desc).limit(10)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_controller'
|
4
|
+
require 'httpclient'
|
5
|
+
|
6
|
+
module Nuntius
|
7
|
+
class FeedbackController < ApplicationController
|
8
|
+
skip_before_action :verify_authenticity_token
|
9
|
+
|
10
|
+
layout false
|
11
|
+
|
12
|
+
def awssns
|
13
|
+
Nuntius::AwsSnsProcessorService.perform(notification: ::JSON.parse(request.body.read))
|
14
|
+
head :ok
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency 'nuntius/application_controller'
|
4
|
+
require 'twilio-ruby'
|
5
|
+
|
6
|
+
module Nuntius
|
7
|
+
module InboundMessages
|
8
|
+
class TwilioInboundSmsesController < ApplicationController
|
9
|
+
skip_before_action :verify_authenticity_token
|
10
|
+
|
11
|
+
layout false
|
12
|
+
|
13
|
+
# Point twilio to you nuntius mount path (/nuntius/inbound_messages/twilio_inbound_smses)
|
14
|
+
# { 'ToCountry' => 'NL',
|
15
|
+
# 'ToState' => '',
|
16
|
+
# 'SmsMessageSid' => 'SMb711289e438f577f230f5837e9c74a08',
|
17
|
+
# 'NumMedia' => '0',
|
18
|
+
# 'ToCity' => '',
|
19
|
+
# 'FromZip' => '',
|
20
|
+
# 'SmsSid' => 'SMb711289e438f577f230f5837e9c74a08',
|
21
|
+
# 'FromState' => '',
|
22
|
+
# 'SmsStatus' => 'received',
|
23
|
+
# 'FromCity' => '',
|
24
|
+
# 'Body' => 'St',
|
25
|
+
# 'FromCountry' => 'NL',
|
26
|
+
# 'To' => '+3197014204768',
|
27
|
+
# 'MessagingServiceSid' => 'MG790b6bd09f119b54ffb7f03b8841b1c9',
|
28
|
+
# 'ToZip' => '',
|
29
|
+
# 'NumSegments' => '1',
|
30
|
+
# 'MessageSid' => 'SMb711289e438f577f230f5837e9c74a08',
|
31
|
+
# 'AccountSid' => 'ACf54dd7a47a8011d65b54d472a7190549',
|
32
|
+
# 'From' => '+31641085630',
|
33
|
+
# 'ApiVersion' => '2010-04-01',
|
34
|
+
# 'controller' => 'nuntius/inbound_messages/twilio_inbound_smses',
|
35
|
+
# 'action' => 'create' }
|
36
|
+
def create
|
37
|
+
inbound_message = Nuntius::InboundMessage.find_or_create_by!(transport: 'sms', provider: 'twilio', provider_id: params[:SmsSid])
|
38
|
+
inbound_message.from = params[:From]
|
39
|
+
inbound_message.to = params[:To]
|
40
|
+
inbound_message.text = params[:Body]
|
41
|
+
inbound_message.metadata = params
|
42
|
+
inbound_message.save!
|
43
|
+
|
44
|
+
twiml = Nuntius::DeliverInboundMessageService.new(inbound_message).call
|
45
|
+
|
46
|
+
# twiml = Twilio::TwiML::MessagingResponse.new do |resp|
|
47
|
+
# resp.message body: 'The Robots are coming! Head for the hills!'
|
48
|
+
# end
|
49
|
+
|
50
|
+
render body: twiml.to_s,
|
51
|
+
content_type: 'text/xml',
|
52
|
+
layout: false
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
class MessageDrop < ApplicationDrop
|
5
|
+
delegate :id, :from, :to, :subject, :html, :text, to: :@object
|
6
|
+
|
7
|
+
def base_url
|
8
|
+
Nuntius::Engine.routes.url_helpers.message_url(@object.id, host: host)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
module ApplicationHelper
|
5
|
+
def nuntius_dashboard_menu
|
6
|
+
Satis::Menus::Builder.build(:dashboard) do |m|
|
7
|
+
m.item :templates, link: nuntius.admin_templates_path, icon: 'fal fa-file'
|
8
|
+
m.item :layouts, link: nuntius.admin_layouts_path, icon: 'fal fa-table-layout'
|
9
|
+
m.item :locales, link: nuntius.admin_locales_path, icon: 'fal fa-language'
|
10
|
+
m.item :campaigns, link: nuntius.admin_campaigns_path, icon: 'fal fa-megaphone'
|
11
|
+
m.item :lists, link: nuntius.admin_lists_path, icon: 'fal fa-address-book'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def nuntius_templates_menu
|
16
|
+
Satis::Menus::Builder.build(:templates) do |m|
|
17
|
+
m.item :new, link: nuntius.new_admin_template_path
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def nuntius_messages_menu
|
22
|
+
Satis::Menus::Builder.build(:messages) do |m|
|
23
|
+
m.item :new, link: nuntius.new_admin_message_path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def nuntius_layouts_menu
|
28
|
+
Satis::Menus::Builder.build(:layouts) do |m|
|
29
|
+
m.item :new, link: nuntius.new_admin_layout_path
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def nuntius_locales_menu
|
34
|
+
Satis::Menus::Builder.build(:locales) do |m|
|
35
|
+
m.item :new, link: nuntius.new_admin_locale_path
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def nuntius_campaigns_menu
|
40
|
+
Satis::Menus::Builder.build(:campaign) do |m|
|
41
|
+
m.item :new, link: nuntius.new_admin_campaign_path
|
42
|
+
m.item :lists, link: nuntius.admin_lists_path
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def nuntius_lists_menu
|
47
|
+
Satis::Menus::Builder.build(:lists) do |m|
|
48
|
+
m.item :new, link: nuntius.new_admin_list_path
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def nuntius_list_menu
|
53
|
+
Satis::Menus::Builder.build(:lists) do |m|
|
54
|
+
m.item :new_subscriber, link: nuntius.new_admin_list_subscriber_path(@list) if @list.persisted?
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def present(model, presenter_class = nil)
|
59
|
+
array = nil
|
60
|
+
if model.is_a? Array
|
61
|
+
array = model
|
62
|
+
model = model.first
|
63
|
+
end
|
64
|
+
|
65
|
+
klass = presenter_class || "#{model.class}Presenter".constantize
|
66
|
+
presenter = array ? array.map { |m| klass.new(m) } : klass.new(model)
|
67
|
+
yield(presenter) if block_given?
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_missing(method, *args, &block)
|
71
|
+
if main_app.respond_to?(method)
|
72
|
+
main_app.send(method, *args)
|
73
|
+
else
|
74
|
+
super
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Initializes the appropriate Messenger class and calls the event method
|
4
|
+
module Nuntius
|
5
|
+
class DeliverInboundMessageJob < ApplicationJob
|
6
|
+
def perform(inbound_message)
|
7
|
+
Nuntius::DeliverInboundMessageService.new(inbound_message).call
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Initializes the appropriate Messenger class and calls the event method
|
4
|
+
module Nuntius
|
5
|
+
class MessengerJob < ApplicationJob
|
6
|
+
def perform(obj, event, params = {})
|
7
|
+
return unless obj
|
8
|
+
|
9
|
+
messenger = Nuntius::BaseMessenger.messenger_for_obj(obj).new(obj, event, params)
|
10
|
+
return unless messenger.is_a?(Nuntius::CustomMessenger) || messenger.respond_to?(event.to_sym)
|
11
|
+
|
12
|
+
messenger.call
|
13
|
+
templates = messenger.templates
|
14
|
+
messenger.dispatch(templates) if templates.present?
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Initializes the appropriate Messenger class and calls the event method
|
4
|
+
module Nuntius
|
5
|
+
class ProcessInboundMessageJob < ApplicationJob
|
6
|
+
def perform(inbound_message)
|
7
|
+
Nuntius::DeliverInboundMessageService.perform(inbound_message: inbound_message)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Nuntius
|
2
|
+
class PurgeMessageJob < ApplicationJob
|
3
|
+
def perform(account_id, months)
|
4
|
+
messages = Nuntius::Message.distinct.select(:id).where("metadata ->> 'account_id' = :account", account: account_id)
|
5
|
+
.where(created_at: ..months.months.ago.beginning_of_day)
|
6
|
+
.where.not(status: %w[complaint bounced])
|
7
|
+
|
8
|
+
Nuntius::Message.where(parent_message_id: messages.pluck(:id)).in_batches.update_all(parent_message_id: nil)
|
9
|
+
|
10
|
+
messages.in_batches.destroy_all
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Initializes the appropriate Messenger class and calls the event method
|
4
|
+
module Nuntius
|
5
|
+
class RetrieveMailJob < ApplicationJob
|
6
|
+
def perform
|
7
|
+
klasses = Nuntius::BaseMessageBox.message_box_for(transport: :mail)
|
8
|
+
|
9
|
+
klasses.each do |klass|
|
10
|
+
RetrieveInboundMailService.new(klass.settings).call
|
11
|
+
end
|
12
|
+
|
13
|
+
Nuntius::InboundMessage.where(status: 'pending').each do |message|
|
14
|
+
Nuntius::DeliverInboundMessageJob.perform_later(message)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This job will be called only once for each provider sent out to deliver the job
|
4
|
+
module Nuntius
|
5
|
+
class TransportDeliveryJob < ApplicationJob
|
6
|
+
def perform(provider_name, message)
|
7
|
+
return if message.delivered_or_blocked?
|
8
|
+
return if message.parent_message&.delivered_or_blocked?
|
9
|
+
|
10
|
+
if message.provider != provider_name
|
11
|
+
original_message = message
|
12
|
+
message = message.dup
|
13
|
+
message.parent_message = original_message
|
14
|
+
message.status = 'pending'
|
15
|
+
message.provider_id = ''
|
16
|
+
end
|
17
|
+
message.provider = provider_name
|
18
|
+
message.save!
|
19
|
+
|
20
|
+
provider = Nuntius::BaseProvider.class_from_name(provider_name, message.transport).new(message)
|
21
|
+
message = provider.deliver
|
22
|
+
message.save! unless message.pending?
|
23
|
+
|
24
|
+
# First refresh check is after 5 seconds
|
25
|
+
if message.delivered_or_blocked?
|
26
|
+
message.cleanup!
|
27
|
+
else
|
28
|
+
Nuntius::TransportRefreshJob.set(wait: 5).perform_later(provider_name, message) unless Rails.env.development?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Initializes the appropriate Messenger class and calls the event method
|
4
|
+
module Nuntius
|
5
|
+
class TransportRefreshJob < ApplicationJob
|
6
|
+
def perform(provider_name, message)
|
7
|
+
return if message.delivered_or_blocked? || message.refreshes >= 3
|
8
|
+
|
9
|
+
provider = Nuntius::BaseProvider.class_from_name(provider_name, message.transport).new(message)
|
10
|
+
message = provider.refresh
|
11
|
+
# FIXME: This may need to be more atomic
|
12
|
+
message.refreshes += 1
|
13
|
+
message.save!
|
14
|
+
|
15
|
+
if message.delivered_or_blocked?
|
16
|
+
message.cleanup!
|
17
|
+
else
|
18
|
+
Nuntius::TransportRefreshJob.set(wait: message.refreshes + 5).perform_later(provider_name, message)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nuntius
|
4
|
+
# Message boxes process inbound messages
|
5
|
+
class BaseMessageBox
|
6
|
+
class << self
|
7
|
+
attr_reader :routes
|
8
|
+
|
9
|
+
def provider(value = nil)
|
10
|
+
@provider = value.to_sym if value
|
11
|
+
@provider
|
12
|
+
end
|
13
|
+
|
14
|
+
def transport(value = nil)
|
15
|
+
@transport = value.to_sym if value
|
16
|
+
@transport
|
17
|
+
end
|
18
|
+
|
19
|
+
def route(mapping = nil)
|
20
|
+
@routes ||= {}
|
21
|
+
@routes = @routes.merge(mapping) if mapping.is_a?(Hash)
|
22
|
+
@routes
|
23
|
+
end
|
24
|
+
|
25
|
+
# Defines the settings
|
26
|
+
def settings(hash = {})
|
27
|
+
@settings = hash if hash
|
28
|
+
@settings
|
29
|
+
end
|
30
|
+
|
31
|
+
def deliver(message)
|
32
|
+
klasses = message_box_for(transport: message.transport.to_sym, provider: message.provider.to_sym)
|
33
|
+
klass, method = message_box_for_route(klasses, message.to)
|
34
|
+
|
35
|
+
klass.new(message).send(method) if method
|
36
|
+
end
|
37
|
+
|
38
|
+
def message_box_for(transport: nil, provider: nil)
|
39
|
+
result = descendants
|
40
|
+
result = result.select { |message_box| message_box.transport == transport } if transport
|
41
|
+
result = result.select { |message_box| message_box.provider == provider } if provider
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def mail
|
46
|
+
return nil if transport != 'mail' && provider != 'imap'
|
47
|
+
return @mail if @mail
|
48
|
+
|
49
|
+
@mail = Mail.read(inbound_message.raw_message.download)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def descendants
|
55
|
+
ObjectSpace.each_object(Class).select { |k| k < self }
|
56
|
+
end
|
57
|
+
|
58
|
+
def message_box_for_route(message_boxes, recipients)
|
59
|
+
klass = message_boxes.find do |message_box|
|
60
|
+
routes = (message_box.routes || {})
|
61
|
+
routes.any? { |regexp, _method| [*recipients].any? { |recipient| regexp.match(recipient) } }
|
62
|
+
end
|
63
|
+
method = klass.routes.find { |regexp, _method| [*recipients].any? { |recipient| regexp.match(recipient) } }&.last if klass
|
64
|
+
|
65
|
+
[klass, method] if method
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
attr_reader :message
|
70
|
+
|
71
|
+
def initialize(message)
|
72
|
+
@message = message
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|