4

I'm using Community 1.9 with the Magemonkey extension by eBizMarts for Mailchimp installed. How can I go about creating a rule so that any person who subscribes successfully gets a $10 coupon to spend on the online store?

5

This is not available out the box, and no rule would make this happen. You would need to do some custom code to make this work, as well as utilize mailchimps callback hooks to allow you to issue coupons on a successful subscription confirmation.

So lets start:

The first step is to go create a Shopping Cart Price Rule, and in the configuration, you set it to use a 'Specific Coupon', and then tick 'Use auto Generation' - do not generate coupons. This will be done via code from the mailchimp callback hook.

Create a controller action in your module. This is the callback hook that you will configure in mailchimp.

The controller would do a bit of basic validation to make sure it comes from the callback, and then use a model to handle the coupon generation and emailing thereof.

In mailchmimp you would set the hook as follows: (the wkey is just a random generated number, to ensure only the mailchimp hook can call the action)

mailchmip callback

Your controller action will look something like this: (note some irrelevant code removed)

class YourCompany_Mailingdriver_WebhookController extends Mage_Core_Controller_Front_Action
{

    /**
     * Entry point for all webhook operations
     */
    public function indexAction()
    {

        $requestKey = $this->getRequest()->getParam('wkey');

        //Checking if "wkey" para is present on request, we cannot check for !isPost()
        //because Mailchimp pings the URL (GET request) to validate webhook
        if( !$requestKey && $requestKey != '4ccd6d389b491419default'){
            $this->getResponse()
                ->setHeader('HTTP/1.1', '403 Forbidden')
                ->sendResponse();
            return $this;
        }

        Mage::app()->setCurrentStore(Mage::app()->getDefaultStoreView());

        Mage::log($this->getRequest()->getPost(), null, 'NewsletterPromotions_Mailingdriver_MonkeyApiCalls.log');

    $data  = $this->getRequest()->getPost();
    if(Mage::getIsDeveloperMode()) {
        $data = array('type'=>'subscribe',
              'data' => array('email'=>'your_email@example.com'),
              'list_id' => 'AAAAAAAAA');
    }
    if (array_key_exists('type',$data)) {
        Mage::getModel('mailingdriver/subscribe')->processWebhookData($data);
        } else {
            Mage::helper('monkey')->log($this->__('WebHook Data invalid!'));
        }  
    }

}

The actual work is done in the model method processWebhookData:

public function processWebhookData(array $data) {
        if (Mage::helper('mailingdriver')->canShow()) {
            if ($data['type'] == 'subscribe') {
                try {
                    $subscriber = Mage::getModel('newsletter/subscriber')
                            ->loadByEmail($data['data']['email']);
                     if ($this->canGetCoupon($subscriber)) { // only new subscribers can get a coupon.
            $this->sendCoupon($subscriber);
                        $subscriber->setNewSubscriber(0); // un-flag as new. Now only if they are physically deleted from magento subscriber list will they ever get another coupon
                    } else {
                        mage::log("subscriber {$subscriber->getEmail()} is not a new subscription", null, 'NewsletterPromotions_Mailingdriver_MonkeyApiCalls.log');
                        Mage::helper('mailingdriver/couponmailer')->sendNoCoupon($subscriber);
                    }
                } catch (Exception $e) {
                    Mage::logException($e);
                }
                $subscriber->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED)
                        ->save();
            }
        }
    }

The code above first checks to see if a person can get a coupon (this may not apply to your needs, but included for completness:

/**
     * Test if coupon can be issued
     *
     * @param object $subscriber
     * @return boolean
     */
    private function canGetCoupon($subscriber) {
    // new subscriber can get coupon, no issues.
    if ($subscriber->getNewSubscriber() == 1) {
        return true;
    }
    if ($subscriber->getStatus() != Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED) {
        // not a new subscriber, not subscribed (active), but is the date they unsubscribed older than the configured days in admin?
        $todayDate = strtotime(Mage::app()->getLocale()->date()->toString(Varien_Date::DATE_INTERNAL_FORMAT));
        $daysAllowed = Mage::helper('mailingdriver')->unsubscribePeriod();
        $statusChanged = strtotime($subscriber->getChangeStatusAt());
        $dateDiff = $todayDate - $statusChanged;
        $days = $dateDiff / (60 * 60 * 24);
        if ($days > $daysAllowed) {
        mage::log("subscriber {$subscriber->getEmail()} unsubscribed for {$days} - allowing coupon", null, 'NewsletterPromotions_Mailingdriver_MonkeyApiCalls.log');
        return true;
        }
    }
    return false;
    }

You will see the code above gets a numeric value for how many days a person should have been unsubscribed for, before they can again get a coupon. Adjust to your needs how you will populate that. The call is Mage::helper('mailingdriver')->unsubscribePeriod();

So, if they are valid to get a coupon, we generate one for them. This is done from a call in the sendCoupon method.

public function sendCoupon($subscriber) {
        if (!Zend_Validate::is($subscriber->getEmail(), 'EmailAddress')) {
            Mage::throwException(Mage::helper('mailingdriver')->__('Please enter a valid email address.'));
        }
        try {
            if ($coupon = $this->_generateCoupon()) {
                //send email
                Mage::helper('mailingdriver/couponmailer')->sendCoupon($subscriber, $coupon->getCode());
            }
        } catch (Exception $e) {
            mage::throwException($e->getMessage());
        }
    }

and finally the code that interacts with your created Cart rule, and creates the coupon. You can see in the code how the generated coupon will be formatted.

/**
     * Generate a coupon 
     * @throws Exception
     */
    protected function _generateCoupon() {
        /** @var $rule Mage_SalesRule_Model_Rule */
        $rule = Mage::getModel('salesrule/rule')->load(Mage::helper('mailingdriver')->getRuleId());
        if (!$rule->getId() && !$rule->getEnabled() != 1) {
            mage::throwException('Mailingdriver activated, but Shopping Cart Rule ID could not be found, or rule is disabled');
        }
        $data = array(
            'rule_id' => $rule->getId(),
            'qty' => 1,
            'length' => 5,
            'format' => 'alphanum',
            'prefix' => 'PREFIX-',
            'suffix' => '',
            'dash' => 0,
            'uses_per_coupon' => $rule->getUsesPerCoupon(),
            'uses_per_customer' => $rule->getUsesPerCustomer(),
            'to_date' => $rule->getToDate(),
        );
        try {
            $generator = $rule->getCouponMassGenerator();
            if (!$generator->validateData($data)) {
                mage::throwException('Not valid data provided to Mailingdriver to use coupon mass generator!');
            } else {
                $generator->setData($data);
                $generator->generatePool();
                $collection = Mage::getModel('salesrule/coupon')
                        ->getCollection()
                        ->addFieldToSelect('*');
                $collection->getSelect()
                        ->order('coupon_id DESC')
                        ->limit(1);
                if ($collection->Count() == 0) {
                    mage::throwException('Could not retrieve a valid coupon code after generated');
                }
                return $collection->getFirstItem();
            }
        } catch (Exception $e) {
            mage::throwException($e->getMessage());
        }
    }

in the code above Mage::helper('mailingdriver')->getRuleId() is the id of your Cart Promo Rule you created.

Hope that helps, and ask if you need some clarification on any of the code.

  • Sorry for the late reply, but WOW! Thank you ever so much for the extremely comprehensive post. Please give me some time just to understand the code and then attempt implementing it. I'm sure I'll have questions, so I will post back here. Thanks again – maGz Oct 21 '14 at 22:42
  • Thank u, thank u, thank u! I haven't completed implementing it, but so far looking very promising. I've accepted your answer, but do please expect me to come back if I have any questions :) – maGz Oct 22 '14 at 22:07
  • No worries. I use this method on a few sites. Glad I could help. – ProxiBlue Oct 22 '14 at 22:11
1

A quick and dirty solution is to create a discount rule for 10$, that can be used multiple times, but only one for each customer and hard code the coupon code in the newsletter subscription confirmation email that is sent to the customer.
For a clean solution use what @ProxiBlue answered. Looks like it should work.

0

I've built an app that enables you to automatically generate a unique coupon code for every new subscribe. Then you can include the coupon in a welcome email sent from Mailchimp. The app is named Personal Discount and it's available at https://personaldiscount.io

Personal Discount - automation settings

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.