Huawei Push Kit

Huawei Push Kit

Huawei Push Kit is a messaging service provided for you. It establishes a messaging channel from the cloud to devices. By integrating Push Kit, you can send messages to your apps on users’ devices in real time.

The Alpakka Huawei Push Kit connector provides a way to send notifications with Huawei Push Kit.

Project Info: Alpakka Huawei Push Kit
Artifact
com.lightbend.akka
akka-stream-alpakka-huawei-push-kit
9.0.0
JDK versions
Eclipse Temurin JDK 11
Eclipse Temurin JDK 17
Scala versions2.13.12
JPMS module nameakka.stream.alpakka.huawei.pushkit
License
Readiness level
Since 3.0.4, 2021-11-25
Home pagehttps://doc.akka.io/libraries/alpakka/current
API documentation
Forums
Release notesGitHub releases
IssuesGithub issues
Sourceshttps://github.com/akka/alpakka

Artifacts

The Akka dependencies are available from Akka’s library repository. To access them there, you need to configure the URL for this repository.

sbt
resolvers += "Akka library repository".at("https://repo.akka.io/maven")
Maven
<project>
  ...
  <repositories>
    <repository>
      <id>akka-repository</id>
      <name>Akka library repository</name>
      <url>https://repo.akka.io/maven</url>
    </repository>
  </repositories>
</project>
Gradle
repositories {
    mavenCentral()
    maven {
        url "https://repo.akka.io/maven"
    }
}

Additionally, add the dependencies as below.

sbt
val AkkaVersion = "2.10.0"
val AkkaHttpVersion = "10.7.0"
libraryDependencies ++= Seq(
  "com.lightbend.akka" %% "akka-stream-alpakka-huawei-push-kit" % "9.0.0",
  "com.typesafe.akka" %% "akka-stream" % AkkaVersion,
  "com.typesafe.akka" %% "akka-http" % AkkaHttpVersion,
  "com.typesafe.akka" %% "akka-http-spray-json" % AkkaHttpVersion
)
Maven
<properties>
  <akka.version>2.10.0</akka.version>
  <akka.http.version>10.7.0</akka.http.version>
  <scala.binary.version>2.13</scala.binary.version>
</properties>
<dependencies>
  <dependency>
    <groupId>com.lightbend.akka</groupId>
    <artifactId>akka-stream-alpakka-huawei-push-kit_${scala.binary.version}</artifactId>
    <version>9.0.0</version>
  </dependency>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-stream_${scala.binary.version}</artifactId>
    <version>${akka.version}</version>
  </dependency>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-http_${scala.binary.version}</artifactId>
    <version>${akka.http.version}</version>
  </dependency>
  <dependency>
    <groupId>com.typesafe.akka</groupId>
    <artifactId>akka-http-spray-json_${scala.binary.version}</artifactId>
    <version>${akka.http.version}</version>
  </dependency>
</dependencies>
Gradle
def versions = [
  AkkaVersion: "2.10.0",
  AkkaHttpVersion: "10.7.0",
  ScalaBinary: "2.13"
]
dependencies {
  implementation "com.lightbend.akka:akka-stream-alpakka-huawei-push-kit_${versions.ScalaBinary}:9.0.0"
  implementation "com.typesafe.akka:akka-stream_${versions.ScalaBinary}:${versions.AkkaVersion}"
  implementation "com.typesafe.akka:akka-http_${versions.ScalaBinary}:${versions.AkkaHttpVersion}"
  implementation "com.typesafe.akka:akka-http-spray-json_${versions.ScalaBinary}:${versions.AkkaHttpVersion}"
}

The table below shows direct dependencies of this module and the second tab shows all libraries it depends on transitively.

Direct dependencies
OrganizationArtifactVersion
com.github.jwt-scalajwt-json-common_2.139.4.6
com.typesafe.akkaakka-http-spray-json_2.1310.7.0
com.typesafe.akkaakka-http_2.1310.7.0
com.typesafe.akkaakka-stream_2.132.10.0
org.scala-langscala-library2.13.12
Dependency tree
com.github.jwt-scala    jwt-json-common_2.13    9.4.6    Apache-2.0
    com.github.jwt-scala    jwt-core_2.13    9.4.6    Apache-2.0
        org.scala-lang    scala-library    2.13.12    Apache-2.0
    org.scala-lang    scala-library    2.13.12    Apache-2.0
com.typesafe.akka    akka-http-spray-json_2.13    10.7.0    BUSL-1.1
    com.typesafe.akka    akka-http_2.13    10.7.0    BUSL-1.1
        com.typesafe.akka    akka-http-core_2.13    10.7.0    BUSL-1.1
            com.typesafe.akka    akka-parsing_2.13    10.7.0    BUSL-1.1
                org.scala-lang    scala-library    2.13.12    Apache-2.0
            org.scala-lang    scala-library    2.13.12    Apache-2.0
        com.typesafe.akka    akka-pki_2.13    2.10.0    BUSL-1.1
            com.hierynomus    asn-one    0.6.0    The Apache License, Version 2.0
            com.typesafe.akka    akka-actor_2.13    2.10.0    BUSL-1.1
                com.typesafe    config    1.4.3    Apache-2.0
                org.scala-lang    scala-library    2.13.12    Apache-2.0
            org.scala-lang    scala-library    2.13.12    Apache-2.0
            org.slf4j    slf4j-api    2.0.16
        org.scala-lang    scala-library    2.13.12    Apache-2.0
    io.spray    spray-json_2.13    1.3.6    Apache 2
        org.scala-lang    scala-library    2.13.12    Apache-2.0
    org.scala-lang    scala-library    2.13.12    Apache-2.0
com.typesafe.akka    akka-http_2.13    10.7.0    BUSL-1.1
    com.typesafe.akka    akka-http-core_2.13    10.7.0    BUSL-1.1
        com.typesafe.akka    akka-parsing_2.13    10.7.0    BUSL-1.1
            org.scala-lang    scala-library    2.13.12    Apache-2.0
        org.scala-lang    scala-library    2.13.12    Apache-2.0
    com.typesafe.akka    akka-pki_2.13    2.10.0    BUSL-1.1
        com.hierynomus    asn-one    0.6.0    The Apache License, Version 2.0
        com.typesafe.akka    akka-actor_2.13    2.10.0    BUSL-1.1
            com.typesafe    config    1.4.3    Apache-2.0
            org.scala-lang    scala-library    2.13.12    Apache-2.0
        org.scala-lang    scala-library    2.13.12    Apache-2.0
        org.slf4j    slf4j-api    2.0.16
    org.scala-lang    scala-library    2.13.12    Apache-2.0
com.typesafe.akka    akka-stream_2.13    2.10.0    BUSL-1.1
    com.typesafe.akka    akka-actor_2.13    2.10.0    BUSL-1.1
        com.typesafe    config    1.4.3    Apache-2.0
        org.scala-lang    scala-library    2.13.12    Apache-2.0
    com.typesafe.akka    akka-protobuf-v3_2.13    2.10.0    BUSL-1.1
    org.reactivestreams    reactive-streams    1.0.4    MIT-0
    org.scala-lang    scala-library    2.13.12    Apache-2.0
org.scala-lang    scala-library    2.13.12    Apache-2.0

Settings

All of the configuration settings for Huawei Push Kit can be found in the reference.conf.

sourcealpakka.huawei.pushkit {
  app-id: "105260069"
  app-secret: "a192c0f08d03216b0f03b946918d5c725bbf54264a434227928c612012eefd24"
}

The test and maxConcurrentConnections parameters in HmsSettings are the predefined values. You can send test notifications (so called validate only). And you can set the number of maximum concurrent connections.

Sending notifications

To send a notification message create your notification object, and send it!

Scala
sourceimport akka.stream.alpakka.huawei.pushkit._
import akka.stream.alpakka.huawei.pushkit.scaladsl.HmsPushKit
import akka.stream.alpakka.huawei.pushkit.models.AndroidConfig
import akka.stream.alpakka.huawei.pushkit.models.AndroidNotification
import akka.stream.alpakka.huawei.pushkit.models.BasicNotification
import akka.stream.alpakka.huawei.pushkit.models.ClickAction
import akka.stream.alpakka.huawei.pushkit.models.Condition
import akka.stream.alpakka.huawei.pushkit.models.ErrorResponse
import akka.stream.alpakka.huawei.pushkit.models.PushKitNotification
import akka.stream.alpakka.huawei.pushkit.models.PushKitResponse
import akka.stream.alpakka.huawei.pushkit.models.Response
import akka.stream.alpakka.huawei.pushkit.models.Tokens

val result1: Future[immutable.Seq[Response]] =
  Source
    .single(notification)
    .via(HmsPushKit.send(config))
    .map {
      case res @ PushKitResponse(code, msg, requestId) =>
        println(s"Response $res")
        res
      case res @ ErrorResponse(errorMessage) =>
        println(s"Send error $res")
        res
    }
    .runWith(Sink.seq)
Java
sourceimport akka.stream.alpakka.huawei.pushkit.*;
import akka.stream.alpakka.huawei.pushkit.javadsl.HmsPushKit;
import akka.stream.alpakka.huawei.pushkit.models.AndroidConfig;
import akka.stream.alpakka.huawei.pushkit.models.AndroidNotification;
import akka.stream.alpakka.huawei.pushkit.models.BasicNotification;
import akka.stream.alpakka.huawei.pushkit.models.ClickAction;
import akka.stream.alpakka.huawei.pushkit.models.ErrorResponse;
import akka.stream.alpakka.huawei.pushkit.models.PushKitNotification;
import akka.stream.alpakka.huawei.pushkit.models.PushKitResponse;
import akka.stream.alpakka.huawei.pushkit.models.Response;
import akka.stream.alpakka.huawei.pushkit.models.Tokens;

CompletionStage<List<Response>> result =
    Source.single(notification)
        .via(HmsPushKit.send(config))
        .map(
            res -> {
              if (!res.isFailure()) {
                PushKitResponse response = (PushKitResponse) res;
                System.out.println("Response " + response);
              } else {
                ErrorResponse response = (ErrorResponse) res;
                System.out.println("Send error " + response);
              }
              return res;
            })
        .runWith(Sink.seq(), system);

With this type of send you can get responses from the server. These responses can be PushKitResponse or ErrorResponse. You can choose what you want to do with this information, but keep in mind if you try to resend the failed messages you will need to use exponential backoff! (see @extref[Akka docs RestartFlow.onFailuresWithBackoff)

If you don’t care if the notification was sent successfully, you may use fireAndForget.

Scala
sourceimport akka.stream.alpakka.huawei.pushkit._
import akka.stream.alpakka.huawei.pushkit.scaladsl.HmsPushKit
import akka.stream.alpakka.huawei.pushkit.models.AndroidConfig
import akka.stream.alpakka.huawei.pushkit.models.AndroidNotification
import akka.stream.alpakka.huawei.pushkit.models.BasicNotification
import akka.stream.alpakka.huawei.pushkit.models.ClickAction
import akka.stream.alpakka.huawei.pushkit.models.Condition
import akka.stream.alpakka.huawei.pushkit.models.ErrorResponse
import akka.stream.alpakka.huawei.pushkit.models.PushKitNotification
import akka.stream.alpakka.huawei.pushkit.models.PushKitResponse
import akka.stream.alpakka.huawei.pushkit.models.Response
import akka.stream.alpakka.huawei.pushkit.models.Tokens

val config = HmsSettings()
val notification: PushKitNotification =
  PushKitNotification.empty
    .withNotification(
      BasicNotification.empty
        .withTitle("title")
        .withBody("body")
    )
    .withAndroidConfig(
      AndroidConfig.empty
        .withNotification(
          AndroidNotification.empty
            .withClickAction(
              ClickAction.empty
                .withType(3)
            )
        )
    )
    .withTarget(Tokens(Set[String]("token").toSeq))

Source
  .single(notification)
  .runWith(HmsPushKit.fireAndForget(config))
Java
sourceimport akka.stream.alpakka.huawei.pushkit.*;
import akka.stream.alpakka.huawei.pushkit.javadsl.HmsPushKit;
import akka.stream.alpakka.huawei.pushkit.models.AndroidConfig;
import akka.stream.alpakka.huawei.pushkit.models.AndroidNotification;
import akka.stream.alpakka.huawei.pushkit.models.BasicNotification;
import akka.stream.alpakka.huawei.pushkit.models.ClickAction;
import akka.stream.alpakka.huawei.pushkit.models.ErrorResponse;
import akka.stream.alpakka.huawei.pushkit.models.PushKitNotification;
import akka.stream.alpakka.huawei.pushkit.models.PushKitResponse;
import akka.stream.alpakka.huawei.pushkit.models.Response;
import akka.stream.alpakka.huawei.pushkit.models.Tokens;

HmsSettings config = HmsSettings.create(system);
PushKitNotification notification =
    PushKitNotification.fromJava()
        .withNotification(BasicNotification.fromJava().withTitle("title").withBody("body"))
        .withAndroidConfig(
            AndroidConfig.fromJava()
                .withNotification(
                    AndroidNotification.fromJava()
                        .withClickAction(ClickAction.fromJava().withType(3))))
        .withTarget(new Tokens(new Set.Set1<>("token").toSeq()));

Source.single(notification).runWith(HmsPushKit.fireAndForget(config), system);

With fire and forget you will just send messages and ignore all the errors.

To help the integration and error handling or logging, there is a variation of the flow where you can send data beside your notification.

Scala only

You can build notification described in the original documentation. It can be done by hand, or using some builder method. See an example of the condition builder below.

Scala
sourceimport akka.stream.alpakka.huawei.pushkit.models.Condition.{Topic => CTopic}
val condition = Condition(CTopic("TopicA") && (CTopic("TopicB") || (CTopic("TopicC") && !CTopic("TopicD"))))
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.