implement mobile notification push to aerogear

This commit is contained in:
Thibault Duplessis 2015-12-10 21:42:56 +07:00
parent 5d40dd3121
commit 5737efbc57
7 changed files with 96 additions and 17 deletions

View file

@ -78,7 +78,8 @@ final class Env(
Env.blog,
Env.video,
Env.shutup, // required to load the actor
Env.insight // required to load the actor
Env.insight, // required to load the actor
Env.push // required to load the actor
)
play.api.Logger("boot").info("Preloading complete")
}

View file

@ -156,9 +156,4 @@ object Account extends LilaController {
else
lila.security.Store.closeUserAndSessionId(me.id, sessionId)
}
def registerDeviceId(id: String) = Auth { implicit ctx =>
me =>
Env.push.deviceApi.register(me, id)
}
}

View file

@ -75,7 +75,6 @@ POST /account/kidConfirm controllers.Account.kidConfirm
GET /account/security controllers.Account.security
POST /account/signout/:sessionId controllers.Account.signout(sessionId: String)
GET /account/info controllers.Account.info
POST /account/register-device-id/:id controllers.Account.registerDeviceId(id: String)
# Site
GET /socket controllers.Main.websocket

View file

@ -2,15 +2,45 @@ package lila.push
import lila.user.User
final class Aerogear(config: Aerogear.Config) {
import play.api.libs.json._
import play.api.libs.ws.{ WS, WSAuthScheme }
import play.api.Play.current
def register(user: User, deviceId: String): Funit = ???
// https://aerogear.org/docs/specs/aerogear-unifiedpush-rest/index.html#397083935
private final class Aerogear(config: Aerogear.Config) {
import Aerogear._
def push(p: Push): Funit = WS.url(s"${config.url}/rest/sender")
.withAuth(config.applicationId, config.masterSecret, WSAuthScheme.BASIC)
.post(Json.obj(
"message" -> p
)).flatMap {
case res if res.status == 200 => funit
case res => fufail(s"[push] $p ${res.status} ${res.body}")
}
}
private object Aerogear {
case class Push(
userId: String,
alert: String,
sound: String, // ???
userData: JsObject)
private implicit val pushWrites: OWrites[Push] = OWrites { p =>
Json.obj(
"alert" -> p.alert,
"sound" -> p.sound,
"user-data" -> p.userData
)
}
case class Config(
url: String,
variantId: String,
secret: String)
secret: String,
applicationId: String,
masterSecret: String)
}

View file

@ -1,21 +1,40 @@
package lila.push
import com.typesafe.config.Config
import akka.actor._
import lila.common.PimpedConfig._
final class Env(config: Config) {
final class Env(
config: Config,
system: ActorSystem) {
private val AerogearConfig = Aerogear.Config(
url = config getString "aerogear.url",
variantId = config getString "aerogear.variant_id",
secret = config getString "aerogear.secret")
private val AerogearConfig = Aerogear.Config(
url = config getString "aerogear.url",
variantId = config getString "aerogear.variant_id",
secret = config getString "aerogear.secret",
applicationId = config getString "aerogear.application_id",
masterSecret = config getString "aerogear.master_secret")
lazy val aerogear = new Aerogear(AerogearConfig)
private lazy val aerogear = new Aerogear(AerogearConfig)
private lazy val api = new PushApi(aerogear)
system.actorOf(Props(new Actor {
override def preStart() {
system.lilaBus.subscribe(self, 'finishGame, 'moveEvent)
}
import akka.pattern.pipe
def receive = {
case lila.game.actorApi.FinishGame(game, _, _) => api finish game
case move: lila.hub.actorApi.round.MoveEvent => api move move
}
}))
}
object Env {
lazy val current: Env = "push" boot new Env(
system = lila.common.PlayApp.system,
config = lila.common.PlayApp loadConfig "push")
}

View file

@ -0,0 +1,35 @@
package lila.push
import lila.game.{ Game, GameRepo, Pov }
import lila.hub.actorApi.round.MoveEvent
import lila.user.User
import play.api.libs.json._
// https://aerogear.org/docs/specs/aerogear-unifiedpush-rest/index.html#397083935
private final class PushApi(aerogear: Aerogear) {
def finish(game: Game): Funit = ???
def move(move: MoveEvent): Funit = move.opponentUserId ?? { userId =>
GameRepo game move.gameId flatMap {
case Some(game) if filter(game) =>
Pov.ofUserId(game, userId) ?? { pov =>
aerogear push Aerogear.Push(
userId = userId,
alert = "It's your turn!",
sound = "default",
userData = Json.obj(
"gameId" -> game.id,
"color" -> pov.color.name,
"fen" -> move.fen,
"move" -> move.move)
)
}
case _ => funit
}
}
private def filter(game: Game) =
game.isCorrespondence && game.playable && game.nonAi
}

View file

@ -221,7 +221,7 @@ object ApplicationBuild extends Build {
libraryDependencies ++= provided(play.api, RM, PRM)
)
lazy val push = project("push", Seq(common, db, user)).settings(
lazy val push = project("push", Seq(common, db, user, game)).settings(
libraryDependencies ++= provided(play.api, RM, PRM)
)