Skip to content

Commit 3cd904d

Browse files
committed
expo_push_tokens model and creation api #1
1 parent 9d49fd4 commit 3cd904d

File tree

12 files changed

+215
-0
lines changed

12 files changed

+215
-0
lines changed

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gem "exponent-server-sdk"
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class ExpoPushTokensController < ApplicationController
2+
before_action :require_login
3+
accept_api_auth :create
4+
5+
def create
6+
@token = ExpoPushToken.new user: User.current, token: params[:token]
7+
if @token.save
8+
respond_to do |format|
9+
format.api { head :created }
10+
end
11+
else
12+
respond_to do |format|
13+
format.api { render_validation_errors(@token) }
14+
end
15+
end
16+
end
17+
end

app/models/expo_push_token.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class ExpoPushToken < ActiveRecord::Base
2+
belongs_to :user
3+
4+
validates_presence_of :token
5+
validates_presence_of :user
6+
end
7+

config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
resources :expo_push_tokens, only: %i(create)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class CreateExpoPushTokens < ActiveRecord::Migration[5.2]
2+
def change
3+
create_table :expo_push_tokens do |t|
4+
t.references :user, foreign_key: true
5+
t.string :token, null: false
6+
end
7+
end
8+
end

init.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
require 'redmine'
2+
3+
Rails.configuration.to_prepare do
4+
RedmineExpoPush.setup
5+
end
6+
7+
Redmine::Plugin.register :redmine_expo_push do
8+
name 'Redmine Expo Push Notifications Plugin'
9+
author 'Jens Krämer, Georepublic'
10+
author_url 'https://hub.georepublic.net/gtt/redmine_expo_push'
11+
description 'Notify mobile app users through push notifications'
12+
version '1.0.0'
13+
14+
requires_redmine version_or_higher: '3.4.0'
15+
16+
#settings default: {
17+
#}, partial: 'redmine_text_blocks/settings'
18+
19+
# project_module :text_blocks do
20+
#
21+
# permission :view_text_blocks, {}, require: :member, read: true
22+
# permission :manage_text_blocks, {
23+
# text_blocks: %i( new edit update create destroy ),
24+
# projects: %i( manage_text_blocks )
25+
# }, require: :member
26+
# end
27+
28+
# menu :admin_menu, :text_blocks,
29+
# { controller: 'text_blocks', action: 'index' },
30+
# caption: :label_text_block_plural, :html => {:class => 'icon'}
31+
32+
end
33+

lib/redmine_expo_push.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module RedmineExpoPush
2+
def self.setup
3+
# RedmineExpoPush::Patches::MailerPatch.apply
4+
RedmineExpoPush::Patches::UserPatch.apply
5+
end
6+
end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module RedmineExpoPush
2+
class Notification
3+
def initialize(title: nil, body: nil, data: {})
4+
@title = title
5+
@body = body
6+
@data = data
7+
@recipients = []
8+
end
9+
10+
def add_recipient(user)
11+
@recipients << user
12+
end
13+
14+
# https://docs.expo.io/versions/latest/guides/push-notifications/
15+
# https://github.com/expo/expo-server-sdk-ruby
16+
# https://docs.expo.io/versions/latest/guides/push-notifications/#message-format
17+
def deliver
18+
messages = @recipients.map do |user|
19+
ExpoPushToken.where(user: user).map do |token|
20+
{
21+
to: token,
22+
title: @title,
23+
body: @body,
24+
data: @data
25+
}
26+
end
27+
end
28+
messages.flatten!
29+
30+
Exponent::Push::Client.new(gzip: true).publish messages
31+
end
32+
end
33+
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
module RedmineExpoPush
2+
module Patches
3+
# this is a draft, just in case we want to add general push notification
4+
# support for all redmine notifications
5+
module MailerPatch
6+
7+
def self.apply
8+
Mailer.class_eval do
9+
class << self
10+
prepend ClassMethods
11+
end
12+
end
13+
end
14+
15+
module ClassMethods
16+
17+
def deliver_mail(mail, &block)
18+
if perform_deliveries
19+
notification = nil
20+
%i(to cc bcc).each do |field|
21+
receivers = Array(mail.send(field)).flatten.compact
22+
skip_receivers = []
23+
receivers.each do |addr|
24+
user = User.having_mail(addr).first
25+
if user.present?
26+
cfg = RedmineExpoPush::UserConfig.new(user)
27+
if cfg.send_push_notifications?
28+
notification ||= Notification.new(mail)
29+
notification.add_recipient user
30+
skip_receivers << addr if cfg.skip_emails?
31+
end
32+
end
33+
end
34+
mail.send "#{field}=", (receivers - skip_receivers)
35+
end
36+
notification.deliver if notification
37+
end
38+
39+
super
40+
end
41+
42+
end
43+
44+
end
45+
end
46+
end
47+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module RedmineExpoPush
2+
module Patches
3+
module UserPatch
4+
def self.apply
5+
User.prepend self unless User < self
6+
end
7+
8+
def remove_references_before_destroy
9+
super
10+
if self.id
11+
ExpoPushToken.where(user_id: id).delete_all
12+
end
13+
end
14+
end
15+
end
16+
end

0 commit comments

Comments
 (0)