En este tutorial te enseñaremos los pasos para hacer que una aplicación desarrollada en Laravel funcione como receptor de las notificaciones por parte de SNS.

Suscripción a los topics (temas) de SNS/AWS con Laravel

Ahora trabajaremos con la aplicación receptor, también creada en Laravel.

  1. Debemos crear la ruta donde estaremos recibiendo las notificaciones por parte de SNS.
Route::get('/sns-notifications', function () {
    //code
});
  1. Nos dirigimos a la sección AWS/Topics y entramos a la descripción del topic creado previamente: styde-topic-updates

Una vez estemos en esta sección, debemos dar clic en crear una suscripción para poder registrar el enlace de nuestra página.

Aquí es donde vendrá nuestro primer problema, si estamos haciendo pruebas en nuestro entorno local no podremos registrar la url de nuestra computadora. Esto lo podemos solucionar usando ngrok, este software nos ayudará a crear un túnel entre nuestra aplicación local y los servidores de ngrok lo que permitirá que podamos hacer nuestras pruebas sin problemas.

Configuración de ngrok

  • Si estás usando docker-compose, la siguiente configuración te ayudará, solo debes agregarla al archivo docker-compose.yml e inicializar la variable NGROK_AUTH con el token que se te proveerá al suscribirte a ngrok en el archivo .env.
ngrok:
 container_name: ngrok
 ports:
   - "4040:4040"
 image: wernight/ngrok
 links:
   - "nginx"
 environment:
   - NGROK_AUTH=${NGROK_AUTH}
   - NGROK_REGION=us
   - NGROK_PORT=nginx:80
  • Debes acceder a http://localhost:4040/inspect/http y verás dos enlaces que fueron generados, tomaremos el que tiene protocolo https y lo usaremos para registrarlo en el topic de SNS. Este enlace apunta a nuestro http://localhost.

  1. Nuestro enlace completo quedará de la siguiente manera: https://ba4e6c4e.ngrok.io/sns-notification, aquí es donde recibiremos nuestras notificaciones.
  2.  Antes de ir a registrar nuestro enlace, debes saber que SNS espera una respuesta de confirmación por parte de nuestro servidor y como verás en la documentación de AWS, es un poco engorroso, por eso mismo el equipo de AWS desarrolló un paquete para poder confirmar la suscripción de forma sencilla. Lo instalaremos de la siguiente manera:
composer require aws/aws-php-sns-message-validator
  1. Debemos colocar el código de confirmación en nuestra ruta. Con esto, podremos hacer una llamada de regreso hacia AWS. Para hacer el request nos apoyaremos de la clase Client de Guzzle:
Route::get('/sns-notifications', function () {
   $client = new \GuzzleHttp\Client();
   // Instantiate the Message and Validator
   $message = Message::fromRawPostData();
   $validator = new MessageValidator();

   // Validate the message and log errors if invalid.
   try {
       $validator->validate($message);
   } catch (\Aws\Sns\Exception\InvalidSnsMessageException $e) {
       // Pretend we're not here if the message is invalid.
       throw $e;
   }

   \Illuminate\Support\Facades\Log::info($message);

   // Check the type of the message and handle the subscription.
   if ($message['Type'] === 'SubscriptionConfirmation') {
       // Confirm the subscription by sending a GET request to the SubscribeURL
       return $client->get($message['SubscribeURL']);
   }
});
  1. Una vez hecho esto, vamos a nuestro topic, registramos la url de nuestra aplicación y presionamos create subscription.

Aquí debemos sustituir http://localhost por el nuevo dominio que nos ha creado ngrok

Agrega la ruta en la variable except del middleware VerifyCsrfToken para evitar CSRF verification (error 419).

Si todo sale bien, al dirigirnos a la descripción de nuestro topic, deberíamos ver nuestra suscripción con el status confirmed.

Leyendo Mensaje

  1. Borraremos el código de confirmación, ya que en esa misma url es donde estarán llegando los mensajes desde el SNS.
  2. Agregamos el siguiente código (en él podrás ver un ejemplo de cómo obtener la información que contiene el mensaje):
Route::post('/sns-notifications', function (Request $request) {
   $message = json_decode($request->getContent(), true);
   $data = json_decode(data_get($message, 'MessageAttributes.Information.Value'), true);
  
   if ($data['status'] === 'updated') {
       \Log::info('Actualizando Nicho');
   } elseif ($message['status'] === 'deleted') {
       \Log::info('Borrando Nicho');
   }
});
  1. Accedemos al enlace http://localhost/send-notification que desarrollamos en el tutorial anterior, lo que nos ayudará a publicar un nuevo mensaje en SNS.
  2. Después de acceder a la ruta deberíamos ver un nuevo mensaje en nuestra queue, así como el siguiente Log:

Imprimirá:

[2020-05-04 18:18:36] local.INFO: array (
  'nicho' => 'mexicans',
  'id' => '123456',
  'status' => 'updated',
)  
[2020-05-04 18:18:36] local.INFO: Actualizando Nicho

Listo, con esto concluimos los pasos para publicar y recibir mensajes con SNS y Laravel.

 

Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.