mirror of
https://github.com/christianselig/apollo-backend
synced 2024-11-25 21:27:42 +00:00
add test notification endpoint
This commit is contained in:
parent
1249f54bf2
commit
0d296a672e
4 changed files with 84 additions and 1 deletions
1
go.mod
1
go.mod
|
@ -7,6 +7,7 @@ require (
|
||||||
github.com/DataDog/datadog-go v4.8.1+incompatible
|
github.com/DataDog/datadog-go v4.8.1+incompatible
|
||||||
github.com/Microsoft/go-winio v0.5.0 // indirect
|
github.com/Microsoft/go-winio v0.5.0 // indirect
|
||||||
github.com/adjust/rmq/v4 v4.0.1
|
github.com/adjust/rmq/v4 v4.0.1
|
||||||
|
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||||
github.com/go-co-op/gocron v1.6.2
|
github.com/go-co-op/gocron v1.6.2
|
||||||
github.com/go-redis/redis/v8 v8.11.0
|
github.com/go-redis/redis/v8 v8.11.0
|
||||||
github.com/heroku/x v0.0.31
|
github.com/heroku/x v0.0.31
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -112,6 +112,8 @@ github.com/dgryski/go-metro v0.0.0-20180109044635-280f6062b5bc/go.mod h1:c9O8+fp
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
|
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"github.com/DataDog/datadog-go/statsd"
|
"github.com/DataDog/datadog-go/statsd"
|
||||||
"github.com/jackc/pgx/v4/pgxpool"
|
"github.com/jackc/pgx/v4/pgxpool"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
|
"github.com/sideshow/apns2/token"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/christianselig/apollo-backend/internal/data"
|
"github.com/christianselig/apollo-backend/internal/data"
|
||||||
|
@ -21,6 +22,7 @@ type api struct {
|
||||||
db *pgxpool.Pool
|
db *pgxpool.Pool
|
||||||
reddit *reddit.Client
|
reddit *reddit.Client
|
||||||
models *data.Models
|
models *data.Models
|
||||||
|
apns *token.Token
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAPI(ctx context.Context, logger *logrus.Logger, statsd *statsd.Client, db *pgxpool.Pool) *api {
|
func NewAPI(ctx context.Context, logger *logrus.Logger, statsd *statsd.Client, db *pgxpool.Pool) *api {
|
||||||
|
@ -31,9 +33,23 @@ func NewAPI(ctx context.Context, logger *logrus.Logger, statsd *statsd.Client, d
|
||||||
16,
|
16,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var apns *token.Token
|
||||||
|
{
|
||||||
|
authKey, err := token.AuthKeyFromFile(os.Getenv("APPLE_KEY_PATH"))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
apns = &token.Token{
|
||||||
|
AuthKey: authKey,
|
||||||
|
KeyID: os.Getenv("APPLE_KEY_ID"),
|
||||||
|
TeamID: os.Getenv("APPLE_TEAM_ID"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
models := data.NewModels(ctx, db)
|
models := data.NewModels(ctx, db)
|
||||||
|
|
||||||
return &api{logger, statsd, db, reddit, models}
|
return &api{logger, statsd, db, reddit, models, apns}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *api) Server(port int) *http.Server {
|
func (a *api) Server(port int) *http.Server {
|
||||||
|
@ -49,6 +65,7 @@ func (a *api) Routes() *httprouter.Router {
|
||||||
router.GET("/v1/health", a.healthCheckHandler)
|
router.GET("/v1/health", a.healthCheckHandler)
|
||||||
|
|
||||||
router.POST("/v1/device", a.upsertDeviceHandler)
|
router.POST("/v1/device", a.upsertDeviceHandler)
|
||||||
|
router.POST("/v1/device/test", a.testDeviceHandler)
|
||||||
router.POST("/v1/device/:apns/account", a.upsertAccountHandler)
|
router.POST("/v1/device/:apns/account", a.upsertAccountHandler)
|
||||||
|
|
||||||
return router
|
return router
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/dustin/go-humanize/english"
|
||||||
"github.com/julienschmidt/httprouter"
|
"github.com/julienschmidt/httprouter"
|
||||||
|
"github.com/sideshow/apns2"
|
||||||
|
"github.com/sideshow/apns2/payload"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/christianselig/apollo-backend/internal/data"
|
"github.com/christianselig/apollo-backend/internal/data"
|
||||||
)
|
)
|
||||||
|
@ -23,3 +29,60 @@ func (a *api) upsertDeviceHandler(w http.ResponseWriter, r *http.Request, _ http
|
||||||
|
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *api) testDeviceHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
d, err := a.models.Devices.GetByAPNSToken(ps.ByName("apns"))
|
||||||
|
if err != nil {
|
||||||
|
a.logger.WithFields(logrus.Fields{
|
||||||
|
"err": err,
|
||||||
|
}).Info("failed fetching device from database")
|
||||||
|
a.errorResponse(w, r, 500, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt := `
|
||||||
|
SELECT username
|
||||||
|
FROM accounts
|
||||||
|
INNER JOIN devices_accounts ON devices.account_id = accounts.id
|
||||||
|
WHERE devices_accounts.device = $1`
|
||||||
|
rows, err := a.db.Query(ctx, stmt, d.ID)
|
||||||
|
if err != nil {
|
||||||
|
a.logger.WithFields(logrus.Fields{
|
||||||
|
"apns": ps.ByName("apns"),
|
||||||
|
"err": err,
|
||||||
|
}).Error("failed to fetch device accounts")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
var users []string
|
||||||
|
for rows.Next() {
|
||||||
|
var user string
|
||||||
|
rows.Scan(&user)
|
||||||
|
users = append(users, user)
|
||||||
|
}
|
||||||
|
|
||||||
|
body := fmt.Sprintf("Active usernames are: %s", english.OxfordWordSeries(users, "and"))
|
||||||
|
notification := &apns2.Notification{}
|
||||||
|
notification.Topic = "com.christianselig.Apollo"
|
||||||
|
notification.Payload = payload.
|
||||||
|
NewPayload().
|
||||||
|
Category("test-notification").
|
||||||
|
AlertBody(body)
|
||||||
|
|
||||||
|
client := apns2.NewTokenClient(a.apns)
|
||||||
|
if !d.Sandbox {
|
||||||
|
client = client.Production()
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := client.Push(notification); err != nil {
|
||||||
|
a.logger.WithFields(logrus.Fields{
|
||||||
|
"err": err,
|
||||||
|
}).Info("failed to send test notification")
|
||||||
|
a.errorResponse(w, r, 500, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue