phpemailsendgridsymfony-1.4swiftmailer

Enabling subscription track for Sendgrid


This is really an extension of this question

but my code has changed a bit, so I thought I should start a new question. I am using the SMTP-API to speed up the delivery between our server and Sendgrid.

$hdr = new SmtpApiHeader();
$toList = $mailTo;
$hdr->addTo($toList);
$hdr->addFilterSetting('subscriptiontrack', 'enable', 1);

$to = array('email@email.edu'=>'Carey Estes');
$transport = $connection = Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 465, 'ssl');
$transport ->setUsername($username);
$transport ->setPassword($password);
$swift = Swift_Mailer::newInstance($transport);

$message = new Swift_Message($subject);

$headers = $message->getHeaders();
$headers->addTextHeader('X-SMTPAPI', $hdr->asJSON());

$message->setFrom($mailFrom);
$message->setBody($contents, 'text/html');
$message->setTo($to);

if ($recipients = $swift->send($message, $failures))
{
    return true;
}

Similar to the issue I had before, I cannot manipulate the unsubscribe link in the email. Before, I could not turn it off...and now with the new setup, I can't seem to turn it on.

$hdr->addFilterSetting('subscriptiontrack', 'enable', 1);

should make the unsubscribe link available in the email correct? Whether 0 or 1, the unsubscribe link does not appear.

In the previous question, I was structuring the JSON in the header incorrectly. Is this the case now?

UPDATE

Here is a var_dump of the $header variable, which looks wrong to me:

object(Swift_Mime_SimpleHeaderSet)#315 (5) { ["_factory":"Swift_Mime_SimpleHeaderSet":private]=> object(Swift_Mime_SimpleHeaderFactory)#316 (3) { ["_encoder":"Swift_Mime_SimpleHeaderFactory":private]=> object(Swift_Mime_HeaderEncoder_QpHeaderEncoder)#317 (2) { ["_charStream":protected]=> object(Swift_CharacterStream_NgCharacterStream)#318 (9) { ["_charReader":"Swift_CharacterStream_NgCharacterStream":private]=> NULL ["_charReaderFactory":"Swift_CharacterStream_NgCharacterStream":private]=> object(Swift_CharacterReaderFactory_SimpleCharacterReaderFactory)#319 (2) { ["_map":"Swift_CharacterReaderFactory_SimpleCharacterReaderFactory":private]=> array(15) { ["utf-?8"]=> array(2) { ["class"]=> string(32) "Swift_CharacterReader_Utf8Reader" ["constructor"]=> array(0) { } } ["(us-)?ascii"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(iso|iec)-?8859-?[0-9]+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["windows-?125[0-9]"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["cp-?[0-9]+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["ansi"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["macintosh"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["koi-?7"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["koi-?8-?.+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["mik"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(cork|t1)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["v?iscii"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(ucs-?2|utf-?16)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(2) } } ["(ucs-?4|utf-?32)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(4) } } [".*"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } } ["_loaded":"Swift_CharacterReaderFactory_SimpleCharacterReaderFactory":private]=> array(0) { } } ["_charset":"Swift_CharacterStream_NgCharacterStream":private]=> string(5) "utf-8" ["_datas":"Swift_CharacterStream_NgCharacterStream":private]=> string(0) "" ["_datasSize":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_map":"Swift_CharacterStream_NgCharacterStream":private]=> NULL ["_mapType":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_charCount":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_currentPos":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) } ["_filter":protected]=> NULL } ["_paramEncoder":"Swift_Mime_SimpleHeaderFactory":private]=> object(Swift_Encoder_Rfc2231Encoder)#320 (1) { ["_charStream":"Swift_Encoder_Rfc2231Encoder":private]=> object(Swift_CharacterStream_NgCharacterStream)#321 (9) { ["_charReader":"Swift_CharacterStream_NgCharacterStream":private]=> NULL ["_charReaderFactory":"Swift_CharacterStream_NgCharacterStream":private]=> object(Swift_CharacterReaderFactory_SimpleCharacterReaderFactory)#319 (2) { ["_map":"Swift_CharacterReaderFactory_SimpleCharacterReaderFactory":private]=> array(15) { ["utf-?8"]=> array(2) { ["class"]=> string(32) "Swift_CharacterReader_Utf8Reader" ["constructor"]=> array(0) { } } ["(us-)?ascii"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(iso|iec)-?8859-?[0-9]+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["windows-?125[0-9]"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["cp-?[0-9]+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["ansi"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["macintosh"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["koi-?7"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["koi-?8-?.+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["mik"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(cork|t1)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["v?iscii"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(ucs-?2|utf-?16)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(2) } } ["(ucs-?4|utf-?32)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(4) } } [".*"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } } ["_loaded":"Swift_CharacterReaderFactory_SimpleCharacterReaderFactory":private]=> array(0) { } } ["_charset":"Swift_CharacterStream_NgCharacterStream":private]=> string(5) "utf-8" ["_datas":"Swift_CharacterStream_NgCharacterStream":private]=> string(0) "" ["_datasSize":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_map":"Swift_CharacterStream_NgCharacterStream":private]=> NULL ["_mapType":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_charCount":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_currentPos":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) } } ["_charset":"Swift_Mime_SimpleHeaderFactory":private]=> string(5) "utf-8" } ["_headers":"Swift_Mime_SimpleHeaderSet":private]=> array(8) { ["content-transfer-encoding"]=> array(1) { [0]=> object(Swift_Mime_Headers_UnstructuredHeader)#314 (9) { ["_value":"Swift_Mime_Headers_UnstructuredHeader":private]=> string(16) "quoted-printable" ["_specials":"Swift_Mime_Headers_AbstractHeader":private]=> array(0) { } ["_grammar":"Swift_Mime_Headers_AbstractHeader":private]=> array(0) { } ["_name":"Swift_Mime_Headers_AbstractHeader":private]=> string(25) "Content-Transfer-Encoding" ["_encoder":"Swift_Mime_Headers_AbstractHeader":private]=> object(Swift_Mime_HeaderEncoder_QpHeaderEncoder)#317 (2) { ["_charStream":protected]=> object(Swift_CharacterStream_NgCharacterStream)#318 (9) { ["_charReader":"Swift_CharacterStream_NgCharacterStream":private]=> NULL ["_charReaderFactory":"Swift_CharacterStream_NgCharacterStream":private]=> object(Swift_CharacterReaderFactory_SimpleCharacterReaderFactory)#319 (2) { ["_map":"Swift_CharacterReaderFactory_SimpleCharacterReaderFactory":private]=> array(15) { ["utf-?8"]=> array(2) { ["class"]=> string(32) "Swift_CharacterReader_Utf8Reader" ["constructor"]=> array(0) { } } ["(us-)?ascii"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(iso|iec)-?8859-?[0-9]+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["windows-?125[0-9]"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["cp-?[0-9]+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["ansi"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["macintosh"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["koi-?7"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["koi-?8-?.+"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["mik"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(cork|t1)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["v?iscii"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } ["(ucs-?2|utf-?16)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(2) } } ["(ucs-?4|utf-?32)"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(4) } } [".*"]=> array(2) { ["class"]=> string(45) "Swift_CharacterReader_GenericFixedWidthReader" ["constructor"]=> array(1) { [0]=> int(1) } } } ["_loaded":"Swift_CharacterReaderFactory_SimpleCharacterReaderFactory":private]=> array(0) { } } ["_charset":"Swift_CharacterStream_NgCharacterStream":private]=> string(5) "utf-8" ["_datas":"Swift_CharacterStream_NgCharacterStream":private]=> string(0) "" ["_datasSize":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_map":"Swift_CharacterStream_NgCharacterStream":private]=> NULL ["_mapType":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_charCount":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) ["_currentPos":"Swift_CharacterStream_NgCharacterStream":private]=> int(0) } ["_filter":protected]=> NULL } ["_lineLength":"Swift_Mime_Headers_AbstractHeader":private]=> int(78) ["_lang":"Swift_Mime_Headers_AbstractHeader":private]=> NULL ["_charset":"Swift_Mime_Headers_AbstractHeader":private]=> string(5) "utf-8" ["_cachedValue":"Swift_Mime_Headers_AbstractHeader":private]=> NULL } } ["content-type"]=> array(1) { [0]=> object(Swift_Mime_Headers_ParameterizedHeader)#327 (12) { ["_paramEncoder":"Swift_Mime_Headers_ParameterizedHeader":private]=> NULL ["_params":"Swift_Mime_Headers_ParameterizedHeader":private]=> array(1) { ["charset"]=> string(5) "utf-8" } ["_tokenRe":"Swift_Mime_Headers_ParameterizedHeader":private]=> string(63) "(?:[\x21\x23-\x27\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7E]+)" ["_value":"Swift_Mime_Headers_UnstructuredHeader":private]=> string(10) "text/plain" ["_specials":"Swift_Mime_Headers_AbstractHeader":private]=> array(12) { [0]=> string(1) "(" [1]=> string(1) ")" [2]=> string(1) "<" [3]=> string(1) ">" [4]=> string(1) "[" [5]=> string(1) "]" [6]=> string(1) ":" [7]=> string(1) ";" [8]=> string(1) "@" [9]=> string(1) "," [10]=> string(1) "." [11]=> string(1) """ }

UPDATE

Here is the SmtpApiHeader class:

<?php 

class SmtpApiHeader
{
    var $data;

    function addTo($tos)
    {
        if (!isset($this->data['to'])) {
            $this->data['to'] = array();
        }
        $this->data['to'] = array_merge($this->data['to'], (array) $tos);
    }

    function addSubVal($var, $val)
    {
        if (!isset($this->data['sub'])) {
            $this->data['sub'] = array();
        }

        if (!isset($this->data['sub'][$var])) {
            $this->data['sub'][$var] = array();
        }
        $this->data['sub'][$var] = array_merge($this->data['sub'][$var], (array) $val);
    }

    function setUniqueArgs($val)
    {
        if (!is_array($val))
            return;
        // checking for associative array
        $diff = array_diff_assoc($val, array_values($val));
        if (((empty($diff)) ? false : true)) {
            $this->data['unique_args'] = $val;
        }
    }

    function setCategory($cat)
    {
        $this->data['category'] = $cat;
    }

    function addFilterSetting($filter, $setting, $value)
    {
        if (!isset($this->data['filters'])) {
            $this->data['filters'] = array();
        }

        if (!isset($this->data['filters'][$filter])) {
            $this->data['filters'][$filter] = array();
        }

        if (!isset($this->data['filters'][$filter]['settings'])) {
            $this->data['filters'][$filter]['settings'] = array();
        }
        $this->data['filters'][$filter]['settings'][$setting] = $value;
    }

    function asJSON()
    {
        $json = json_encode($this->data);
        // Add spaces so that the field can be folded
        $json = preg_replace('/(["\]}])([,:])(["\[{])/', '$1$2 $3', $json);
        return $json;
    }

    function as_string()
    {
        $json = $this->asJSON();
        $str  = "X-SMTPAPI: " . wordwrap($json, 76, "\n ");
        return $str;
    }

}

which I got here

UPDATE 28.8.13

If I do as Nick suggests and remove the hdr call and run this:

$headers->addTextHeader('X-Test', 'Some Text'); 
                echo $headers->toString();

Then I get this:

Message-ID: <1377710372.521e3124a5c6c@localhost> Date: Wed, 28 Aug 2013 13:19:32 -0400 Subject: Testing, More From: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Test: Some Text

It would seem as suggested that the issue is with the SmtpApiHeader class, but it is just a copy from the Sendgrid docs. strange.

UPDATE 30.8.13

I was able to get the Sendgrid php library (per Swift's rec in the previous question) to make this work properly. Seems to be the best way to handle the latency and adding filters. It is a bit tricky to incorporate this into Symfony 1.4, but a test on Friday showed significant increase in speed and consistency.


Solution

  • I was able to get the Sendgrid php library (per Swift's rec in the previous question) to make this work properly. Seems to be the best way to handle the latency and adding filters. It is a bit tricky to incorporate this into Symfony 1.4, but a test run showed significant increase in speed and consistency.