Email

Applet de lista de distribución de código abierto usando el SDK de PHP de Mailgun

Este artículo fue escrito por Jeff Reifman, un consultor tecnológico con sede en Seattle y fundador de Geogram, un servicio de envío de emails grupal gratuito para lugares locales impulsado por Mailgun. Síguelo en @reifman.
Imagen para Applet de lista de distribución de código abierto usando el SDK de PHP de Mailgun

Este artículo fue escrito por Jeff Reifman, un consultor tecnológico  con sede en Seattle y fundador de Geogram, un servicio de envío de emails grupal gratuito para lugares locales impulsado por Mailgun. Síguelo en @reifman.

Introducción a las listas de Mailgun

Aunque Mailgun se conoce principalmente como un motor de email escalable basado en la nube, su función de listas de distribución ofrece una forma fácil y cómoda de gestionar listas y enviar mensajes de difusión a múltiples destinatarios. Puedes enviar mensajes a las listas de distribución de Mailgun a través de tu proveedor de email web favorito, cliente de email, teléfono inteligente o mediante la API. Además, Mailgun ofrece API para gestionar y enviar mensajes a tus listas de forma programática. Recientemente, Mailgun ha lanzado un nuevo SDK para PHP para facilitar aún más el uso de su API.

Es posible que las listas de distribución de Mailgun ofrezcan la funcionalidad básica que necesitas para dejar de utilizar servicios de envío de emails de pago o aplicaciones de listas de código abierto como PHPList. Yo utilizo los servicios de listas de Mailgun para comunicarme con mis amigos, llegar a mis comunidades sociales y hacer contactos de negocios.

Este tutorial no solo describe cómo utilizar la API de listas de distribución de Mailgun para gestionar tus propias listas mediante PHP, sino que también ofrece un código abierto y gratuito que se puede instalar para una pequeña aplicación web, ListApp. Esta te permite gestionar y enviar emails a través de la API de listas utilizando Mailgun.com. Su objetivo principal es demostrar cómo se puede utilizar la API de listas de Mailgun en tu aplicación. ListApp está programada en el framework Yii para PHP. No necesitas tener conocimientos sobre el framework Yii para ejecutar la aplicación.

Cómo instalar y utilizar la aplicación de código abierto

La aplicación ofrece un front-end sencillo basado en web para escenarios comunes que podrías utilizar con las funciones de listas de distribución de Mailgun:

  • Sincronizar tus listas y los miembros de las listas
  • Crear, actualizar y eliminar listas
  • Importar miembros a una lista
  • Enviar mensajes a listas
  • Proporcionar un formulario público de suscripción con

El código de ListApp está disponible de forma gratuita en Github.com. Puedes instalarlo en cualquier servidor PHP/MySQL. He incluido instrucciones para configurar ListApp en un servidor de Rackspace Cloud con Ubuntu 12.04 con 1 GB de RAM. Utilizamos Ubuntu Linux, Apache, PHP 5.x, MySQL 5.x y las bibliotecas PEAR y cURL.

Aunque utilices tu propio servidor, deberías leer las instrucciones de configuración de Rackspace para crear un sitio en Apache, crear e instalar la base de datos y generar tus credenciales de inicio de sesión. También es importante personalizar los ajustes del sitio en el archivo config-listapp.ini.

Tendrás que registrarte para obtener una cuenta de Mailgun gratuita (o de nivel superior) para poder conseguir tus claves de API para el archivo de ajustes.

Si tienes una cuenta de pago, tendrás que añadir tus dominios y crear ajustes de DNS para utilizarlos. Si utilizas una cuenta gratuita, tu dominio será tuopcion.mailgun.org. Por lo tanto, las direcciones de tus listas pueden ser comodin@tuopcion.mailgun.org. Tus claves de API de Mailgun aparecerán en la página de inicio del panel de control.

Cómo utilizar la API de listas de distribución de Mailgun

Utilizar la API de listas de distribución de Mailgun es muy sencillo. Mailgun ofrece su propia documentación de la API para listas de distribución para servirte de ayuda. Puedes revisar cómo ListApp utiliza la API de Mailgun en nuestro componente Yiigun.php. ListApp utiliza el SDK de PHP de Mailgun para interactuar con Mailgun.

Estos son algunos ejemplos de usos habituales de la API de listas de distribución con Mailgun:

Inicialización del SDK de PHP de Mailgun

Cada vez que se utiliza la clase Yiigun, se llama al constructor, lo que crea una inicialización segura con la API de Mailgun:

                                

                                    function __construct()
{
    // Initialize Mailgun connection
    $this->mg = new Mailgun(Yii::app()->params['mailgun']['api_key']);
}

                                
                            

Sincronización de listas y miembros de listas

Una vez que hayas iniciado sesión en ListApp, haz clic en la opción Synchronize (Sincronizar). Esto obtendrá copias de todas las listas de distribución existentes en Mailgun y descargará a todos sus miembros en la base de datos local. Básicamente, sincroniza hacia abajo tu lista de distribución desde el sitio de Mailgun.com. Esta opción no se sincroniza hacia arriba.

Aquí tienes la función fetchLists. El uso del SDK de PHP de Mailgun hace que esto sea muy sencillo:

                                

                                    public function fetchLists()
{
    $result = $this->mg->get("lists");
    return $result->http_response_body;
}

                                
                            

Así es como obtenemos a los miembros:

                                

                                    public function fetchListMembers($address)
{
    $result = $this->mg->get("lists/" . $address . '/members');
    return $result->http_response_body;
}

                                
                            

Creación de una lista

Puedes crear nuevas listas de distribución utilizando las opciones del menú de la derecha en ListApp. Cada lista requiere un nombre, una dirección de email de la lista y una descripción. Al crear una nueva lista, ListApp también la sube con sus ajustes a Mailgun.com. También puedes actualizar las propiedades de cualquier lista.

Así es como creamos una lista nueva:

                                

                                    public function listCreate($newlist)
{
    $result = $this->mg->post("lists", [
        'address'      => $newlist->address,
        'name'         => $newlist->name,
        'description'  => $newlist->description,
        'access_level' => $newlist->access_level
    ]);

    return $result->http_response_body;
}

                                
                            

Así es como actualizamos las propiedades de las listas de distribución:

                                

                                    public function listUpdate($existing_address, $model)
{
    $result = $this->mg->put("lists/" . $existing_address, [
        'address'      => $model->address,
        'name'         => $model->name,
        'description'  => $model->description,
        'access_level' => $model->access_level
    ]);

    return $result->http_response_body;
}

                                
                            

Importación de miembros a la lista

Puedes importar miembros nuevos a cualquier lista desde ListApp. Para esta función, utilizamos las bibliotecas de análisis de listas de contactos de PEAR. Puedes pegar cualquier lista de direcciones de email con el formato Nombre personal separadas por comas o saltos de línea. ListApp añadirá a los miembros de forma local y los subirá a Mailgun.com.

Para añadir miembros de forma masiva, en primer lugar creamos una cadena JSON con los nuevos miembros a subir. Aquí tienes un código de ejemplo que puedes usar. Puedes ver un ejemplo completo aquí.

                                

                                    $json_upload = '[';

foreach ($addresses as $i) {
    $json_upload .= '{';
    $json_upload .= '"name": "' . $i->name . '", ';
    $json_upload .= '"address": "' . $i->address . '"';
    $json_upload .= '},';
}

$json_upload .= ']';

                                
                            

A continuación, llamamos a la función de subida masiva con esta cadena JSON:

                                

                                    public function memberBulkAdd($list = '', $json_str = '')
{
    $result = $this->mg->post("lists/" . $list . '/members.json', [
        'members'    => $json_str,
        'subscribed' => true,
        'upsert'     => 'yes'
    ]);

    return $result->http_response_body;
}

                                
                            

También puedes añadir miembros de manera individual a las listas utilizando la opción de menú Añadir un miembro.

Envío de un mensaje

Puedes enviar un mensaje a cualquier lista a través del menú de la derecha. Entregamos el mensaje saliente a Mailgun como cualquier otro mensaje:

                                

                                    public function send_simple_message($to = '', $subject = '', $body = '', $from = '')
{
    if ($from '') {
        $from = Yii::app()->params['supportEmail'];
    }

    $domain = Yii::app()->params['mail_domain'];

    $result = $this->mg->sendMessage($domain, [
        'from'    => $from,
        'to'      => $to,
        'subject' => $subject,
        'text'    => $body,
    ]);

    return $result->http_response_body;
}

                                
                            

Mailgun gestionará entonces la entrega del mensaje a los destinatarios individuales.

También puedes utilizar algunas de las variables de destinatario genéricas de Mailgun para incluir saludos personales, como Hola %recipient_fname% (consulta las Variables de plantilla).

Uso del formulario público de suscripción

Puedes ver el formulario de suscripción en la página de detalles de la lista de ListApp. Además, puedes proporcionar a los usuarios un enlace al formulario público de suscripción de una lista en https://listapp.yourdomain.com/request/create/<list-id#&gt;:

ListApp también utiliza la nueva API de validación de emails de Mailgun la cual detecta errores tipográficos como @gmal.com:

Estamos utilizando la validación AJAX integrada de Yii para integrar la API de validación de emails de Mailgun. La función de reglas de Yii llama a un validador personalizado que hemos creado y que se comunica con el validador de Mailgun. Consulta el modelo Request:

                                

                                    public function rules()
{
    return array(
        array('address', 'required'),
        array('name, address', 'length', 'max' => 255),
        array('address', 'mailgunValidator'),
    );
}

public function mailgunValidator($attribute, $params)
{
    $yg = new Yiigun();
    $result = $yg->validate($this->$attribute);

    if ($result->is_valid) {
        return false;
    } else {
        $this->addError(
            $attribute,
            'There is a problem with your email address ' . $result->address .
            '. Did you mean ' . $result->did_you_mean . '?'
        );
    }
}

function validate($email = '')
{
    $this->mgValidate = new Mailgun(Yii::app()->params['mailgun']['public_key']);
    $result = $this->mgValidate->get('address/validate', array('address' => $email));
    return $result->http_response_body;
}

                                
                            

Una vez validada una solicitud de suscripción, utilizamos el Opt In Handler del SDK de Mailgun para enviar un email al usuario con un enlace de verificación. Esto evita las adiciones falsas:

                                

                                    public function generateVerifyHash($model, $mglist)
{
    // Generate secure hash for verifying subscription requests
    $verify_secret = Yii::app()->params['verify_secret'];
    $optInHandler = $this->mg->OptInHandler();
    $generatedHash = $optInHandler->generateHash(
        $mglist->address,
        $verify_secret,
        $model->address
    );

    // Remove encodings - fixes Yii routing issue
    $generatedHash = str_ireplace('%', '', $generatedHash);

    return $generatedHash;
}

public function sendVerificationRequest($model, $mglist)
{
    // Send an email with the verification link
    $body = "Please verify your subscription by clicking on the link below:rn"
          . Yii::app()->getBaseUrl(true)
          . "/request/verify/"
          . $model->id
          . "/"
          . $model->hash;

    $this->send_simple_message(
        $model->address,
        'Please verify your subscription to ' . $mglist->name,
        $body,
        Yii::app()->params['support_email']
    );
}

                                
                            

Así es como añadimos a los miembros suscritos cuando hacen clic en el enlace de verificación, en el RequestController:

                                

                                    public function actionVerify($id, $hash)
{
    $request = $this->loadModel($id);

    if ($hash $request->hash) {  // findByPk($request->mglist_id);

        // Insert new Member
        $member_id = $request->insertMember($request->name, $request->address);

        // Add member to this list
        Member::model()->addToList($member_id, $request->mglist_id);

        // Add member at Mailgun
        $yg = new Yiigun();
        $yg->memberAdd($mglist->address, $request->address, $request->name);

        $this->render('verify', array(
            'model'  => $this->loadModel($id),
            'mglist' => $mglist,
        ));
    } else {
        echo 'Sorry, your request is invalid.';
        yexit();
    }
}

public function memberAdd($list = '', $email = '', $name = '')
{
    $result = $this->mg->post(
        "lists/" . $list . '/members',
        array(
            'address'    => $email,
            'name'       => $name,
            'subscribed' => true,
            'upsert'     => 'yes'
        )
    );

    return $result->http_response_body;
}

                                
                            

Adaptación de este código para PHP (sin usar Yii)

Yii es básicamente un framework MVC como Ruby on Rails, pero con toda la sencillez y la madurez de PHP. Es rápido, eficiente y bastante sencillo. También incluye generación de código (scaffolding), registro activo (active record), soporte para transacciones, localización I18n y soporte para almacenamiento en caché, entre otros. Además, la documentación, la asistencia de la comunidad y los plugins disponibles son bastante buenos. Tardamos menos de 10 horas en crear ListApp con Yii.

Sin embargo, si prefieres no utilizar Yii, puedes basarte en el componente Yiigun utilizado en ListApp. Básicamente, Yiigun.php es un archivo de clase PHP con métodos y funciones de ayuda (helpers) para aprovechar el SDK para listas de distribución de Mailgun.

La versión actual de ListApp se comunica con blog.mailgun.com/post/the-php-sdk-the-first-of-many-official-mailgun-sdks/Mailgun en tiempo real y no dispone de un amplio tratamiento de errores. A largo plazo, sería conveniente añadir solicitudes a la API asíncronas y en cola.

Además del propio material de Mailgun documentación de la API para listas de distribución (que incluye ejemplos en cURL, Ruby, PHP, Python, Java y C#), puedes revisar, extraer y adaptar el archivo Yiigun.php y sus funciones para tu propio framework o aplicación PHP.

Si no utilizas Yii, tendrás que usar composer para instalar el SDK de acuerdo con las instrucciones de instalación de Mailgun.

Cómo contribuir a las extensiones para la aplicación de código abierto a través de Github

Si quieres añadir funciones o ampliar ListApp para tus propios fines, te sugiero que hagas un fork del código en Github. Si publicamos alguna actualización o función nueva, podrás fusionar los cambios en tu trabajo en cualquier momento.

Si quieres contribuir a ListApp añadiendo funciones y pidiéndonos que las incluyamos en el código base principal (algo que nos encantaría), puedes enviar un pull request.

Git es una herramienta de gestión de código fuente colaborativa y basada en Internet extremadamente potente, pero puede resultar un poco confusa al principio. Consulta su página de ayuda para ver guías sobre los usos más habituales.

Enlaces relacionados