Google Play genera notificaciones en respuesta a eventos que ocurren y pueden afectar a una empresa. Los proveedores de soluciones de EMM pueden recibir estas notificaciones y tomar medidas sobre ellas; por ejemplo, proporcionan alertas o, también, otros mecanismos para sus administradores de clientes.
En esta guía, se explica cómo configurar la infraestructura del servidor necesaria para recibir y procesar solo notificaciones push de EMM. Las notificaciones de extracción no requieren la configuración que se detalla en esta guía.
Además de la configuración del servidor descrita en esta guía, para las notificaciones push debes otorgar los privilegios adecuados y realizar otras tareas de configuración en la Consola de API de Google. Consulta Habilita notificaciones push de EMM para obtener más detalles.
Para obtener más información sobre Google Cloud Pub/Sub, incluidos ejemplos, consulta la documentación de Cloud Pub/Sub.
Puedes configurar el sistema para que las notificaciones push se envíen a un extremo HTTPS especificado o a un servidor que espere a que se envíen las notificaciones.
Acerca de la configuración de extremos de envío
Para configurar un extremo de envío, necesitas un servidor con un certificado SSL válido. En este ejemplo, crearás y subirás un certificado SSL a una autoridad certificadora (CA) y, luego, configurarás el servidor de NGINX. Por último, compilas y ejecutas el código de prueba para confirmar que tu configuración es correcta.
En este ejemplo, se muestra cómo configurar un servidor NGINX en modo proxy inverso para conectarse a la app de suscriptor (en PushSubscriber.java
) que se ejecuta en el puerto 8093 mediante Ubuntu 14.04. Es posible que tu empresa use un servidor diferente, pero la configuración de muestra debería funcionar, sin cambios, en todas las distribuciones basadas en Debian. Otras distribuciones (como las basadas en Red Hat) son similares, pero la ubicación de los archivos de configuración puede ser diferente.
Antes de poder recibir notificaciones, debes configurar un extremo que cumpla con los siguientes criterios:
Debes ser propietario del dominio y verificar la propiedad en la Consola de API de Google.
Debes poder ejecutar un servicio en el puerto 443 (SSL).
Debes tener un certificado SSL firmado por una CA. Los certificados autofirmados no funcionan.
El servidor web que ejecutas debe admitir webhooks.
No es necesario que el extremo se ejecute en Google App Engine (aunque puede hacerlo).
Crea y sube un certificado SSL
1. Genera un certificado de capa de conexión segura (SSL):
myusername@myhost:/tmp$ sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 -keyout cert.key -out cert.crt
Esto genera la siguiente respuesta. Reemplaza los valores de muestra (como push.solarmora.com
y myusername@myhost
) por el nombre real del servidor, la empresa, la dirección, etc., en el siguiente código. Puedes usar cualquier subdominio, siempre y cuando el registro A
de este subdominio apunte a tu 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. Verifica que se haya creado un archivo de certificado:
$ myusername@myhost:/tmp$ ls cert*
cert.crt cert.key
3. Para obtener este certificado firmado, produce una solicitud de firma de certificado (CSR) para subir a tu firmante:
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. Asegúrate de que el contenido del archivo CSR tenga el siguiente aspecto:
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. Sube la parte del certificado entre las líneas BEGIN
y END
(inclusive) a tu CA. El proceso exacto dependerá de tu AC, pero incluirá los siguientes pasos:
- Sube el archivo CSR a tu sitio de CA o pega el contenido del archivo en el sitio de CA. Luego, la AC valida y procesa estos datos.
- Descarga el certificado firmado que generó tu AC.
6. El resultado de la AC debe contener varios archivos: el certificado firmado y el certificado de la AC que confirma que son aptos para firmar certificados. Concatena todos los archivos de certificados *.crt
en el paquete descargado en un solo archivo de paquete, por ejemplo, bundle.push.solarmora.com.crt
:
$ cat *.crt > bundle.push.solarmora.com.crt
Configura tu servidor proxy
En esta sección, configurarás el servidor web de código abierto de NGINX y el servidor proxy inverso para entregar al extremo y reenviar todas las solicitudes entrantes al servidor suscriptor. NGINX se usa como ejemplo, pero puedes usar cualquier otro proxy HTTP en su lugar.
1. Instala NGINX en tu servidor:
$ sudo apt-get update $ sudo apt-get install nginx $ nginx -v $ nginx version: nginx/1.4.6 (Ubuntu)
2. Para asegurarte de que NGINX procese los archivos de configuración adicionales del servidor que creas en el directorio sites-enabled
, edita /etc/nginx/nginx.conf
y, luego, incluye lo siguiente:
$ include /etc/nginx/conf.d/*.conf; $ include /etc/nginx/sites-enabled/*;
3. Copia los archivos de certificado en una ubicación segura que el usuario www-data
pueda leer, pero preferentemente que no lo pueda leer ningún otro usuario (es posible que debas ajustar el nombre de usuario si tu servidor web se ejecuta como un usuario 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. Crea una nueva configuración de server
. Edita push.solarmora.com
en /etc/nginx/sites-enabled
y usa el nombre de dominio completamente calificado de tu servidor real como nombre de archivo:
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. Reinicia NGINX para implementar los cambios:
myusername@myhost:/etc/nginx$ sudo service nginx restart * Restarting nginx nginx ...done.
6. Tu servidor ya está configurado. Para verificar la configuración, intenta consultar tu servidor mediante 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 es la respuesta esperada, ya que no se configuró ningún servidor descendente (localhost:8093
en nuestro archivo de configuración).
Ejemplos de compilación y ejecución
Para ejecutar los ejemplos de esta sección, necesitas un proyecto activo de la Consola de API de Google. Te recomendamos que crees una específicamente para realizar pruebas y la mantengas separado de tu proyecto de producción. Después de crear un proyecto de prueba, debes crear una cuenta de servicio. Toma nota de la dirección de correo electrónico de la cuenta de servicio y coloca el archivo .p12 asociado en alguna parte de tu servidor.
Cómo configurar el árbol del código fuente
1. Clona el repositorio 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. En los sistemas basados en Debian, instala Maven y el compilador de búferes de protocolo de Google:
$ sudo apt-get install maven protobuf-compiler
3. Verifica que Maven y el compilador de búferes de protocolo de Google estén instalados correctamente:
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. En el archivo de configuración de Maven pom.xml
, se supone que el compilador de búferes de protocolo está instalado en el directorio /usr/bin/protoc
:
myusername@myhost:~$ which protoc /usr/bin/protocSi este no es el caso, puedes modificar
pom.xml
o symlink protoc
:
$ sudo ln -s which protoc
/usr/bin/protoc
5. Compila los ejemplos. Ejecuta mvn clean compile assembly:single
para verificar que puedes compilar el código. Esto debería producir un archivo llamado emm-notifications-[version-number]-jar-with-dependencies.jar
, en el que [version number]
es la versión actual del ejemplo, por ejemplo, 1.0-SNAPSHOT
:myusername@myhost:~/code/play-work/examples/emm-notifications$ ls target/* target/emm-notifications-1.0-SNAPSHOT-jar-with-dependencies.jar.6. Verifica que puedas ejecutar el código
TestPublisher
compilado. Se espera que el código falle:
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. Debes anular algunos valores en el archivo settings.properties
. Para ello, crea una copia del archivo y modifica las propiedades en ella de la siguiente manera:
# 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. Vuelve a ejecutar el código TestPublisher
para asegurarte de que ya no falle. (es posible que veas un solo error en el resultado del registro).
Ejecuta el código de prueba del publicador
Debes ejecutar el código de muestra para publicar notificaciones de modo que tu suscriptor tenga algunos mensajes que leer.
En el siguiente ejemplo, el código busca el tema especificado en my_settings.properties
, pero no lo encuentra y, por lo tanto, crea el tema.
Luego, publica un mensaje en el tema. En este ejemplo, se proporciona una herramienta de pruebas valiosa que te permite emular los mensajes que envía la API de EMM de Google Play.
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}]}
Ejecuta el código de prueba del suscriptor
El código de prueba del suscriptor confirma que puedes recibir los mensajes publicados por el código TestPublisher
.
1. Asegúrate de que tu código esté actualizado y compilado. Luego, ejecuta el código de prueba del suscriptor:
myusername@myhost:~/code/play-work/examples/emm-notifications$ DEVELOPER_CONSOLE_SETTINGS=./my_settings.propertiesEl suscriptor ya se está ejecutando y está listo para aceptar mensajes entrantes.
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. Vuelve a ejecutar el publicador y se agregarán los mensajes nuevos al registro:
Feb 27, 2015 1:47:24 PM com.google.android.work.emmnotifications.PushSubscriber$1 handle INFO: Raw request: {"message":{"data":"CjEKFQoIMTIzMjEzMjESCXJpZ2h0IG5vdxIWY29tLmdvb2dsZS5hbmRyb2lkLmdtcxgA",Se recibió y procesó un mensaje de forma correcta.
"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 }