class ApplicationPush < ActionPush::Base
default :ios do |ios|
ios.thread_id = 'fuck'
ios.badge = 10
end
end
class UserPush < ApplicationPush
default :ios do |ios|
ios.alert do |a|
a.launch_image = 'user.png'
end
end
def welcome
# envelope#title and #body set corresponding
# attributes for all registered providers like ios and android
envelope.title = 'hello'
envelope.body = 'world'
envelope.payload = { user_id: 1 }
envelope.for(:ios) do |ios|
ios.thread_id = 123
end
# push method sets #scheduled = true to the message,
# so this pushes will be delivered when you call a
# class method: `UserPush.welcome`
push :ios, token: 'foo'
push :android, token: 'bar'
end
def buy
push :ios, token: 'foo' do |ios|
# translations are available under the key:
# en.user_push.buy.title
#
# You can set I18n scope by redefining i18n_scope method:
#
# def i18n_scope
# "self.class.to_s.underscore}.#{action_name}"
# end
ios.title = t('.title')
# you can redefine scheduling in a block
ios.scheduled = false
end
push :android do |android|
android.token = 'foo'
android.title = t('.title')
end
end
end
Using with Sidekiq
# enable delay extension at `config/initializers/sidekiq.rb`
Sidekiq::Extensions.enable_delay!
@user = User.last
UserPush.delay_for(4.seconds).welcome(@user.id)
Configuration
gorush = ActionPush::Delivery::Gorush.new(
url: 'http://localhost:8088/api/push',
topic: 'com.app.id',
logger: STDOUT
)
ActionPush::Base.register_delivery_method :ios, ->(push) do
gorush.send_to_apple(push)
end
Testing
# spec/support/action_push.rb
ActionPush::Base.register_delivery_method :ios, ActionPush::Delivery::Memory
RSpec.configure do |config|
config.before(:each) do
ActionPush::Delivery::Memory.clear
end
end
# app/models/user.rb
class User < ApplicationRecord
def confirm
update!(confirmed_at: Time.current)
UserPush.welcome(id)
end
end
# app/pushes/user_push.rb
class UserPush < ApplicationPush
def welcome(id)
user = User.find(id)
envelope.title = 'Welcome push'
envelope.body = 'Glad to see you'
push :ios, token: user.ios_push_token
end
end
# spec/models/user_spec.rb
RSpec.describe User do
let(:user) do
create :user
end
it 'sends a push' do
expect { user.confirm }.to change { ActionPush::Delivery::Memory.size }.by(1)
expect(ActionPush::Delivery::Memory.last).to have_attributes(title: 'Welcome push', body: 'Glad to see you', token: user.ios_push_token)
end
end
Interceptor
# config/initializers/action_push.rb
ActionPush::Base.register_interceptor = ->(instance, provider, _push, &block) do
Logger.info <<~DOC
Sending a push "#{instance.class}.#{instance.action} to #{provider}"
DOC
block.call
end
Реализация провайдера
Можно легко реализовать функционал нового провайдера для, скажем, отправки уведомлений в браузер пользователя через WebSocket.
В этом примере провайдером будет выступать nchan
class WebsocketMessage < ActionPush::Provider::Base
attr_accessor :chanel, :payload
end
class ApplicationPush < ActionPush::Base
register_default :socket, WebsocketMessage.new
end
class FollowRequestPush < ApplicationPush
def notify(user_id)
user = User.find(user_id)
push :socket, chanel: "pub/#{user.id}", payload: { title: t('.title') }
end
end
# config/initializers/action_push
ApplicationPush.register_delivery_method :socket, ->(push) do
`curl http://nchan:8080/#{push.chanel} -X POST --data='#{push.payload.to_json}'`
end
Теперь вы можете слать уведомления прямо в браузер пользователя:
FollowRequestPush.notify(1)