Exemplo n.º 1
0
 /**
  * @return int
  */
 public function execute()
 {
     // Instantiate and set data for the actual message
     $message = new ProcessMessage();
     $message->setData("firstName", $this->firstName);
     $message->setData("lastName", $this->lastName);
     $message->setData("name", "{$this->firstName} {$this->lastName}");
     $message->setData("email", $this->email);
     // Build a config object for use in a Rule. This needs to be wrapped in a
     // config group and added to a process definition as well as the full class
     // name for the rule and some default requirements.
     // Once fully setup we add the process definition to the message processor.
     $config = new Config();
     $config->setData("attribute_name", "firstName");
     $config->setData("attribute_check", $this->firstName);
     $config->setData("attribute_check_type", AttributeFilter::MATCH_EQUAL);
     $configGroup = new ConfigGroup();
     $configGroup->addConfig("process", $config);
     $process = new ProcessDefinition();
     $process->setProcessClass('Qubes\\Defero\\Components\\Campaign\\Rules\\Filter\\AttributeFilter');
     $process->setQueueName("defero");
     $process->setQueueService("queue");
     $process->configure($configGroup);
     $message->addProcess($process);
     // Same as above. Running the same check on a different variable.
     $config = new Config();
     $config->setData("attribute_name", "lastName");
     $config->setData("attribute_check", $this->lastName);
     $config->setData("attribute_check_type", AttributeFilter::MATCH_EQUAL);
     $configGroup = new ConfigGroup();
     $configGroup->addConfig("process", $config);
     $process = new ProcessDefinition();
     $process->setProcessClass('Qubes\\Defero\\Components\\Campaign\\Rules\\Filter\\AttributeFilter');
     $process->setQueueName("defero");
     $process->setQueueService("queue");
     $process->configure($configGroup);
     $message->addProcess($process);
     // Here we add a delivery rule,
     $process = new ProcessDefinition();
     /*$process->setProcessClass(
         'Qubes\Defero\Components\Campaign\Rules\Delivery\FailDeliveryRule'
       );*/
     $process->setProcessClass('Qubes\\Defero\\Components\\Campaign\\Rules\\Delivery\\DelayDeliveryRule');
     $config = new Config();
     $config->setData("delay", 60);
     $configGroup = new ConfigGroup();
     $configGroup->addConfig("process", $config);
     $process->configure($configGroup);
     $process->setQueueName("defero");
     $process->setQueueService("queue");
     $message->addProcess($process);
     // Final process is used to send the message
     $process = new ProcessDefinition();
     $process->setQueueName("defero");
     $process->setQueueService("queue");
     $process->setProcessClass('Qubes\\Defero\\Components\\Campaign\\Process\\EmailService\\Smtp');
     $message->addProcess($process);
     \Queue::setDefaultQueueProvider("messagequeue");
     \Queue::push(new StdQueue("defero_messages"), serialize($message));
 }
Exemplo n.º 2
0
 /**
  * @param int     $campaignId
  * @param array[] $batch
  *
  * @return bool
  * @throws \Exception
  */
 public static function pushMessageBatch($campaignId, array $batch)
 {
     if (!$batch) {
         return false;
     }
     $cacheId = 'DeferoQueueCampaign' . $campaignId;
     /**
      * @var Campaign $campaign
      * @var Contact  $contact
      */
     $campaign = ExpiringEphemeralCache::getCache($cacheId, __CLASS__);
     if ($campaign === null) {
         $campaign = new Campaign($campaignId);
         $campaign->reload();
         ExpiringEphemeralCache::storeCache($cacheId, $campaign, __CLASS__, 60);
     }
     if (!$campaign || !$campaign->exists()) {
         throw new \Exception('Campaign does not exist');
     }
     $campaignId = $campaign->id();
     $processorsCacheId = $cacheId . ':processors';
     $processors = ExpiringEphemeralCache::getCache($processorsCacheId, __CLASS__);
     if ($processors === null) {
         $processors = [];
         $processorsConfig = Container::get(Container::CONFIG)->get('processors');
         if ($campaign->processors) {
             foreach ($campaign->processors as $processorData) {
                 $config = new Config();
                 $config->hydrate($processorData);
                 $configGroup = new ConfigGroup();
                 $configGroup->addConfig("process", $config);
                 $process = new ProcessDefinition();
                 $process->setProcessClass($processorsConfig->getStr($processorData->processorType));
                 $process->setQueueName("defero");
                 $process->setQueueService("queue");
                 $process->configure($configGroup);
                 $processors[] = $process;
             }
         } else {
             throw new \Exception("Cannot queue campaign No default processors found.");
         }
         ExpiringEphemeralCache::storeCache($processorsCacheId, $processors, __CLASS__, 60);
     }
     $blacklistDomains = [];
     foreach (Container::config()->get('blacklist')->getArr('domains', []) as $d) {
         $blacklistDomains[] = preg_quote($d, '/');
     }
     $blacklistRegex = '/(' . implode('|', $blacklistDomains) . ')$/i';
     //grab all user_ids from $batch, check SentEmailLog
     $logKeys = [];
     $keyedBatch = [];
     //use this to recover $batch
     $dedupe = true;
     foreach ($batch as $data) {
         if (isset($data['user_id'])) {
             $logKeys[] = $data['user_id'] . '-' . $campaignId;
             $keyedBatch[$data['user_id']] = $data;
         }
         if (isset($data['dedupe'])) {
             $dedupe = false;
         }
     }
     if ($logKeys && $dedupe) {
         try {
             //check if we sent this campaign to users today or the previous day
             $yesterday = date('Y-m-d', strtotime('-1 day'));
             $today = date('Y-m-d');
             $result = SentEmailLog::cf()->multiGet($logKeys, [$yesterday, $today]);
             foreach ($result as $key => $column) {
                 if (is_array($column) && (isset($column[$yesterday]) || isset($column[$today]))) {
                     list($userId, $cId) = explode('-', $key);
                     //remove user from keyedBatch because they have already
                     // received this campaign
                     unset($keyedBatch[$userId]);
                     \Log::info("Skipping user because they already got this campaign: [user_id:" . $data['user_id'] . ', campaign_id: ' . $campaignId . "]");
                 }
             }
             $batch = array_values($keyedBatch);
         } catch (\Exception $e) {
             \Log::error("Email Deduping Failed: " . $e->getMessage());
         }
     }
     $messages = [];
     foreach ($batch as $data) {
         $data = array_change_key_case($data);
         // check blacklist
         if ($blacklistDomains && preg_match($blacklistRegex, $data['email'])) {
             continue;
         }
         // move language here.
         $userLanguage = $data['language'] = !empty($data['language']) ? $data['language'] : 'en';
         $active = isset($data['campaignactive']) ? $data['campaignactive'] : $campaign->active;
         $message = new ProcessMessage();
         $message->setData('campaignId', $campaignId);
         $message->setData('campaignActive', $active);
         if (!$active) {
             $message->setData('emailService', 'email_test');
         } elseif ($campaign->emailService) {
             $message->setData('emailService', $campaign->emailService);
         } else {
             $message->setData('emailService', 'email');
         }
         if ($campaign->replyTo) {
             $message->setData('replyTo', $campaign->replyTo);
         }
         $message->setData('mailerTracking', $campaign->trackingType);
         $message->setData('data', $data);
         $languageCacheId = $cacheId . ':language:' . $userLanguage;
         $msg = ExpiringEphemeralCache::getCache($languageCacheId, __CLASS__);
         if ($msg === null) {
             $msg = $campaign->message();
             $msg->setLanguage($userLanguage);
             $msg->reload();
             if ($userLanguage !== 'en' && (!$msg->active || !$msg->subject || $campaign->sendType != SendType::PLAIN_TEXT && !$msg->htmlContent || $campaign->sendType != SendType::HTML_ONLY && !$msg->plainText)) {
                 //for non eng if html and plain but no html we shouldn't default to english
                 if ($campaign->sendType == SendType::HTML_AND_PLAIN && !$msg->htmlContent && $msg->plainText) {
                 } else {
                     $msg->setLanguage('en');
                     $msg->reload();
                 }
             }
             ExpiringEphemeralCache::storeCache($languageCacheId, $msg, __CLASS__, 60);
         }
         $contactId = $msg->contactId ?: $campaign->contactId;
         $contactCacheId = $cacheId . ':contact:' . $contactId;
         $contact = ExpiringEphemeralCache::getCache($contactCacheId, __CLASS__);
         if ($contact === null) {
             $contact = new Contact($contactId);
             ExpiringEphemeralCache::storeCache($contactCacheId, $contact, __CLASS__, 60);
         }
         $data['signature'] = $contact->signature;
         $message->setData('senderName', self::replaceData($contact->name, $data));
         $message->setData('senderEmail', self::replaceData($contact->email, $data));
         $message->setData('returnPath', self::replaceData($contact->returnPath, $data));
         $message->setData('sendType', self::replaceData($campaign->sendType, $data));
         $message->setData('subject', self::replaceData($msg->subject, $data));
         $message->setData('plainText', self::replaceData($msg->plainText, $data));
         $message->setData('htmlContent', self::replaceData($msg->htmlContent, $data, true));
         foreach ($processors as $process) {
             $message->addProcess($process);
         }
         $messages[] = serialize($message);
     }
     // queue
     \Queue::setDefaultQueueProvider("messagequeue");
     // prioritize
     if ($campaign->active) {
         $priority = (int) $campaign->priority;
         $priority = $priority < 0 ? 1 : $priority;
     } else {
         $priority = 99;
     }
     $queueName = 'mailer.defero_messages_priority_' . $priority;
     \Queue::pushBatch(new StdQueue($queueName), $messages);
     // stats
     try {
         $hour = time();
         $hour -= $hour % 3600;
         $statsCf = MailStatistic::cf();
         $statsCf->increment($campaignId, $hour . '|queued', count($messages));
     } catch (\Exception $e) {
         \Log::error('Error writing stats for campaign ' . $campaignId . ' : ' . $e->getMessage());
     }
     \Log::info('Queued ' . count($messages) . ' messages for Campaign ' . $campaignId);
     return true;
 }