1

We are currently building an integration where when a product is purchased on Shopify the user can select a date and time to schedule the product to be emailed to a specific email address (e-card product)

The current solution we have built is using the PHP - FUEL SDK (Using SOAP)

  1. We check if the SendDefinition exists and if not create it
  2. We get the CustomerKey from the created SendDefinition to use within the code
  3. ScheduleRequestMsg object is initialised
  4. DailyRecurrence object is initialised
  5. DataExtensionObject is then updated with the user inputs (This includes Recipient Email and Send DateTime) - The Recipient_Email is the key for each object.
  6. The SendDefinitionList is created with DataSourceTypeID = CustomObject and the dataExtension is passed through
  7. Afterwards the Email template is selected based off the product (These templates are created within SFMC)
  8. The EmailSendDefinition is initialised with the SendDefinitionList (DataExtension) and the Email object
  9. ScheduleDefinition is initialised with the date formatted using PHP -> format("c") - with timezone offset.
  10. Once the objects have been created we encode that into a SOAP object and call the schedule method from the SDK.

I can see that the DataExtension is been updated with the user entered values and the email is getting scheduled with the correct template.

The issue we are facing: Multiple emails seem to be going out to each user within the DataExtension even though only one email was scheduled.

I have provided the code below.

The code to check for the SendDefinition and Create it. $emailTemplateCustomerKey <- This is the key to check if the SendDefinition exists (values e-card/print-at-home)

$sendDefinitionList = $this->_getSendDefinitions($client);
if(!empty($sendDefinitionList)){
    foreach($sendDefinitionList as $sendDefinition){
        if($sendDefinition->CustomerKey === $emailTemplateCustomerKey){
            $sendDefinitionExists = true; 
            break;
        }
    }
}else{
    $this->_createSendDefinition($client, $emailTemplateCustomerKey);
}

if(!$sendDefinitionExists){
    $this->_createSendDefinition($client, $emailTemplateCustomerKey);
}

private function _createSendDefinition($client, $template){
    try{
        //Setup the Email Send Definition
        $emailSendDef = new ExactTarget_EmailSendDefinition();
        $emailSendDef->CustomerKey = $template;
        $emailSendDef->Name = $template;
    
        //Setup the Send Classification
        $sendClass = new ExactTarget_SendClassification();
        $sendClass->CustomerKey = "Default Transactional";
        $emailSendDef->SendClassification = $sendClass;

        // Specify the Email To Send
        $email = new ExactTarget_Email();
        $email->CustomerKey = $template;
        $emailSendDef->Email = $email;

        $object = new SoapVar($emailSendDef, SOAP_ENC_OBJECT, 'EmailSendDefinition', "http://exacttarget.com/wsdl/partnerAPI");
        $request = new ExactTarget_CreateRequest();
        $request->Options = NULL;
        $request->Objects = array($object);
        $results = $client->Create($request);
        $client->send();
    } catch (Exception $e) {
        error_log($e->getMessage, 3, dirname(__FILE__). '/error_log');
    }
}

The code we init all the objects and values


try {
    $schr = new ExactTarget_ScheduleRequestMsg();
    $schr->Action = "start";
    $schr->Interactions = array();

    $DateTimeString = date(DATE_ATOM, strtotime($attr_array['Datetime'] ?? date('Y-m-d', strtotime(' +1 day'))));
    $SendTime = new DateTime($DateTimeString);
    $SendTime->setTimezone(new DateTimeZone('UTC'));

    $etr = new ExactTarget_DailyRecurrence();
    $etr->DailyRecurrencePatternType = ExactTarget_DailyRecurrencePatternTypeEnum::Interval;
    $etr->DayInterval = 1;

    $dataExtensionObject = $this->_addRecordToDataExtension($client, $attr_array);

    $dataExtension = new ET_DataExtension();
    $dataExtension->CustomerKey = 'e-gift';

    $senddefList = new ExactTarget_SendDefinitionList();
    $senddefList->DataSourceTypeID = "CustomObject";
    $senddefList->CustomObject = $dataExtension;
    $senddefList->CustomerKey = "e-gift";

    $emailobj = new ExactTarget_Email();
    $emailobj->CustomerKey = $emailTemplateCustomerKey;

    $emailSendDef = new ExactTarget_EmailSendDefinition();
    $emailSendDef->SendDefinitionList = $senddefList;
    $emailSendDef->Email = $emailobj;
    $emailSendDef->CustomerKey = $emailTemplateCustomerKey;

    $sd = new ExactTarget_ScheduleDefinition();
    $sd->RecurrenceType = ExactTarget_RecurrenceTypeEnum::Daily;
    $sd->RecurrenceRangeType = ExactTarget_RecurrenceRangeTypeEnum::EndAfter;
    $sd->StartDateTime = $SendTime->format("c");
    $sd->Occurrences = 1;
    $sd->Recurrence = new SoapVar($etr, SOAP_ENC_OBJECT, 'DailyRecurrence', 'http://exacttarget.com/wsdl/partnerAPI');

    $schr->Schedule = $sd;

    $schr->Interactions[] = new SoapVar($emailSendDef, SOAP_ENC_OBJECT, 'EmailSendDefinition', 'http://exacttarget.com/wsdl/partnerAPI');
    $schr->Options = null;

    echo '<pre>';
    print_r($schr);
    echo '</pre>';
    $results = $client->Schedule($schr);
    echo '<pre>';
    print_r($results);
    echo '</pre>';

} catch (SoapFault $e) {
    error_log($e, 3, dirname(__FILE__). '/error_log');
}

The code we have built to add Records to the selected DataExtension

private function _addRecordToDataExtension($client, $attr_array){
    try{
        $dataExtensionObject = new ExactTarget_DataExtensionObject();
        $dataExtensionObject->CustomerKey = 'e-gift';
        $dataExtensionObject->Properties = array();
        foreach($attr_array as $key => $value){
            $apiProperty = new ExactTarget_APIProperty();
            $apiProperty->Name = $key;
            $apiProperty->Value = $value;
            $dataExtensionObject->Properties[] = $apiProperty;
        }

        $Keys = new ExactTarget_APIProperty();     
        $Keys->Name = "Recipient_Email";
        $Keys->Value = $attr_array['Recipient_Email'] ?? 'leukaemia@leafcutter.com.au';
        $dataExtensionObject->Keys = array($Keys);
        
        $deoSaveOption = new SoapVar($dataExtensionObject, SOAP_ENC_OBJECT, 'DataExtensionObject', "http://exacttarget.com/wsdl/partnerAPI");

        $updateOptions = new ExactTarget_UpdateOptions();
        $updateOptions->SaveOptions = array();
        
        /*% ExactTarget_SaveOption */ 
        $saveOption = new ExactTarget_SaveOption();                
        $saveOption->PropertyName="DataExtensionObject";
        $saveOption->SaveAction=ExactTarget_SaveAction::UpdateAdd;

        $updateOptions->SaveOptions[] = $saveOption;
        $updateOptionsSaveOptions = new SoapVar($updateOptions, SOAP_ENC_OBJECT, 'UpdateOptions', "http://exacttarget.com/wsdl/partnerAPI");

        // Apply options and object to request
        $request = new ExactTarget_UpdateRequest();
        $request->Options = $updateOptionsSaveOptions;
        $request->Objects = array($deoSaveOption);
        $results = $client->Update($request);

        echo '<pre>';
        print_r($results);
        echo '</pre>';
        return $results;

    } catch (Exception $e) {
        error_log($e->getMessage, 3, dirname(__FILE__). '/error_log');
    }
}
3
  • If I get it right, you are sending to all contacts in that data extension you populate, correct? But you need to have a single senddefinition with its specific own data extension to send to. – DonL Nov 19 '20 at 7:34
  • yea I want to send a single email to a single contact however schedule it for a future date. We spoke to support and they said that we can use a single DataExtension and Marketing Cloud will manage the mapping of data which I doubt is true. So the current setup is One DataExtension Multiple contact submissions into one DataExtension Schedule multiple emails (from different or same user) I was thinking of creating a single data extension for a single contact but that seems a bit overkill. – Adrian Nov 20 '20 at 4:00
  • How about journey builder? you can inject contacts via API, having the schedule date as a "wait by attribute" activity. Since that date is not changing for a subscriber, this should be working fine for you. check it out and let me know if that is feasable for you. This would obv. mean quite some changes for you, but i think its the best solution there is. – DonL Nov 20 '20 at 7:19
1

I understand that this is not really a coding issue. It rather is a problem of using a wrong MC functionality.

My solution proposition is to go with Journey Builder. Start with an API Entry Event, including the schedule date in the contact data, beside subscriber key and email address.

Second step is to add a Wait By Attribute Activity, using the schedule date as the attribute to set. After that you can send your email.

Depending on the Journey settings you can allow for re-entry or not.

2
  • I will try this and confirm if this works for our situation. Thanks heaps! – Adrian Nov 22 '20 at 12:36
  • yup this is the way to go.. thanks heaps :) going to add automation into the mix as well :) – Adrian Nov 26 '20 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.