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 essas notificações e agir de acordo com elas, fornecendo alertas ou outros mecanismos para os administradores do cliente, por exemplo.
Neste guia, você verá como configurar a infraestrutura do servidor necessária para receber e processar apenas 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 executar outras tarefas de configuração 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 a documentação do Cloud Pub/Sub.
É possível configurar seu sistema para que as notificações push sejam enviadas a um endpoint HTTPS especificado ou a um servidor que aguarde o envio das notificações.
Sobre a configuração de endpoints de push
Para configurar um endpoint de push, é preciso um servidor com um certificado SSL válido. Neste exemplo, você cria e faz upload de um certificado SSL para uma autoridade de certificação (CA, na sigla em inglês) e, em seguida, configura o servidor NGINX. Por fim, compile e execute o código de teste para confirmar se a configuração está correta.
Neste exemplo, mostramos 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 usando o Ubuntu 14.04. Sua empresa pode usar um servidor diferente, mas a configuração de amostra funcionará, sem alterações, em todas as distribuições baseadas no Debian. Outras distribuições (como as baseadas no RedHat) são semelhantes,
mas o local dos arquivos de configuração pode ser diferente.
Antes de receber notificações, configure um endpoint que atenda aos seguintes critérios:
Você precisa ser o proprietário do domínio e confirmar a propriedade no Console de APIs do Google.
É preciso ser capaz de 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 com webhooks.
Seu endpoint não precisa ser executado no Google App Engine (embora seja possível).
Criar e fazer upload de um certificado SSL
1. Produza um certificado Secure Sockets Layer (SSL):
myusername@myhost:/tmp$ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout cert.key -out cert.crt
Isso gera a seguinte resposta. Substitua os valores de amostra (como push.solarmora.com
e myusername@myhost
) pelo nome real do servidor, empresa, endereço e assim por diante no código a seguir. É possível usar qualquer 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 receber esse certificado assinado, produza uma solicitação de assinatura de certificado (CSR, na sigla em inglês) para fazer upload desse certificado ao 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. Certifique-se de que o conteúdo do arquivo CSR seja parecido 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 o upload da parte do certificado entre as linhas BEGIN
e END
(inclusivas) para sua CA. O processo exato dependerá da sua CA, mas incluirá as seguintes etapas:
- Faça upload do arquivo de CSR no site da AC ou cole o conteúdo do arquivo no site da AC. Em seguida, a AC valida e processa esses dados.
- Faça o download do certificado assinado gerado pela CA.
6. A saída da CA precisa conter vários arquivos: o próprio certificado assinado e o certificado da CA confirmando que eles estão qualificados para assinar certificados. Concatene todos os arquivos de certificado *.crt
no pacote
salvo em um único arquivo, por exemplo, bundle.push.solarmora.com.crt
:
$ cat *.crt > bundle.push.solarmora.com.crt
Configurar seu servidor proxy
Nesta seção, você configurará o servidor da Web de código aberto NGINX e o servidor proxy reverso para exibir o endpoint e encaminhar todas as solicitações recebidas para o servidor assinante. O NGINX é usado como exemplo, mas é possível utilizar 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 diretório sites-enabled
sejam 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 de certificado para um local seguro que possa ser lido pelo usuário www-data
, mas preferencialmente não por outros usuários. Talvez seja necessário ajustar o nome do usuário se o servidor da Web estiver sendo executado como um usuário diferente:
$ 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 server
. Edite push.solarmora.com
em /etc/nginx/sites-enabled
e use o nome de domínio totalmente qualificado
do seu servidor real 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. O servidor foi configurado. Para verificar a
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>
Essa é a resposta esperada, já que nenhum servidor downstream foi configurado
(localhost:8093
no arquivo de configuração).
Compilar e executar exemplos
Para executar os exemplos nesta seção, você precisa de um projeto ativo do Console de APIs do Google. Recomendamos que você crie um especificamente para fins de teste e o mantenha 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 no 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 o Maven e o compilador de buffers de protocolo do Google:
$ sudo apt-get install maven protobuf-compiler
3. Verifique se o Maven e o compilador do Google Protocol Buffers estão instalados 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 do Maven pom.xml
pressupõe que o compilador de buffers de protocolo esteja instalado no diretório /usr/bin/protoc
:
myusername@myhost:~$ which protoc /usr/bin/protocSe esse não for o caso, modifique
pom.xml
ou o link simbólico 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 produz 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.jar6. Verifique se é possível 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. É preciso substituir alguns valores no arquivo settings.properties
. Para fazer isso,
crie uma cópia do arquivo e modifique as propriedades na cópia da seguinte maneira:
# 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. Talvez você veja um
único erro na saída do registro.
Executar o código de teste do editor
Execute o exemplo de código para publicar notificações para que seu assinante tenha algumas mensagens para ler.
No exemplo abaixo, o código procura o
tema especificado em my_settings.properties
, mas não o encontra e, portanto, cria o tópico.
Em seguida, publica uma mensagem no tópico. Este exemplo fornece uma ferramenta de
teste valiosa 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 código TestPublisher
.
1. Verifique se o código está atualizado e compilado. Em seguida, execute o código de teste do assinante:
myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.propertiesO assinante está em execução e pronto para aceitar mensagens recebidas.
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" }
2. Execute o editor novamente, e novas mensagens serão adicionadas ao registro:
Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Raw request: {"message":{"data":"CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA",Uma mensagem foi recebida e processada corretamente.
"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 }