mirror of
https://github.com/mattermost/mattermost.git
synced 2025-02-25 18:55:24 -06:00
PLT-902 switching to push proxy server
This commit is contained in:
16
api/post.go
16
api/post.go
@@ -536,7 +536,7 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
l4g.Error("Failed to send mention email successfully email=%v err=%v", profileMap[id].Email, err)
|
||||
}
|
||||
|
||||
if len(utils.Cfg.EmailSettings.ApplePushServer) > 0 {
|
||||
if *utils.Cfg.EmailSettings.SendPushNotifications {
|
||||
sessionChan := Srv.Store.Session().GetSessions(id)
|
||||
if result := <-sessionChan; result.Err != nil {
|
||||
l4g.Error("Failed to retrieve sessions in notifications id=%v, err=%v", id, result.Err)
|
||||
@@ -548,7 +548,19 @@ func sendNotificationsAndForget(c *Context, post *model.Post, team *model.Team,
|
||||
if len(session.DeviceId) > 0 && alreadySeen[session.DeviceId] == "" && strings.HasPrefix(session.DeviceId, "apple:") {
|
||||
alreadySeen[session.DeviceId] = session.DeviceId
|
||||
|
||||
utils.SendAppleNotifyAndForget(strings.TrimPrefix(session.DeviceId, "apple:"), subjectPage.Render(), 1)
|
||||
msg := model.PushNotification{}
|
||||
msg.Platform = model.PUSH_NOTIFY_APPLE
|
||||
msg.Message = subjectPage.Render()
|
||||
msg.Badge = 1
|
||||
msg.DeviceId = strings.TrimPrefix(session.DeviceId, "apple:")
|
||||
msg.ServerId = utils.CfgDiagnosticId
|
||||
|
||||
httpClient := http.Client{}
|
||||
request, _ := http.NewRequest("POST", *utils.Cfg.EmailSettings.PushNotificationServer+"/api/v1/send_push", strings.NewReader(msg.ToJson()))
|
||||
|
||||
if _, err := httpClient.Do(request); err != nil {
|
||||
l4g.Error("Failed to send push notificationid=%v, err=%v", id, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,9 +68,8 @@
|
||||
"ConnectionSecurity": "",
|
||||
"InviteSalt": "bjlSR4QqkXFBr7TP4oDzlfZmcNuH9YoS",
|
||||
"PasswordResetSalt": "vZ4DcKyVVRlKHHJpexcuXzojkE5PZ5eL",
|
||||
"ApplePushServer": "",
|
||||
"ApplePushCertPublic": "",
|
||||
"ApplePushCertPrivate": ""
|
||||
"SendPushNotifications": true,
|
||||
"PushNotificationServer": "https://push.mattermost.com"
|
||||
},
|
||||
"RateLimitSettings": {
|
||||
"EnableRateLimiter": true,
|
||||
|
||||
@@ -68,6 +68,7 @@ func main() {
|
||||
manualtesting.InitManualTesting()
|
||||
}
|
||||
|
||||
setDiagnosticId()
|
||||
runSecurityAndDiagnosticsJobAndForget()
|
||||
|
||||
// wait for kill signal before attempting to gracefully shutdown
|
||||
@@ -80,6 +81,21 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func setDiagnosticId() {
|
||||
if result := <-api.Srv.Store.System().Get(); result.Err == nil {
|
||||
props := result.Data.(model.StringMap)
|
||||
|
||||
id := props[model.SYSTEM_DIAGNOSTIC_ID]
|
||||
if len(id) == 0 {
|
||||
id = model.NewId()
|
||||
systemId := &model.System{Name: model.SYSTEM_DIAGNOSTIC_ID, Value: id}
|
||||
<-api.Srv.Store.System().Save(systemId)
|
||||
}
|
||||
|
||||
utils.CfgDiagnosticId = id
|
||||
}
|
||||
}
|
||||
|
||||
func runSecurityAndDiagnosticsJobAndForget() {
|
||||
go func() {
|
||||
for {
|
||||
@@ -92,15 +108,9 @@ func runSecurityAndDiagnosticsJobAndForget() {
|
||||
if (currentTime - lastSecurityTime) > 1000*60*60*24*1 {
|
||||
l4g.Debug("Checking for security update from Mattermost")
|
||||
|
||||
id := props[model.SYSTEM_DIAGNOSTIC_ID]
|
||||
if len(id) == 0 {
|
||||
id = model.NewId()
|
||||
systemId := &model.System{Name: model.SYSTEM_DIAGNOSTIC_ID, Value: id}
|
||||
<-api.Srv.Store.System().Save(systemId)
|
||||
}
|
||||
|
||||
v := url.Values{}
|
||||
v.Set(utils.PROP_DIAGNOSTIC_ID, id)
|
||||
|
||||
v.Set(utils.PROP_DIAGNOSTIC_ID, utils.CfgDiagnosticId)
|
||||
v.Set(utils.PROP_DIAGNOSTIC_BUILD, model.CurrentVersion+"."+model.BuildNumber)
|
||||
v.Set(utils.PROP_DIAGNOSTIC_DATABASE, utils.Cfg.SqlSettings.DriverName)
|
||||
v.Set(utils.PROP_DIAGNOSTIC_OS, runtime.GOOS)
|
||||
|
||||
@@ -96,11 +96,8 @@ type EmailSettings struct {
|
||||
ConnectionSecurity string
|
||||
InviteSalt string
|
||||
PasswordResetSalt string
|
||||
|
||||
// For Future Use
|
||||
ApplePushServer string
|
||||
ApplePushCertPublic string
|
||||
ApplePushCertPrivate string
|
||||
SendPushNotifications *bool
|
||||
PushNotificationServer *string
|
||||
}
|
||||
|
||||
type RateLimitSettings struct {
|
||||
@@ -181,6 +178,17 @@ func (o *Config) SetDefaults() {
|
||||
o.TeamSettings.EnableTeamListing = new(bool)
|
||||
*o.TeamSettings.EnableTeamListing = false
|
||||
}
|
||||
|
||||
if o.EmailSettings.SendPushNotifications == nil {
|
||||
o.EmailSettings.SendPushNotifications = new(bool)
|
||||
*o.EmailSettings.SendPushNotifications = true
|
||||
}
|
||||
|
||||
if o.EmailSettings.PushNotificationServer == nil {
|
||||
o.EmailSettings.PushNotificationServer = new(string)
|
||||
*o.EmailSettings.PushNotificationServer = "https://push.mattermost.com"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (o *Config) IsValid() *AppError {
|
||||
|
||||
45
model/push_notification.go
Normal file
45
model/push_notification.go
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
PUSH_NOTIFY_APPLE = "apple"
|
||||
PUSH_NOTIFY_ANDROID = "android"
|
||||
)
|
||||
|
||||
type PushNotification struct {
|
||||
Platform string `json:"platform"`
|
||||
ServerId string `json:"server_id"`
|
||||
DeviceId string `json:"device_id"`
|
||||
Category string `json:"category"`
|
||||
Sound string `json:"sound"`
|
||||
Message string `json:"message"`
|
||||
Badge int `json:"badge"`
|
||||
ContentAvailable int `json:"cont_ava"`
|
||||
}
|
||||
|
||||
func (me *PushNotification) ToJson() string {
|
||||
b, err := json.Marshal(me)
|
||||
if err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return string(b)
|
||||
}
|
||||
}
|
||||
|
||||
func PushNotificationFromJson(data io.Reader) *PushNotification {
|
||||
decoder := json.NewDecoder(data)
|
||||
var me PushNotification
|
||||
err := decoder.Decode(&me)
|
||||
if err == nil {
|
||||
return &me
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
19
model/push_notification_test.go
Normal file
19
model/push_notification_test.go
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestPushNotification(t *testing.T) {
|
||||
msg := PushNotification{Platform: "test"}
|
||||
json := msg.ToJson()
|
||||
result := PushNotificationFromJson(strings.NewReader(json))
|
||||
|
||||
if msg.Platform != result.Platform {
|
||||
t.Fatal("Ids do not match")
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
|
||||
// See License.txt for license information.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
l4g "code.google.com/p/log4go"
|
||||
"fmt"
|
||||
"github.com/anachronistic/apns"
|
||||
"github.com/mattermost/platform/model"
|
||||
)
|
||||
|
||||
func SendAppleNotifyAndForget(deviceId string, message string, badge int) {
|
||||
go func() {
|
||||
if err := SendAppleNotify(deviceId, message, badge); err != nil {
|
||||
l4g.Error(fmt.Sprintf("%v %v", err.Message, err.DetailedError))
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func SendAppleNotify(deviceId string, message string, badge int) *model.AppError {
|
||||
payload := apns.NewPayload()
|
||||
payload.Alert = message
|
||||
payload.Badge = 1
|
||||
|
||||
pn := apns.NewPushNotification()
|
||||
pn.DeviceToken = deviceId
|
||||
pn.AddPayload(payload)
|
||||
client := apns.BareClient(Cfg.EmailSettings.ApplePushServer, Cfg.EmailSettings.ApplePushCertPublic, Cfg.EmailSettings.ApplePushCertPrivate)
|
||||
resp := client.Send(pn)
|
||||
|
||||
if resp.Error != nil {
|
||||
return model.NewAppError("", "Could not send apple push notification", fmt.Sprintf("id=%v err=%v", deviceId, resp.Error))
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ const (
|
||||
)
|
||||
|
||||
var Cfg *model.Config = &model.Config{}
|
||||
var CfgDiagnosticId = ""
|
||||
var CfgLastModified int64 = 0
|
||||
var CfgFileName string = ""
|
||||
var ClientCfg map[string]string = map[string]string{}
|
||||
|
||||
@@ -18,6 +18,7 @@ export default class EmailSettings extends React.Component {
|
||||
|
||||
this.state = {
|
||||
sendEmailNotifications: this.props.config.EmailSettings.SendEmailNotifications,
|
||||
sendPushNotifications: this.props.config.EmailSettings.SendPushNotifications,
|
||||
saveNeeded: false,
|
||||
serverError: null,
|
||||
emailSuccess: null,
|
||||
@@ -36,6 +37,14 @@ export default class EmailSettings extends React.Component {
|
||||
s.sendEmailNotifications = false;
|
||||
}
|
||||
|
||||
if (action === 'sendPushNotifications_true') {
|
||||
s.sendPushNotifications = true;
|
||||
}
|
||||
|
||||
if (action === 'sendPushNotifications_false') {
|
||||
s.sendPushNotifications = false;
|
||||
}
|
||||
|
||||
this.setState(s);
|
||||
}
|
||||
|
||||
@@ -43,11 +52,12 @@ export default class EmailSettings extends React.Component {
|
||||
var config = this.props.config;
|
||||
config.EmailSettings.EnableSignUpWithEmail = ReactDOM.findDOMNode(this.refs.allowSignUpWithEmail).checked;
|
||||
config.EmailSettings.SendEmailNotifications = ReactDOM.findDOMNode(this.refs.sendEmailNotifications).checked;
|
||||
config.EmailSettings.SendPushlNotifications = ReactDOM.findDOMNode(this.refs.sendPushNotifications).checked;
|
||||
config.EmailSettings.RequireEmailVerification = ReactDOM.findDOMNode(this.refs.requireEmailVerification).checked;
|
||||
config.EmailSettings.SendEmailNotifications = ReactDOM.findDOMNode(this.refs.sendEmailNotifications).checked;
|
||||
config.EmailSettings.FeedbackName = ReactDOM.findDOMNode(this.refs.feedbackName).value.trim();
|
||||
config.EmailSettings.FeedbackEmail = ReactDOM.findDOMNode(this.refs.feedbackEmail).value.trim();
|
||||
config.EmailSettings.SMTPServer = ReactDOM.findDOMNode(this.refs.SMTPServer).value.trim();
|
||||
config.EmailSettings.PushNotificationServer = ReactDOM.findDOMNode(this.refs.PushNotificationServer).value.trim();
|
||||
config.EmailSettings.SMTPPort = ReactDOM.findDOMNode(this.refs.SMTPPort).value.trim();
|
||||
config.EmailSettings.SMTPUsername = ReactDOM.findDOMNode(this.refs.SMTPUsername).value.trim();
|
||||
config.EmailSettings.SMTPPassword = ReactDOM.findDOMNode(this.refs.SMTPPassword).value.trim();
|
||||
@@ -525,6 +535,61 @@ export default class EmailSettings extends React.Component {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
htmlFor='sendPushNotifications'
|
||||
>
|
||||
{'Send Push Notifications: '}
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<label className='radio-inline'>
|
||||
<input
|
||||
type='radio'
|
||||
name='sendPushNotifications'
|
||||
value='true'
|
||||
ref='sendPushNotifications'
|
||||
defaultChecked={this.props.config.EmailSettings.SendPushNotifications}
|
||||
onChange={this.handleChange.bind(this, 'sendPushNotifications_true')}
|
||||
/>
|
||||
{'true'}
|
||||
</label>
|
||||
<label className='radio-inline'>
|
||||
<input
|
||||
type='radio'
|
||||
name='sendPushNotifications'
|
||||
value='false'
|
||||
defaultChecked={!this.props.config.EmailSettings.SendPushNotifications}
|
||||
onChange={this.handleChange.bind(this, 'sendPushNotifications_false')}
|
||||
/>
|
||||
{'false'}
|
||||
</label>
|
||||
<p className='help-text'>{'Typically set to true in production. When true, Mattermost attempts to send iOS and Android push notifications through the push notification server.'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='form-group'>
|
||||
<label
|
||||
className='control-label col-sm-4'
|
||||
htmlFor='PushNotificationServer'
|
||||
>
|
||||
{'Push Notification Server:'}
|
||||
</label>
|
||||
<div className='col-sm-8'>
|
||||
<input
|
||||
type='text'
|
||||
className='form-control'
|
||||
id='PushNotificationServer'
|
||||
ref='PushNotificationServer'
|
||||
placeholder='E.g.: "https://push.mattermost.com"'
|
||||
defaultValue={this.props.config.EmailSettings.PushNotificationServer}
|
||||
onChange={this.handleChange}
|
||||
disabled={!this.state.sendPushNotifications}
|
||||
/>
|
||||
<p className='help-text'>{'Location of the push notification server.'}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='form-group'>
|
||||
<div className='col-sm-12'>
|
||||
{serverError}
|
||||
|
||||
Reference in New Issue
Block a user