Configurar o servidor para notificações push

O Google Play gera notificações em resposta a eventos que ocorrem e podem afetar uma empresa. os provedores de soluções de EMM podem receber notificações e agir em relação a elas, fornecendo alertas ou outros mecanismos para para administradores do cliente, por exemplo.

Neste guia, vamos mostrar como configurar a infraestrutura de servidor necessária receber e processar somente notificações push de EMM. As notificações pull não exigem a configuração detalhada neste guia.

Além da configuração do servidor descrita neste guia, para notificações push você também precisa conceder os privilégios apropriados e realizar outras de tarefas no Console de APIs do Google. Consulte Ativar notificações push de EMM para mais detalhes.

Para mais informações sobre o Google Cloud Pub/Sub, incluindo exemplos, consulte Documentação do Cloud Pub/Sub.

Você pode configurar seu sistema para que as notificações push sejam enviadas para um endpoint HTTPS especificado ou para um servidor que aguarda o envio das notificações.

Sobre a configuração de endpoint de push

Para configurar um endpoint de push, você precisa de um servidor com um certificado SSL válido. Em Neste exemplo, você cria e faz upload de um certificado SSL para uma autoridade certificadora (CA) e configure o servidor NGINX. Por fim, você compila e executa o código de teste para confirme se a configuração está correta.

Este exemplo mostra como configurar um Servidor NGINX no modo de proxy reverso para se conectar ao app do assinante (em PushSubscriber.java) em execução na porta 8093 com o Ubuntu 14.04. Sua empresa pode usar uma mas a configuração de exemplo deve funcionar, sem alterações, em todos os servidores distribuições de dados. Outras distribuições (como as baseadas na RedHat) são semelhantes, mas o local dos arquivos de configuração pode ser diferente.

Antes de poder receber notificações, você precisa configurar um endpoint que atende aos seguintes critérios:

  • Você precisa ser o proprietário do domínio e confirmar a propriedade no Console de APIs do Google.

  • Você precisa conseguir executar um serviço na porta 443 (SSL).

  • Você precisa ter um certificado SSL assinado pela CA. Os certificados autoassinados não funcionam.

  • O servidor da Web que você está executando precisa ser compatível webhooks.

Seu endpoint não precisa ser executado no Google App Engine (embora isso seja possível).

Criar e fazer upload de um certificado SSL

1. Produza um certificado SSL (Secure Sockets Layer):

    myusername@myhost:/tmp$ sudo openssl req -x509 -nodes -days 365 \
      -newkey rsa:2048 -keyout cert.key -out cert.crt

Isso gera a resposta a seguir. Substituir os valores de amostra (como push.solarmora.com e myusername@myhost) pelo servidor real nome, empresa, endereço e assim por diante, no código a seguir. Você pode usar qualquer um subdomínio, desde que o registro A desse subdomínio aponte para seu servidor.

    Generating a 2048 bit RSA private key
    ...........................................................................
    .....+++
    writing new private key to 'cert.key'
    -----
    You are about to be asked to enter information that will be incorporated
    into your certificate request.
    What you are about to enter is what is called a Distinguished Name or a DN.
    There are quite a few fields but you can leave some blank
    For some fields there will be a default value,
    If you enter '.', the field will be left blank.
    -----
    Country Name (2 letter code) [AU]:GB
    State or Province Name (full name) [Some-State]:England
    Locality Name (eg, city) []:London
    Organization Name (eg, company) [Internet Widgits Pty Ltd]:Solarmora, Inc.
    Organizational Unit Name (eg, section) []:Creative Publications
    Common Name (e.g. server FQDN or YOUR name) []:push.solarmora.com
    Email Address []:admin@solarmora.com

2. Verifique se um arquivo de certificado foi criado:

$ myusername@myhost:/tmp$ ls cert*
cert.crt  cert.key

3. Para conseguir esse certificado assinado, gere uma solicitação de assinatura de certificado (CSR, na sigla em inglês) para fazer o upload para o signatário:

myusername@myhost:/tmp$ sudo openssl x509 -x509toreq -in cert.crt \
  -out cert.csr -signkey cert.key
Getting request Private Key
Generating certificate request
myusername@myhost:/tmp$ ls cert.*
cert.crt  cert.csr  cert.key

4. Verifique se o conteúdo do arquivo CSR se parece com este:

    Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: C=GB, ST=England, L=London, O=Solarmora, Inc.,
        OU=Creative Publications,
        CN=push.solarmora.com/emailAddress=admin@solarmora.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cc:0f:54:26:3d:d9:17:eb:8f:6c:f7:27:5e:77:
                    64:65:00:db:fe:2a:1f:fa:ea:de:21:7a:c5:5d:87:
                    ...
                    ...
                Exponent: 65537 (0x10001)
        Attributes:
            a0:00
    Signature Algorithm: sha256WithRSAEncryption
         1d:ea:12:b8:c2:6a:d6:f4:6e:92:2f:b9:12:5e:e3:91:15:a0:
         06:b5:81:ce:c5:cf:b7:d2:a7:dd:f2:78:ca:28:8e:21:cd:6d:
         ...
         ...
    -----BEGIN CERTIFICATE REQUEST-----
    MIIC6zCCAdMCAQAwgaUxCzAJBgNVBAYTAkdCMRAwDgYDVQQIDAdFbmdsYW5kMQ8w
    DQYDVQQHDAZMb25kb24xGDAWBgNVBAoMD0FDTUUgQ29ycCwgSW5jLjEYMBYGA1UE
    CwwPQ3JlYXRpdmUgQW52aWxzMRswGQYDVQQDDBJwdXNoLmFjbWUtY29ycC5jb20x
    IjAgBgkqhkiG9w0BCQEWE2FkbWluQGFjbWUtY29ycC5jb20wggEiMA0GCSqGSIb3
    ...
    ...
    -----END CERTIFICATE REQUEST-----

5. Faça upload da parte do certificado entre BEGIN e END (inclusive) para sua CA. O processo exato dependem da sua AC, mas inclui as seguintes etapas:

  1. Faça upload do arquivo de CSR para o site da CA ou cole o conteúdo do arquivo no site da CA. Em seguida, sua CA valida e processa esses dados.
  2. Faça o download do certificado assinado gerado pela CA.

6. A saída da AC deve conter vários arquivos: o arquivo certificado em si e o certificado da CA confirmando que eles estão qualificados para assinar certificados. Concatenar todos os arquivos de certificado *.crt na agrupar em um único arquivo de pacote, por exemplo, bundle.push.solarmora.com.crt:

$ cat *.crt > bundle.push.solarmora.com.crt

Configurar seu servidor proxy

Nesta seção, você vai configurar o servidor da Web de código aberto NGINX e reverter servidor proxy para servir o endpoint e encaminhar todas as solicitações recebidas para o no servidor do assinante. O NGINX é usado como exemplo, mas é possível usar qualquer outro proxy HTTP.

1. Instale o NGINX no seu servidor:

    $ sudo apt-get update
    $ sudo apt-get install nginx
    $ nginx -v
    $ nginx version: nginx/1.4.6 (Ubuntu)

2. Para garantir que os arquivos extras de configuração do servidor criados no sites-enabled são processados pelo NGINX, edite /etc/nginx/nginx.conf e inclua o seguinte:

    $ include /etc/nginx/conf.d/*.conf;
    $ include /etc/nginx/sites-enabled/*;

3. Copie os arquivos do certificado para um local seguro, legível pelo www-data usuário, mas de preferência não legível por nenhum outro usuário (pode ser necessário para ajustar o nome de usuário caso seu servidor da Web seja executado como um servidor usuário):

    $ sudo mkdir -p /var/openssl/push.solarmora.com
    $ sudo mv /tmp/cert.key 
/var/openssl/push.solarmora.com/push.solarmora.com.key $ sudo mv /tmp/bundle.push.solarmora.com.crt
/var/openssl/push.solarmora.com/bundle.push.solarmora.com.crt

4. Crie uma nova configuração de server. Editar push.solarmora.com em /etc/nginx/sites-enabled e usar seu nome de domínio totalmente qualificado do servidor como o nome do arquivo:

server {
   listen 443;
   server_name push.solarmora.com;

   ssl on;
   ssl_certificate
     /var/openssl/push.solarmora.com/bundle.push.solarmora.com.crt;
   ssl_certificate_key
     /var/openssl/push.solarmora.com/push.solarmora.com.key;

   # it is usually very convenient to have separate files for your
   # access and error log to analyze for possible problems
   access_log /var/log/nginx/nginx.push.solarmora.com.log;
   error_log /var/log/nginx/nginx.push.solarmora.com.log;

   location / {
            # assuming the subscriber will run on the same machine
            # on port 8093
            proxy_pass http://localhost:8093;
   }
}

5. Reinicie o NGINX para implementar as alterações:

    myusername@myhost:/etc/nginx$ sudo service nginx restart
    * Restarting nginx nginx
    ...done.

6. Seu servidor está configurado. Para verificar configuração, tente consultar seu servidor usando curl:

    [myusername@myhost:~]$ curl push.solarmora.com
    <html>
    <head><title>502 Bad Gateway</title></head>
    <body bgcolor="white">
    <center><h1>502 Bad Gateway</h1></center>
    <hr><center>nginx/1.4.6 (Ubuntu)</center>
    </body>
    </html>

Esta é a resposta esperada, já que nenhum servidor downstream foi configurado (localhost:8093 em nosso arquivo de configuração).

Exemplos de compilação e execução

Para executar os exemplos desta seção, você precisa de um Console de APIs do Google ativo. em um projeto de IA. Recomendamos que você crie uma para fins de teste e mantenha-o separado do seu projeto de produção. Depois de criar um projeto de teste, você precisa criar uma conta de serviço. Anote o endereço de e-mail da conta de serviço e coloque o arquivo .p12 associado em algum lugar do seu servidor.

Configurar a árvore de código-fonte

1. Clone o repositório play-work.git:

    myusername@myhost:~/code$ git clone
    https://github.com/google/play-work.git
    Cloning into 'play-work'...
    Username for 'https://github.com': username
    Password for 'https://username@github.com':
    remote: Counting objects: 110, done.
    remote: Compressing objects: 100% (60/60), done.
    remote: Total 110 (delta 24), reused 95 (delta 9), pack-reused 0
    Receiving objects: 100% (110/110), 23.88 KiB | 0 bytes/s, done.
    Resolving deltas: 100% (24/24), done.
    Checking connectivity... done.
2: Em sistemas baseados em Debian, instale os Maven e as Compilador de buffers de protocolo do Google:
    $ sudo apt-get install maven protobuf-compiler

3. Verifique se o Maven e o compilador de Buffers de protocolo do Google estão instalado corretamente:

    myusername@myhost:~$ mvn -v
    Apache Maven 3.0.5
    Maven home: /usr/share/maven
    Java version: 1.7.0_75, vendor: Oracle Corporation
    Java home: /usr/lib/jvm/java-7-openjdk-amd64/jre
    Default locale: en_US, platform encoding: UTF-8
    OS name: "linux", version: "3.16.0-30-generic", arch: "amd64", family: "unix"
    myusername@myhost:~$ protoc --version
    libprotoc 2.5.0

4. O arquivo de configuração pom.xml do Maven presume que o compilador dos Buffers de protocolo está instalado no diretório /usr/bin/protoc:

    myusername@myhost:~$ which protoc
    /usr/bin/protoc
Se esse não for o caso, modifique pom.xml ou envie um link simbólico para protoc:
    $ sudo ln -s which protoc /usr/bin/protoc
5) Compile os exemplos. Verifique se é possível criar o código executando mvn clean compile assembly:single. Isso produzirá um arquivo chamado emm-notifications-[version-number]-jar-with-dependencies.jar, em que [version number] é a versão atual do exemplo, por exemplo, 1.0-SNAPSHOT:
    myusername@myhost:~/code/play-work/examples/emm-notifications$ ls target/*
    target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar
6. Verifique se você pode executar o código TestPublisher compilado. Espera-se que o código falhe:

    myusername@myhost:~/code/play-work/examples/emm-notifications$ java -cp \
      target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar \
      com.google.android.work.emmnotifications.TestPublisher
    Exception in thread "main" java.lang.IllegalArgumentException:
    You must specify non-default ServiceAccountEmail in
    settings.properties
        at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:119)
        at com.google.api.client.util.Preconditions.checkArgument(Preconditions.java:69)
        at com.google.android.work.emmnotifications.Settings.verifyVariable(Settings.java:129)
        at com.google.android.work.emmnotifications.Settings.getSettings(Settings.java:103)
        at com.google.android.work.emmnotifications.TestPublisher.main(TestPublisher.java:39)

7. Você precisa substituir alguns valores no arquivo settings.properties. Para isso, crie uma cópia do arquivo e modifique as propriedades na cópia da seguinte forma:

    # This should be your own service account's email address
    ServiceAccountEmail=368628613713-t4hfexampledn5lhpdcu1qqfgio01626@developer.gserviceaccount.com
    ServiceAccountP12KeyFile=/opt/secret/secret.p12
    # This will be the name of the service account
    ProjectName=enterprise-cloud-pub-sub
    SubscriptionName=projects/enterprise-cloud-pub-sub/subscriptions/default
    TopicName=projects/enterprise-cloud-pub-sub/topics/default
    # The push endpoint in your API Console project
    PushEndpoint=https://push.solarmora.com

8. Execute o código TestPublisher novamente para garantir que ele não falhe mais. Você pode ver um erro único na saída do registro.)

Executar o código de teste do editor

É necessário executar o exemplo de código para publicar notificações para que seu o assinante tem algumas mensagens para ler.

No exemplo a seguir, o código procura a especificado em my_settings.properties, mas não o encontra e, portanto, cria o tópico. Em seguida, ele publica uma mensagem no tópico. Esse exemplo mostra uma ótima ferramenta de testes que permite emular mensagens enviadas pela API Google Play EMM.

    myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.properties java -cp \
      target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar com.google.android.work.emmnotifications.TestPublisher
    Feb 27, 2015 1:39:59 PM com.google.android.work.emmnotifications.RetryHttpInitializerWrapper$1 handleResponse
    INFO: RetryHandler: {
      "error": {
        "code": 404,
        "message": "Resource not found (resource=default).",
        "errors": [
          {
            "message": "Resource not found (resource=default).",
            "domain": "global",
            "reason": "notFound"
          }
        ],
        "status": "NOT_FOUND"
      }
    }

    Feb 27, 2015 1:39:59 PM com.google.android.work.emmnotifications.TestPublisher main
    INFO: Topic projects/enterprise-cloud-pub-sub/topics/default doesn't exists, creating it
    Feb 27, 2015 1:40:02 PM com.google.android.work.emmnotifications.TestPublisher main
    INFO: Topic projects/enterprise-cloud-pub-sub/topics/default created
    Feb 27, 2015 1:40:02 PM com.google.android.work.emmnotifications.TestPublisher main
    INFO: Publishing a request: {messages=[{data=CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA}]}

Executar o código de teste do assinante

O código de teste do assinante confirma que você pode receber as mensagens publicadas pelo o código TestPublisher.

1. Certifique-se de que seu código esteja atualizado e compilado e execute o código de teste do assinante:

    myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.properties 
java -cp target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar
com.google.android.work.emmnotifications.PushSubscriber Feb 27, 2015 1:46:37 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Will be using topic name: projects/enterprise-cloud-pub-sub/topics/default, subscription name:
projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Trying to get subscription named projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.RetryHttpInitializerWrapper$1 handleResponse INFO: RetryHandler: { "error": { "code": 404, "message": "Resource not found (resource=default).", "errors": [ { "message": "Resource not found (resource=default).", "domain": "global", "reason": "notFound" } ], "status": "NOT_FOUND" } } Feb 27, 2015 1:46:38 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Subscription doesn't exist, will try to create projects/enterprise-cloud-pub-sub/subscriptions/default Feb 27, 2015 1:46:43 PM com.google.android.work.emmnotifications.PushSubscriber main INFO: Created: { "ackDeadlineSeconds" : 600, "name" : "projects/enterprise-cloud-pub-sub/subscriptions/default", "pushConfig" : { "pushEndpoint" : "https://push.solarmora.com" }, "topic" : "projects/enterprise-cloud-pub-sub/topics/default" }
Agora o assinante está em execução e pronto para aceitar os e-mails recebidos. e envio de mensagens.

2. Execute o editor novamente, e novas mensagens serão adicionado ao registro:

    Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle
    INFO: Raw request: {"message":{"data":"CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA",
"attributes":{},"message_id":"71571141246"},"subscription":"/subscriptions/enterprise-cloud-pub-sub/default"} Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Pubsub message received: { "attributes" : { }, "data" : "CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA", "message_id" : "71571141246" } Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Message received: product_approval_event { common_event_information { enterprise_id: "12321321" event_notification_sent_timestamp: "right now" } product_id: "com.google.android.gms" approved: false }
Uma mensagem foi recebida e processada corretamente.