From 7f69ed596d7e89b0813502ec27f2e36cd6a595b8 Mon Sep 17 00:00:00 2001
From: Charles Drew <cdrew@directvetmarketing.com>
Date: Fri, 20 Jun 2014 15:35:13 -0400
Subject: [PATCH] Initial Committ

---
 app/LICENSE                                   |  21 ++
 app/README.md                                 |   4 +
 .../Block/Adminhtml/Customer/Email.php        |  13 +
 .../Block/Adminhtml/Customer/Email/Grid.php   |  66 ++++
 .../Block/Adminhtml/Customer/Tab/Mailgun.php  |  37 +++
 .../MailGun/Block/Adminhtml/Emailtracking.php |  75 +++++
 .../Block/Adminhtml/Event/Container.php       |  13 +
 .../MailGun/Block/Adminhtml/Event/Grid.php    |  50 +++
 .../Adminhtml/Event/Renderer/Timestamp.php    |  10 +
 .../Block/Adminhtml/Event/Renderer/Type.php   |   9 +
 .../Block/Adminhtml/Global/Container.php      |  13 +
 .../MailGun/Block/Adminhtml/Global/Grid.php   |  66 ++++
 .../FreeLunchLabs/MailGun/Helper/Data.php     |   5 +
 .../FreeLunchLabs/MailGun/Model/Email.php     |  48 +++
 .../MailGun/Model/Email/Template.php          | 133 ++++++++
 .../FreeLunchLabs/MailGun/Model/Event.php     |  36 +++
 .../Model/Exceptions/InvalidParameter.php     |   5 +
 .../Model/Exceptions/InvalidParameterType.php |   5 +
 .../MissingRequiredMIMEParameters.php         |   5 +
 .../Model/Exceptions/TooManyParameters.php    |   5 +
 .../FreeLunchLabs/MailGun/Model/Mailgun.php   | 120 +++++++
 .../MailGun/Model/Messagebuilder.php          | 296 ++++++++++++++++++
 .../MailGun/Model/Resource/Email.php          |  26 ++
 .../Model/Resource/Email/Collection.php       |  38 +++
 .../MailGun/Model/Resource/Event.php          |  10 +
 .../Model/Resource/Event/Collection.php       |  11 +
 .../Adminhtml/EmailtrackingController.php     |  96 ++++++
 .../FreeLunchLabs/MailGun/etc/config.xml      | 151 +++++++++
 .../FreeLunchLabs/MailGun/etc/system.xml      | 111 +++++++
 .../mailgun_setup/mysql4-install-1.0.0.php    |  33 ++
 .../default/default/layout/mailgun.xml        |  21 ++
 .../template/mailgun/customer/tab/tab.phtml   |   1 +
 .../template/mailgun/emaildetail.phtml        |  90 ++++++
 .../template/mailgun/globalemailgrid.phtml    |  15 +
 app/etc/modules/FreeLunchLabs_MailGun.xml     |   9 +
 35 files changed, 1647 insertions(+)
 create mode 100644 app/LICENSE
 create mode 100644 app/README.md
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email/Grid.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Tab/Mailgun.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Emailtracking.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Container.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Grid.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Timestamp.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Type.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Container.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Grid.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Helper/Data.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Email.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Event.php
 create mode 100755 app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameter.php
 create mode 100755 app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameterType.php
 create mode 100755 app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/MissingRequiredMIMEParameters.php
 create mode 100755 app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/TooManyParameters.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email/Collection.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event/Collection.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/controllers/Adminhtml/EmailtrackingController.php
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/etc/config.xml
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/etc/system.xml
 create mode 100644 app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-install-1.0.0.php
 create mode 100644 app/design/adminhtml/default/default/layout/mailgun.xml
 create mode 100644 app/design/adminhtml/default/default/template/mailgun/customer/tab/tab.phtml
 create mode 100644 app/design/adminhtml/default/default/template/mailgun/emaildetail.phtml
 create mode 100644 app/design/adminhtml/default/default/template/mailgun/globalemailgrid.phtml
 create mode 100644 app/etc/modules/FreeLunchLabs_MailGun.xml

diff --git a/app/LICENSE b/app/LICENSE
new file mode 100644
index 0000000..0ada34d
--- /dev/null
+++ b/app/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 chuckdrew
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/app/README.md b/app/README.md
new file mode 100644
index 0000000..b927393
--- /dev/null
+++ b/app/README.md
@@ -0,0 +1,4 @@
+mailgin_magento
+===============
+
+Mailgun extension for Magento
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email.php
new file mode 100644
index 0000000..95cd488
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email.php
@@ -0,0 +1,13 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Customer_Email extends Mage_Adminhtml_Block_Widget_Grid_Container {
+
+    protected function _construct() {
+        parent::_construct();
+
+        $this->_blockGroup = 'freelunchlabs_mailgun';
+        $this->_controller = 'adminhtml_customer_email';
+        $this->_headerText = false;
+        
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email/Grid.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email/Grid.php
new file mode 100644
index 0000000..3ba02dd
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Email/Grid.php
@@ -0,0 +1,66 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Customer_Email_Grid extends Mage_Adminhtml_Block_Widget_Grid {
+
+    public function __construct() {
+        parent::__construct();
+        $this->setId('mailgun_email_grid');
+        $this->setDefaultSort('id');
+        $this->setDefaultDir('ASC');
+        $this->setUseAjax(true);
+        $this->setFilterVisibility(true);
+    }
+
+    protected function _prepareCollection() {
+        $collection = Mage::getResourceModel('freelunchlabs_mailgun/email_collection')->getGridCollection();
+        
+        //Filter on Customer
+        $collection->addFieldToFilter('customer_id', Mage::registry('current_customer')->getId());
+        
+        $this->setCollection($collection);
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns() {
+
+        $this->addColumn('subject', array(
+            'header' => 'Subject',
+            'type' => 'text',
+            'index' => 'subject'
+        ));
+        
+        $this->addColumn('mailgun_id', array(
+            'header' => 'Mailgun ID',
+            'type' => 'text',
+            'index' => 'mailgun_id'
+        ));
+        
+        $this->addColumn('current_status', array(
+            'header' => 'Latest Status',
+            'index' => 'current_status',
+            'renderer'  => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type'
+        ));
+        
+        $this->addColumn('date_sent', array(
+            'header' => 'Date Sent',
+            'type' => 'datetime',
+            'index' => 'date_sent'
+        ));
+
+        return parent::_prepareColumns();
+    }
+
+    public function getRowUrl($row) {
+        return $this->getUrl('*/emailTracking/emailDetail', array(
+            'id' => $row->getId()
+        ));
+    }
+
+    public function getGridUrl() {
+        return $this->getUrl('*/emailtracking/emailGrid', array(
+            '_current' => true,
+            'id' => Mage::registry('current_customer')->getId()
+        ));
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Tab/Mailgun.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Tab/Mailgun.php
new file mode 100644
index 0000000..dc92238
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Customer/Tab/Mailgun.php
@@ -0,0 +1,37 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Customer_Tab_Mailgun extends Mage_Adminhtml_Block_Template implements Mage_Adminhtml_Block_Widget_Tab_Interface {
+
+    public function _construct() {
+        parent::_construct();
+
+        $this->setTemplate('mailgun/customer/tab/tab.phtml');
+    }
+
+    public function getTabLabel() {
+        return $this->__('Email Tracking');
+    }
+
+    public function getTabTitle() {
+        return $this->__('View emails sent to this customer and the email history');
+    }
+
+    public function canShowTab() {
+        return Mage::getStoreConfig('mailgun/events/store');
+    }
+
+    public function isHidden() {
+        return false;
+    }
+    
+    public function getAfter() {
+        return 'tags';
+    }
+    
+    public function getGrid() {
+        $gridBlock = $this->getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_customer_email'); 
+        
+        return $gridBlock->getGridHtml();
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Emailtracking.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Emailtracking.php
new file mode 100644
index 0000000..f4d2d8e
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Emailtracking.php
@@ -0,0 +1,75 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Emailtracking extends Mage_Adminhtml_Block_Template {
+
+    function getFetchActivityUrl() {
+        return $this->getUrl('*/*/getEmailEvents');
+    }
+
+    public function getEmailDetail() {
+        $email = Mage::registry('current_email');
+
+        if ($email->getCustomerId()) {
+            $customer = Mage::getModel('customer/customer')->load($email->getCustomerId());
+            $email->setCustomer($customer);
+        }
+
+        return $email;
+    }
+
+    public function getBackButtonHtml() {
+        return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('Back', 'history.back()', 'back');
+    }
+
+    public function getViewEmailBodyButtonHtml($emailId) {
+        $url = $this->getUrl('*/*/emailView', array(
+            'id' => $emailId
+        ));
+
+        $onClick = "window.open('{$url}','name','width=700,height=800')";
+
+        return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('View Email Body', $onClick);
+    }
+
+    public function getEditCustomerUrl($customerId) {
+        return $url = $this->getUrl('*/customer/edit', array(
+            'id' => $customerId
+        ));
+    }
+
+    public function getCustomerGroupName($customerGroupId) {
+        return Mage::getModel('customer/group')->load($customerGroupId)->getCustomerGroupCode();
+    }
+
+    public function formatCustomerCreateDate($createdTimestamp) {
+        return Mage::helper('core')->formatDate($createdTimestamp, Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
+    }
+
+    public function getFetch24HoursOfEmailActivityButton() {
+        $onClick = "setLocation('{$this->getFetchActivityUrl()}')";
+
+        return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('Fetch Past 24 Hours of Email Activity', $onClick);
+    }
+
+    public function getDeleteEmailTrackingLogsDaysButton() {       
+        $days = Mage::getStoreConfig('mailgun/events/days');
+
+        if ($days) {
+            $url = $this->getUrl('*/*/deleteEmailTrackingLogsDays');
+            $onClick = "confirmSetLocation('Are you sure?', '{$url}')";
+            
+            return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml("Delete Email Records Older Than {$days} Days", $onClick, 'delete');
+        } else {
+            return "";
+        }
+    }
+
+    public function getDeleteAllEmailTrackingLogsButton() {
+        $url = $this->getUrl('*/*/deleteEmailTrackingLogs');
+        $onClick = "confirmSetLocation('Are you sure?', '{$url}')";
+
+        return $this->getLayout()->createBlock('adminhtml/widget')->getButtonHtml('Delete All Email Records', $onClick, 'delete');
+    }
+
+}
+
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Container.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Container.php
new file mode 100644
index 0000000..8bbd5ba
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Container.php
@@ -0,0 +1,13 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Event_Container extends Mage_Adminhtml_Block_Widget_Grid_Container {
+
+    protected function _construct() {
+        parent::_construct();
+
+        $this->_blockGroup = 'freelunchlabs_mailgun';
+        $this->_controller = 'adminhtml_event';
+        $this->_headerText = false;
+        
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Grid.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Grid.php
new file mode 100644
index 0000000..7925c06
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Grid.php
@@ -0,0 +1,50 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Event_Grid extends Mage_Adminhtml_Block_Widget_Grid {
+
+    public function __construct() {
+        parent::__construct();
+        $this->setId('mailgun_event_grid');
+        $this->setDefaultSort('timestamp');
+        $this->setDefaultDir('ASC');
+        $this->setUseAjax(false);
+        $this->setFilterVisibility(false);
+    }
+
+    protected function _prepareCollection() {
+        $collection = Mage::getResourceModel('freelunchlabs_mailgun/event_collection');
+        $collection->addFieldToFilter('email_id', Mage::registry('current_email')->getId());
+        
+        $this->setCollection($collection);
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns() {
+        
+        $this->addColumn('event_type', array(
+            'header' => 'Event',
+            'index' => 'event_type',
+            'renderer'  => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type'
+        ));
+        
+        $this->addColumn('timestamp', array(
+            'header' => 'Event Time',
+            'index' => 'timestamp',
+            'renderer'  => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Timestamp'
+        ));
+
+        return parent::_prepareColumns();
+    }
+
+    public function getRowUrl($row) {
+        return null;
+    }
+
+    public function getGridUrl() {
+        return $this->getUrl('*/emailTracking/emailDetail', array(
+            '_current' => true,
+            'id' => Mage::registry('current_email')->getId()
+        ));
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Timestamp.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Timestamp.php
new file mode 100644
index 0000000..6e46333
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Timestamp.php
@@ -0,0 +1,10 @@
+<?php
+class FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Timestamp extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
+{
+    public function render(Varien_Object $row)
+    {
+        $value =  $row->getData($this->getColumn()->getIndex());
+        $date = Mage::getSingleton('core/date')->date(null, $value);
+        return Mage::helper('core')->formatDate(new Zend_Date($date), 'medium', true);
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Type.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Type.php
new file mode 100644
index 0000000..74ed449
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Event/Renderer/Type.php
@@ -0,0 +1,9 @@
+<?php
+class FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
+{
+    public function render(Varien_Object $row)
+    {
+        $value =  $row->getData($this->getColumn()->getIndex());
+        return ucwords($value);
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Container.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Container.php
new file mode 100644
index 0000000..210fd15
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Container.php
@@ -0,0 +1,13 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Global_Container extends Mage_Adminhtml_Block_Widget_Grid_Container {
+
+    protected function _construct() {
+        parent::_construct();
+
+        $this->_blockGroup = 'freelunchlabs_mailgun';
+        $this->_controller = 'adminhtml_global';
+        $this->_headerText = false;
+        
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Grid.php b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Grid.php
new file mode 100644
index 0000000..dbf0fdf
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Block/Adminhtml/Global/Grid.php
@@ -0,0 +1,66 @@
+<?php
+
+class FreeLunchLabs_MailGun_Block_Adminhtml_Global_Grid extends Mage_Adminhtml_Block_Widget_Grid {
+
+    public function __construct() {
+        parent::__construct();
+        $this->setId('mailgun_global_grid');
+        $this->setDefaultSort('date_sent');
+        $this->setDefaultDir('ASC');
+        $this->setUseAjax(false);
+        $this->setFilterVisibility(true);
+    }
+
+    protected function _prepareCollection() {
+        $collection = Mage::getResourceModel('freelunchlabs_mailgun/email_collection')->getGridCollection();
+        
+        $this->setCollection($collection);
+        return parent::_prepareCollection();
+    }
+
+    protected function _prepareColumns() {
+        
+        $this->addColumn('subject', array(
+            'header' => 'Subject',
+            'type' => 'text',
+            'index' => 'subject'
+        ));
+        
+        $this->addColumn('email_address', array(
+            'header' => 'Recipient Address',
+            'type' => 'email',
+            'index' => 'email_address'
+        ));
+        
+        $this->addColumn('mailgun_id', array(
+            'header' => 'Mailgun ID',
+            'type' => 'text',
+            'index' => 'mailgun_id'
+        ));
+        
+        $this->addColumn('current_status', array(
+            'header' => 'Latest Status',
+            'index' => 'current_status',
+            'renderer'  => 'FreeLunchLabs_MailGun_Block_Adminhtml_Event_Renderer_Type'
+        ));
+        
+        $this->addColumn('date_sent', array(
+            'header' => 'Date Sent',
+            'type' => 'datetime',
+            'index' => 'date_sent'
+        ));
+
+        return parent::_prepareColumns();
+    }
+
+    public function getRowUrl($row) {
+        return $this->getUrl('*/emailTracking/emailDetail', array(
+            'id' => $row->getId()
+        ));
+    }
+
+    public function getGridUrl() {
+        return $this->getUrl('*/emailtracking');
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Helper/Data.php b/app/code/community/FreeLunchLabs/MailGun/Helper/Data.php
new file mode 100644
index 0000000..8bfb539
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Helper/Data.php
@@ -0,0 +1,5 @@
+<?php
+
+class FreeLunchLabs_MailGun_Helper_Data extends Mage_Core_Helper_Abstract {
+    
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Email.php b/app/code/community/FreeLunchLabs/MailGun/Model/Email.php
new file mode 100644
index 0000000..1f8ed03
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Email.php
@@ -0,0 +1,48 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Email extends Mage_Core_Model_Abstract {
+
+    protected function _construct() {
+        $this->_init('freelunchlabs_mailgun/email');
+    }
+
+    public function saveInitialSend($message, $sendResponse) {
+        $customer = Mage::getModel('customer/customer');
+        $customer->setWebsiteId($message->getStore()->getWebsite()->getId());
+        $customer->loadByEmail($message->getPrimaryRecipient());
+
+        if ($customer) {
+            $this->setCustomerId($customer->getId());
+        }
+
+        $this->setEmailAddress($message->getPrimaryRecipient());
+        $this->setMailgunId(str_replace(array("<", ">"), "", $sendResponse->id));
+        $this->setSubject($message->getSubject());
+        $this->setBody($message->getHtmlBody());
+        $this->setDateSent(Mage::getSingleton('core/date')->gmtTimestamp());
+        $this->save();
+
+        Mage::getModel('freelunchlabs_mailgun/event')->logEmailEvent($this->getId(), FreeLunchLabs_MailGun_Model_Event::PUSHED, $this);
+    }
+
+    public function loadByMailgunIdAndRecipient($mailgunId, $recipient) {
+        $collection = $this->getCollection();
+        $collection->addFieldToFilter('mailgun_id', $mailgunId);
+        $collection->addFieldToFilter('email_address', $recipient);
+
+        return $collection->getFirstItem();
+    }
+
+    public function deleteEmailTrackingLogsDays() {
+        $days = Mage::getStoreConfig('mailgun/events/days');
+
+        if ($days) {
+            $this->deleteEmailTrackingLogs($days);
+        }
+    }
+
+    public function deleteEmailTrackingLogs($days = false) {
+        $this->getResource()->deleteEmailTrackingLogs($days);
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php b/app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php
new file mode 100644
index 0000000..6ccdd13
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Email/Template.php
@@ -0,0 +1,133 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Email_Template extends Mage_Core_Model_Email_Template {
+
+    var $bcc = null;
+    var $replyto = null;
+    var $returnPath = null; //This is not used because MailGun overides it for their internal purposes.
+
+    public function send($email, $name = null, array $variables = array()) {
+        //Get appropriate store
+        if(isset($variables['store'])) {
+            $store = $variables['store'];
+        } elseif($this->getDesignConfig()->getStore()) {
+            $store = Mage::getModel('core/store')->load($this->getDesignConfig()->getStore());
+        } else {
+            $store = Mage::app()->getStore();
+        }
+        
+        if ($store->getConfig('mailgun/general/active')) {
+            if (!$this->isValidForSend()) {
+                Mage::logException(new Exception('This letter cannot be sent.')); 
+                return false;
+            }
+            
+            $message = Mage::getModel('freelunchlabs_mailgun/messagebuilder');
+
+            //Recipient(s)
+            $emails = array_values((array) $email);
+            $names = is_array($name) ? $name : (array) $name;
+            $names = array_values($names);
+            foreach ($emails as $key => $email) {
+                if (!isset($names[$key])) {
+                    $names[$key] = substr($email, 0, strpos($email, '@'));
+                }
+            }
+
+            $variables['email'] = reset($emails);
+            $variables['name'] = reset($names);
+
+            //Add To Recipients
+            $isPrimary = true;
+            foreach ($emails as $key => $email) {
+                if($isPrimary) {
+                    //Add primary recipient
+                    $message->setPrimaryRecipient($email);
+                }
+                $isPrimary = false;
+                
+                $message->addToRecipient($names[$key] . " <" . $email . ">");
+            }
+            
+            //Subject
+            $subject = $this->getProcessedTemplateSubject($variables);
+            $message->setSubject($subject);
+            
+            //From Name
+            $message->setFromAddress($this->getSenderName() . " <" . $this->getSenderEmail() . ">");
+
+            //Bcc
+            if (is_array($this->bcc)) {
+                foreach ($this->bcc as $bcc_email) {
+                    $message->addBccRecipient($bcc_email);
+                }
+            } elseif ($this->bcc) {
+                $message->addBccRecipient($this->bcc);
+            }
+
+            //Reply To
+            if (!is_null($this->replyto)) {
+                $message->setReplyToAddress($this->replyto);
+            }
+
+            //Message Body
+            $this->setUseAbsoluteLinks(true);
+            $processedTemplateBody = $this->getProcessedTemplate($variables, true);
+
+            if ($this->isPlain()) {
+                $message->setTextBody($processedTemplateBody);
+            } else {
+                $message->setHtmlBody($processedTemplateBody);
+            }
+
+            //Add Unique Args
+            $message->addCustomData("message_data", array('id' => 123456));
+            
+            //Tag message with type
+            $message->addTag($this->getTemplateId());
+            $message->addTag($store->getConfig('mailgun/general/tag'));
+            
+            if($store->getConfig('mailgun/events/opens')) {
+                $message->setOpenTracking(true);
+            }
+            
+            if($store->getConfig('mailgun/events/clicks')) {
+                $message->setClickTracking(true);
+            }
+            
+            //Set store
+            $message->setStore($store);
+            
+            //Send it!
+            try {
+                Mage::getModel('freelunchlabs_mailgun/mailgun')->send($message);
+                $this->_mail = null;
+            } catch (Exception $e) {
+                $this->_mail = null;
+                Mage::logException($e);
+                return false;
+            }
+
+            return true;
+        } else {
+            return parent::send($email, $name, $variables);
+        }
+    }
+
+    public function addBcc($bcc) {
+        $this->bcc = $bcc;
+        return parent::addBcc($bcc);
+    }
+
+    public function setReturnPath($email) {
+        $this->returnPath = $email;
+        return parent::setReturnPath($email);
+        
+    }
+
+    public function setReplyTo($email) {
+        $this->replyto = $email;
+        return parent::setReplyTo($email);
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Event.php b/app/code/community/FreeLunchLabs/MailGun/Model/Event.php
new file mode 100644
index 0000000..3b65ae6
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Event.php
@@ -0,0 +1,36 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Event extends Mage_Core_Model_Abstract {
+    //Event types
+
+    const PUSHED = "pushed";
+    const ACCEPTED = "accepted";
+    const REJECTED = "rejected";
+    const DELIVERED = "delivered";
+    const FAILED = "failed";
+    const OPENED = "opened";
+    const CLICKED = "clicked";
+    const UNSUBSCRIBED = "unsubscribed";
+    const COMPLAINED = "complained";
+    const STORED = "stored";
+
+    protected function _construct() {
+        $this->_init('freelunchlabs_mailgun/event');
+    }
+
+    public function logEmailEvent($emailId, $eventType, $email = false) {
+        $this->setEmailId($emailId);
+        $this->setEventType($eventType);
+        $this->setTimestamp(Mage::getSingleton('core/date')->gmtTimestamp());
+        $this->save();
+    }
+
+    public function loadByTimestampAndEmailId($timestamp, $emailId) {
+        $collection = $this->getCollection();
+        $collection->addFieldToFilter('timestamp', $timestamp);
+        $collection->addFieldToFilter('email_id', $emailId);
+
+        return $collection->getFirstItem();
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameter.php b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameter.php
new file mode 100755
index 0000000..433686a
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameter.php
@@ -0,0 +1,5 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter extends \Exception{}
+
+?>
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameterType.php b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameterType.php
new file mode 100755
index 0000000..9c4e533
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/InvalidParameterType.php
@@ -0,0 +1,5 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameterType extends \Exception{}
+
+?>
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/MissingRequiredMIMEParameters.php b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/MissingRequiredMIMEParameters.php
new file mode 100755
index 0000000..e4badc8
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/MissingRequiredMIMEParameters.php
@@ -0,0 +1,5 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Exceptions_MissingRequiredMIMEParameters extends \Exception{}
+
+?>
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/TooManyParameters.php b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/TooManyParameters.php
new file mode 100755
index 0000000..df12fc6
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Exceptions/TooManyParameters.php
@@ -0,0 +1,5 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters extends \Exception{}
+
+?>
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php b/app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php
new file mode 100644
index 0000000..49ade88
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Mailgun.php
@@ -0,0 +1,120 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Mailgun extends Mage_Core_Model_Abstract {
+
+    public $apiUrl = "https://api.mailgun.net/v2/";
+
+    public function mailgunRequest($type, $domain, $apiKey, $data, $method = Zend_Http_Client::GET, $uriOveride = false) {
+     
+        $client = new Zend_Http_Client();
+        $client->setAuth("api", $apiKey);
+        $client->setMethod($method);
+        
+        if($uriOveride) {
+            $client->setUri($uriOveride);
+        } else {
+            $client->setUri($this->apiUrl . $domain . "/" . $type);
+        }
+        
+        if($method == Zend_Http_Client::POST) {
+            foreach($data as $key => $value) {
+                $client->setParameterPost($key, $value);
+            }
+        } else {
+            foreach($data as $key => $value) {
+                $client->setParameterGet($key, $value);
+            }
+        }
+        
+        try {
+            $response = $client->request();
+            
+            if($response->getStatus() == 200) {
+                return json_decode($response->getBody());
+            } else {
+                throw new Zend_Http_Exception("Error connecting to MailGun API. Returned error code: " . $response->getStatus() . " --- " . $response->getBody());
+            }
+        } catch (Exception $e) {
+            Mage::logException($e);
+            return false;
+        }
+    }
+    
+    public function send($message) {
+        
+        $domain = $message->getStore()->getConfig('mailgun/general/domain');
+        $apiKey = $message->getStore()->getConfig('mailgun/general/key');
+       
+        $sendResponse = $this->mailgunRequest('messages', $domain, $apiKey, $message->getMessage(), Zend_Http_Client::POST);
+        
+        if($message->getStore()->getConfig('mailgun/events/store')) {
+            Mage::getModel('freelunchlabs_mailgun/email')->saveInitialSend($message, $sendResponse);
+        }
+        
+        return $sendResponse;
+    }
+
+    public function processEmailEventsForAllStores() {
+    
+        $stores = Mage::getModel('core/store')->getCollection();
+        
+        foreach($stores as $store) {
+            if($store->getConfig('mailgun/events/store')) {
+                $this->processEmailEventsForSingleStore($store);
+            }
+        }        
+    }
+    
+    public function processEmailEventsForSingleStore(Mage_Core_Model_Store $store) {
+        
+        if($store->getConfig('mailgun/events/store')) {
+            
+            $data = array(
+                'end' => date("r", time() - 86400),
+                'tags' => $store->getConfig('mailgun/general/tag')
+            );
+            
+            $mailgunEvents = $this->mailgunRequest(
+                    'events', 
+                    $store->getConfig('mailgun/general/domain'), 
+                    $store->getConfig('mailgun/general/key'), 
+                    $data
+            );
+            
+            $events = $mailgunEvents->items;
+            
+            while (sizeof($mailgunEvents->items) > 0) {
+                $mailgunEvents = $this->mailgunRequest(
+                    'events', 
+                    $store->getConfig('mailgun/general/domain'), 
+                    $store->getConfig('mailgun/general/key'), 
+                    $data,
+                    Zend_Http_Client::GET,
+                    $mailgunEvents->paging->next    
+                );
+                
+                $events = array_merge($events, $mailgunEvents->items);
+            }
+            
+            $this->storeEvents($events);
+        }
+    }
+    
+    public function storeEvents($events) {
+        foreach($events as $mailgunEvent) {
+            $email = Mage::getModel('freelunchlabs_mailgun/email')->loadByMailgunIdAndRecipient($mailgunEvent->message->headers->{'message-id'}, $mailgunEvent->recipient);
+            
+            if($email->getId()) {
+                $event = Mage::getModel('freelunchlabs_mailgun/event')->loadByTimestampAndEmailId($mailgunEvent->timestamp, $email->getId());
+                
+                if(!$event->getId()) {
+                    $event->setEmailId($email->getId());
+                    $event->setEventType($mailgunEvent->event);
+                    $event->setTimestamp($mailgunEvent->timestamp);
+                    $event->save();
+                }
+            }
+        }
+    }
+    
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php b/app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php
new file mode 100644
index 0000000..5260d03
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Messagebuilder.php
@@ -0,0 +1,296 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Messagebuilder extends Varien_Object {
+
+    const API_USER = "api";
+    const SDK_USER_AGENT = "freelunchlabs_magento_extension";
+    const RECIPIENT_COUNT_LIMIT = 1000;
+    const CAMPAIGN_ID_LIMIT = 3;
+    const TAG_LIMIT = 3;
+    const DEFAULT_TIME_ZONE = "UTC";
+
+    //Common Exception Messages
+    const EXCEPTION_INVALID_CREDENTIALS = "Your credentials are incorrect.";
+    const EXCEPTION_GENERIC_HTTP_ERROR = "An HTTP Error has occurred! Check your network connection and try again.";
+    const EXCEPTION_MISSING_REQUIRED_PARAMETERS = "The parameters passed to the API were invalid. Check your inputs!";
+    const EXCEPTION_MISSING_ENDPOINT = "The endpoint you've tried to access does not exist. Check your URL.";
+    const TOO_MANY_RECIPIENTS = "You've exceeded the maximum recipient count (1,000) on the to field with autosend disabled.";
+    const INVALID_PARAMETER_NON_ARRAY = "The parameter you've passed in position 2 must be an array.";
+    const INVALID_PARAMETER_ATTACHMENT = "Attachments must be passed with an \"@\" preceding the file path. Web resources not supported.";
+    const INVALID_PARAMETER_INLINE = "Inline images must be passed with an \"@\" preceding the file path. Web resources not supported.";
+    const TOO_MANY_PARAMETERS_CAMPAIGNS = "You've exceeded the maximum (3) campaigns for a single message.";
+    const TOO_MANY_PARAMETERS_TAGS = "You've exceeded the maximum (3) tags for a single message.";
+    const TOO_MANY_PARAMETERS_RECIPIENT = "You've exceeded the maximum recipient count (1,000) on the to field with autosend disabled.";
+
+    protected $message = array();
+    protected $variables = array();
+    protected $files = array();
+    protected $counters = array('recipients' => array('to' => 0,
+            'cc' => 0,
+            'bcc' => 0),
+            'attributes' => array('attachment' => 0,
+            'campaign_id' => 0,
+            'custom_option' => 0,
+            'tag' => 0)
+    );
+
+    protected function safeGet($params, $key, $default) {
+        if (array_key_exists($key, $params)) {
+            return $params[$key];
+        }
+        return $default;
+    }
+
+    protected function getFullName($params) {
+        if (array_key_exists("first", $params)) {
+            $first = $this->safeGet($params, "first", "");
+            $last = $this->safeGet($params, "last", "");
+            return trim("$first $last");
+        }
+        return $this->safeGet($params, "full_name", "");
+    }
+
+    protected function parseAddress($address, $variables) {
+        if (!is_array($variables)) {
+            return $address;
+        }
+        $fullName = $this->getFullName($variables);
+        if ($fullName != null) {
+            return "'$fullName' <$address>";
+        }
+        return $address;
+    }
+
+    protected function addRecipient($headerName, $address, $variables) {
+        $compiledAddress = $this->parseAddress($address, $variables);
+
+        if (isset($this->message[$headerName])) {
+            array_push($this->message[$headerName], $compiledAddress);
+        } elseif ($headerName == "h:reply-to") {
+            $this->message[$headerName] = $compiledAddress;
+        } else {
+            $this->message[$headerName] = array($compiledAddress);
+        }
+        if (array_key_exists($headerName, $this->counters['recipients'])) {
+            $this->counters['recipients'][$headerName] += 1;
+        }
+    }
+
+    public function addToRecipient($address, $variables = null) {
+        if ($this->counters['recipients']['to'] > self::RECIPIENT_COUNT_LIMIT) {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(TOO_MANY_PARAMETERS_RECIPIENT);
+        }
+        $this->addRecipient("to", $address, $variables);
+        return end($this->message['to']);
+    }
+
+    public function addCcRecipient($address, $variables = null) {
+        if ($this->counters['recipients']['cc'] > self::RECIPIENT_COUNT_LIMIT) {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(TOO_MANY_PARAMETERS_RECIPIENT);
+        }
+        $this->addRecipient("cc", $address, $variables);
+        return end($this->message['cc']);
+    }
+
+    public function addBccRecipient($address, $variables = null) {
+        if ($this->counters['recipients']['bcc'] > self::RECIPIENT_COUNT_LIMIT) {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(TOO_MANY_PARAMETERS_RECIPIENT);
+        }
+        $this->addRecipient("bcc", $address, $variables);
+        return end($this->message['bcc']);
+    }
+
+    public function setFromAddress($address, $variables = null) {
+        $this->addRecipient("from", $address, $variables);
+        return $this->message['from'];
+    }
+
+    public function setReplyToAddress($address, $variables = null) {
+        $this->addRecipient("h:reply-to", $address, $variables);
+        return $this->message['h:reply-to'];
+    }
+
+    public function setSubject($subject = NULL) {
+        if ($subject == NULL || $subject == "") {
+            $subject = " ";
+        }
+        $this->message['subject'] = $subject;
+        return $this->message['subject'];
+    }
+    
+    public function getSubject() {
+        return $this->message['subject'];
+    }
+
+    public function addCustomHeader($headerName, $headerData) {
+        if (!preg_match("/^h:/i", $headerName)) {
+            $headerName = "h:" . $headerName;
+        }
+        $this->message[$headerName] = array($headerData);
+        return $this->message[$headerName];
+    }
+
+    public function setTextBody($textBody) {
+        if ($textBody == NULL || $textBody == "") {
+            $textBody = " ";
+        }
+        $this->message['text'] = $textBody;
+        return $this->message['text'];
+    }
+
+    public function setHtmlBody($htmlBody) {
+        if ($htmlBody == NULL || $htmlBody == "") {
+            $htmlBody = " ";
+        }
+        $this->message['html'] = $htmlBody;
+        return $this->message['html'];
+    }
+    
+    public function getHtmlBody() {
+        return $this->message['html'];
+    }
+
+    public function addAttachment($attachmentPath, $attachmentName = null) {
+        if (preg_match("/^@/", $attachmentPath)) {
+            if (isset($this->files["attachment"])) {
+                $attachment = array('filePath' => $attachmentPath,
+                    'remoteName' => $attachmentName);
+                array_push($this->files["attachment"], $attachment);
+            } else {
+                $this->files["attachment"] = array(array('filePath' => $attachmentPath,
+                        'remoteName' => $attachmentName));
+            }
+            return true;
+        } else {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_ATTACHMENT);
+        }
+    }
+
+    public function addInlineImage($inlineImagePath, $inlineImageName = null) {
+        if (preg_match("/^@/", $inlineImagePath)) {
+            if (isset($this->files['inline'])) {
+                $inlineAttachment = array('filePath' => $inlineImagePath,
+                    'remoteName' => $inlineImageName);
+                array_push($this->files['inline'], $inlineAttachment);
+            } else {
+                $this->files['inline'] = array(array('filePath' => $inlineImagePath,
+                        'remoteName' => $inlineImageName));
+            }
+            return true;
+        } else {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_INLINE);
+        }
+    }
+
+    public function setTestMode($testMode) {
+        if (filter_var($testMode, self::FILTER_VALIDATE_BOOLEAN)) {
+            $testMode = "yes";
+        } else {
+            $testMode = "no";
+        }
+        $this->message['o:testmode'] = $testMode;
+        return $this->message['o:testmode'];
+    }
+
+    public function addCampaignId($campaignId) {
+        if ($this->counters['attributes']['campaign_id'] < self::CAMPAIGN_ID_LIMIT) {
+            if (isset($this->message['o:campaign'])) {
+                array_push($this->message['o:campaign'], $campaignId);
+            } else {
+                $this->message['o:campaign'] = array($campaignId);
+            }
+            $this->counters['attributes']['campaign_id'] += 1;
+            return $this->message['o:campaign'];
+        } else {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(self::TOO_MANY_PARAMETERS_CAMPAIGNS);
+        }
+    }
+
+    public function addTag($tag) {
+        if ($this->counters['attributes']['tag'] < self::TAG_LIMIT) {
+            if (isset($this->message['o:tag'])) {
+                array_push($this->message['o:tag'], $tag);
+            } else {
+                $this->message['o:tag'] = array($tag);
+            }
+            $this->counters['attributes']['tag'] += 1;
+            return $this->message['o:tag'];
+        } else {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_TooManyParameters(self::TOO_MANY_PARAMETERS_TAGS);
+        }
+    }
+
+    public function setDkim($enabled) {
+        if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) {
+            $enabled = "yes";
+        } else {
+            $enabled = "no";
+        }
+        $this->message["o:dkim"] = $enabled;
+        return $this->message["o:dkim"];
+    }
+
+    public function setOpenTracking($enabled) {
+        if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) {
+            $enabled = "yes";
+        } else {
+            $enabled = "no";
+        }
+        $this->message['o:tracking-opens'] = $enabled;
+        return $this->message['o:tracking-opens'];
+    }
+
+    public function setClickTracking($enabled) {
+        if (filter_var($enabled, FILTER_VALIDATE_BOOLEAN)) {
+            $enabled = "yes";
+        } elseif ($enabled == "html") {
+            $enabled = "html";
+        } else {
+            $enabled = "no";
+        }
+        $this->message['o:tracking-clicks'] = $enabled;
+        return $this->message['o:tracking-clicks'];
+    }
+
+    public function setDeliveryTime($timeDate, $timeZone = NULL) {
+        if (isset($timeZone)) {
+            $timeZoneObj = new DateTimeZone("$timeZone");
+        } else {
+            $timeZoneObj = new DateTimeZone(self::DEFAULT_TIME_ZONE);
+        }
+
+        $dateTimeObj = new DateTime($timeDate, $timeZoneObj);
+        $formattedTimeDate = $dateTimeObj->format(DateTime::RFC2822);
+        $this->message['o:deliverytime'] = $formattedTimeDate;
+        return $this->message['o:deliverytime'];
+    }
+
+    public function addCustomData($customName, $data) {
+        if (is_array($data)) {
+            $jsonArray = json_encode($data);
+            $this->message['v:' . $customName] = $jsonArray;
+            return $this->message['v:' . $customName];
+        } else {
+            throw new FreeLunchLabs_MailGun_Model_Exceptions_InvalidParameter(self::INVALID_PARAMETER_NON_ARRAY);
+        }
+    }
+
+    public function addCustomParameter($parameterName, $data) {
+        if (isset($this->message[$parameterName])) {
+            array_push($this->message[$parameterName], $data);
+            return $this->message[$parameterName];
+        } else {
+            $this->message[$parameterName] = array($data);
+            return $this->message[$parameterName];
+        }
+    }
+
+    public function getMessage() {
+        return $this->message;
+    }
+
+    public function getFiles() {
+        return $this->files;
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email.php b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email.php
new file mode 100644
index 0000000..c7926f5
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email.php
@@ -0,0 +1,26 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Resource_Email extends Mage_Core_Model_Resource_Db_Abstract
+{
+    protected function _construct()
+    {
+        $this->_init('freelunchlabs_mailgun/email', 'id');
+    }
+
+    public function deleteEmailTrackingLogs($days = false) {
+        if($days) {   
+            $daysPrior = date("Y-m-d H:i:s", Mage::getModel('core/date')->timestamp(time() - (86400 * $days)));
+            $where = " WHERE date_sent < '{$daysPrior}'";
+        } else {
+            $where = "";
+        }
+     
+        $query = "DELETE FROM {$this->getMainTable()}" . $where;
+
+        Mage::getSingleton('core/resource')
+                ->getConnection('core_write')
+                ->query($query);
+ 
+    }
+    
+}
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email/Collection.php b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email/Collection.php
new file mode 100644
index 0000000..3e0b54b
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Email/Collection.php
@@ -0,0 +1,38 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Resource_Email_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    protected function _construct()
+    {
+        parent::_construct();
+
+        $this->_init('freelunchlabs_mailgun/email');
+    }
+    
+    public function getGridCollection() {
+        //Fields
+        $this->addFieldToSelect('id');
+        $this->addFieldToSelect('subject');
+        $this->addFieldToSelect('email_address');
+        $this->addFieldToSelect('mailgun_id');
+        $this->addFieldToSelect('date_sent');
+        $this->addFieldToSelect('customer_id');
+        
+        //Get latest status
+        $this->getSelect()->joinLeft(
+            array('me1' => Mage::getResourceModel('freelunchlabs_mailgun/event')->getMainTable()),
+            'main_table.id = me1.email_id',
+            'event_type as current_status'
+        );
+        
+        $this->getSelect()->joinLeft(
+            array('me2' => Mage::getResourceModel('freelunchlabs_mailgun/event')->getMainTable()),
+            '(main_table.id = me2.email_id AND (me1.timestamp < me2.timestamp OR me1.timestamp = me2.timestamp AND me1.id < me2.id))',
+            false    
+        );
+        
+        $this->getSelect()->where('me2.id IS NULL');
+        
+        return $this;
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event.php b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event.php
new file mode 100644
index 0000000..8296cd2
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event.php
@@ -0,0 +1,10 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Resource_Event extends Mage_Core_Model_Resource_Db_Abstract
+{
+    protected function _construct()
+    {
+        $this->_init('freelunchlabs_mailgun/event', 'id');
+    }
+    
+}
diff --git a/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event/Collection.php b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event/Collection.php
new file mode 100644
index 0000000..3e0cf86
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/Model/Resource/Event/Collection.php
@@ -0,0 +1,11 @@
+<?php
+
+class FreeLunchLabs_MailGun_Model_Resource_Event_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
+{
+    protected function _construct()
+    {
+        parent::_construct();
+
+        $this->_init('freelunchlabs_mailgun/event');
+    }
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/controllers/Adminhtml/EmailtrackingController.php b/app/code/community/FreeLunchLabs/MailGun/controllers/Adminhtml/EmailtrackingController.php
new file mode 100644
index 0000000..4a0af6d
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/controllers/Adminhtml/EmailtrackingController.php
@@ -0,0 +1,96 @@
+<?php
+
+class FreeLunchLabs_MailGun_Adminhtml_EmailtrackingController extends Mage_Adminhtml_Controller_Action {
+
+    protected function _initCustomer($idFieldName = 'id')
+    {
+        $this->_title($this->__('Customers'))->_title($this->__('Manage Customers'));
+
+        $customerId = (int) $this->getRequest()->getParam($idFieldName);
+        $customer = Mage::getModel('customer/customer');
+
+        if ($customerId) {
+            $customer->load($customerId);
+        }
+
+        Mage::register('current_customer', $customer);
+        return $this;
+    }
+    
+    protected function _initEmail($idFieldName = 'id') {
+        $emailId = (int) $this->getRequest()->getParam($idFieldName);
+        $email = Mage::getModel('freelunchlabs_mailgun/email');  
+
+        if ($emailId) {
+            $email->load($emailId);
+        }
+
+        Mage::register('current_email', $email);
+        return $this;
+    } 
+
+    public function emailGridAction()
+    {
+        $this->_initCustomer();
+        $this->loadLayout();
+        $gridBlock = $this->getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_customer_email');
+        
+        $this->getResponse()->setBody($gridBlock->getGridHtml());
+    }
+    
+    public function indexAction() {
+        $this->_title($this->__('System'))->_title($this->__('Email Tracking'));
+        
+        $this->loadLayout();      
+        $this->_setActiveMenu('customer');
+        $this->renderLayout();
+    }
+    
+    public function emailDetailAction() {
+        $this->_title($this->__('System'))->_title($this->__('Email Tracking - Detail'));
+        
+        $this->_initEmail();
+        
+        $this->loadLayout();      
+        $this->_setActiveMenu('customer');
+        $this->renderLayout();
+    }
+    
+    public function getEmailEventsAction() {
+        Mage::getModel('freelunchlabs_mailgun/mailgun')->processEmailEventsForAllStores();
+
+        $this->_getSession()->addSuccess(
+            Mage::helper('adminhtml')->__('Past 24 hours of email events fetched.')
+        );
+
+        $this->_redirect('*/*');
+    }
+    
+    public function emailViewAction() {
+        $this->_title($this->__('System'))->_title($this->__('Email Tracking - Detail - Email Body'));
+        $this->_initEmail();
+   
+        $this->getResponse()->setBody(Mage::registry('current_email')->getBody());
+    }
+    
+    public function deleteEmailTrackingLogsDaysAction() {
+        Mage::getModel('freelunchlabs_mailgun/email')->deleteEmailTrackingLogsDays();
+
+        $this->_getSession()->addSuccess(
+            Mage::helper('adminhtml')->__('Email records older than ' . Mage::getStoreConfig('mailgun/events/days') . ' days were deleted.')
+        );
+
+        $this->_redirect('*/*');
+    }
+    
+    public function deleteEmailTrackingLogsAction() {
+        Mage::getModel('freelunchlabs_mailgun/email')->deleteEmailTrackingLogs();
+
+        $this->_getSession()->addSuccess(
+            Mage::helper('adminhtml')->__('All Email Records Were Deleted.')
+        );
+
+        $this->_redirect('*/*');
+    }
+
+}
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/etc/config.xml b/app/code/community/FreeLunchLabs/MailGun/etc/config.xml
new file mode 100644
index 0000000..4c378e1
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/etc/config.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0"?>
+<config>
+    <modules>
+        <FreeLunchLabs_MailGun>
+            <version>1.0.0</version>
+        </FreeLunchLabs_MailGun>
+    </modules>
+    <global>
+        <models>
+            <freelunchlabs_mailgun>
+                <class>FreeLunchLabs_MailGun_Model</class>
+                <resourceModel>freelunchlabs_mailgun_resource</resourceModel>
+            </freelunchlabs_mailgun>
+            <core>
+                <rewrite>
+                    <email_template>FreeLunchLabs_MailGun_Model_Email_Template</email_template>
+                </rewrite>
+            </core>
+            <freelunchlabs_mailgun_resource>
+                <class>FreeLunchLabs_MailGun_Model_Resource</class>
+                <entities>
+                    <email>
+                        <table>mailgun_email_tracking</table>
+                    </email>
+                    <event>
+                        <table>mailgun_email_tracking_event</table>
+                    </event>
+                </entities>
+            </freelunchlabs_mailgun_resource>
+        </models>
+        <resources>
+            <mailgun_setup>
+                <setup>
+                    <module>FreeLunchLabs_MailGun</module>
+                </setup>
+                <connection>
+                    <use>core_setup</use>
+                </connection>
+            </mailgun_setup>
+            <mailgun_write>
+                <connection>
+                    <use>core_write</use>
+                </connection>
+            </mailgun_write>
+            <mailgun_read>
+                <connection>
+                    <use>core_read</use>
+                </connection>
+            </mailgun_read>
+        </resources>
+        <helpers>
+            <mailgun>
+                <class>FreeLunchLabs_MailGun_Helper</class>
+            </mailgun>
+        </helpers>
+        <blocks>
+            <freelunchlabs_mailgun>
+                <class>FreeLunchLabs_MailGun_Block</class>
+            </freelunchlabs_mailgun>
+        </blocks>
+    </global>
+    <admin>
+        <routers>
+            <adminhtml>
+                <args>
+                    <modules>
+                        <freelunchlabs_mailgun before="Mage_Adminhtml">FreeLunchLabs_MailGun_Adminhtml</freelunchlabs_mailgun>
+                    </modules>
+                </args>
+            </adminhtml>
+        </routers>
+    </admin>
+    <adminhtml>
+        <menu>
+            <customer>
+                <children>
+                    <cloudfront translate="title" module="mailgun">
+                        <title>Email Tracking</title>
+                        <sort_order>9999</sort_order>
+                        <action>adminhtml/emailtracking</action>
+                    </cloudfront>
+                </children>
+            </customer>
+        </menu>
+        <acl>
+            <resources>
+                <admin>
+                    <children>
+                        <system>
+                            <children>
+                                <config>
+                                    <children>
+                                        <mailgun translate="title" module="mailgun">
+                                            <title>MailGun Configuration</title>
+                                            <sort_order>50</sort_order>
+                                        </mailgun>
+                                    </children>
+                                </config>
+                                <emailtracking>
+                                    <title>Email Tracking</title>
+                                    <sort_order>70</sort_order>
+                                </emailtracking>
+                            </children>
+                        </system>
+                    </children>
+                </admin>
+            </resources>
+        </acl>
+        <layout>
+            <updates>
+                <mailgun>
+                    <file>mailgun.xml</file>
+                </mailgun>
+            </updates>
+        </layout>
+    </adminhtml>
+    <default>
+        <mailgun>
+            <general>
+                <active>0</active>
+                <tag>magento-store</tag>
+            </general>
+            <events>
+                <store>1</store>
+                <days>30</days>
+                <clicks>1</clicks>
+                <opens>1</opens>
+            </events>
+        </mailgun>
+    </default>
+    <crontab>
+        <jobs>
+            <freelunchlabs_purgelogs>
+                <schedule>
+                    <cron_expr>0,15,30,45 * * * *</cron_expr>
+                </schedule>
+                <run>
+                    <model>freelunchlabs_mailgun/email::deleteEmailTrackingLogsDays</model>
+                </run>
+            </freelunchlabs_purgelogs>
+            <freelunchlabs_processevents>
+                <schedule>
+                    <cron_expr>0,15,30,45 * * * *</cron_expr>
+                </schedule>
+                <run>
+                    <model>freelunchlabs_mailgun/mailgun::processEmailEventsForAllStores</model>
+                </run>
+            </freelunchlabs_processevents>
+        </jobs>
+    </crontab>
+</config>
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/etc/system.xml b/app/code/community/FreeLunchLabs/MailGun/etc/system.xml
new file mode 100644
index 0000000..ca2a4b9
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/etc/system.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<config>
+    <sections>
+        <mailgun translate="label" module="mailgun">
+            <class>separator-top</class>
+            <label>MailGun Configuration</label>
+            <tab>general</tab>
+            <sort_order>110</sort_order>
+            <show_in_default>1</show_in_default>
+            <show_in_website>1</show_in_website>
+            <show_in_store>1</show_in_store>
+            <groups>
+                <general translate="label comment">
+                    <label>MailGun Configuration</label>
+                    <frontend_type>text</frontend_type>
+                    <sort_order>1</sort_order>
+                    <show_in_default>1</show_in_default>
+                    <show_in_website>0</show_in_website>
+                    <show_in_store>1</show_in_store>
+                    <fields>
+                        <active translate="label comment">
+                            <label>Enabled MailGun For Sending Emails</label>
+                            <frontend_type>select</frontend_type>
+                            <source_model>adminhtml/system_config_source_yesno</source_model>
+                            <sort_order>1</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store>1</show_in_store>
+                        </active>
+                        <key translate="label comment">
+                            <label>MailGun API Key</label>
+                            <frontend_type>password</frontend_type>
+                            <sort_order>3</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store>1</show_in_store>
+                            <comment>Your MailGun API Key</comment>
+                        </key>
+                        <domain translate="label comment">
+                            <label>Sending Domain</label>
+                            <frontend_type>text</frontend_type>
+                            <sort_order>4</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store>1</show_in_store>
+                            <comment>Your verified sending domain. For example, "example.com", "email.example.com"</comment>
+                        </domain>
+                        <tag translate="label comment">
+                            <label>Email Tag</label>
+                            <frontend_type>text</frontend_type>
+                            <sort_order>5</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store>1</show_in_store>
+                            <comment>For Administrative purposes only. This tag is used for filtering emails in MailGun.</comment>
+                        </tag>
+                    </fields>
+                </general>
+                <events translate="label">
+                    <label>Email Tracking</label>
+                    <frontend_type>text</frontend_type>
+                    <sort_order>2</sort_order>
+                    <show_in_default>1</show_in_default>
+                    <show_in_website>1</show_in_website>
+                    <show_in_store>1</show_in_store>
+                    <fields>
+                        <store translate="label comment">
+                            <label>Track All Emails</label>
+                            <frontend_type>select</frontend_type>
+                            <source_model>adminhtml/system_config_source_yesno</source_model>
+                            <sort_order>1</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store>1</show_in_store>
+                            <comment>Keep a record of all transactional emails sent.</comment>
+                        </store>
+                        <days translate="label comment">
+                            <label>Days To Save Email Records</label>
+                            <frontend_type>text</frontend_type>
+                            <sort_order>2</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>0</show_in_website>
+                            <show_in_store>0</show_in_store>
+                            <comment>Days to save email records. Leave blank for indefinitely.</comment>
+                        </days>
+                        <clicks translate="label comment">
+                            <label>Enabled Click Tracking</label>
+                            <frontend_type>select</frontend_type>
+                            <source_model>adminhtml/system_config_source_yesno</source_model>
+                            <sort_order>3</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store >1</show_in_store>
+                            <comment>Keep track of every time a recipient clicks on links in your messages. Links will be overwritten and pointed to MailGun servers so they can track clicks.</comment>
+                        </clicks>
+                        <opens translate="label comment">
+                            <label>Enabled Open Tracking</label>
+                            <frontend_type>select</frontend_type>
+                            <source_model>adminhtml/system_config_source_yesno</source_model>
+                            <sort_order>4</sort_order>
+                            <show_in_default>1</show_in_default>
+                            <show_in_website>1</show_in_website>
+                            <show_in_store>1</show_in_store>
+                            <comment>Keep track of every time a recipient opens your messages. Opens are tracked by including a transparent .png file in you email.</comment>
+                        </opens>
+                    </fields>
+                </events>
+            </groups>
+        </mailgun>
+    </sections>
+</config>
\ No newline at end of file
diff --git a/app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-install-1.0.0.php b/app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-install-1.0.0.php
new file mode 100644
index 0000000..0fd7ebc
--- /dev/null
+++ b/app/code/community/FreeLunchLabs/MailGun/sql/mailgun_setup/mysql4-install-1.0.0.php
@@ -0,0 +1,33 @@
+<?php
+
+$installer = $this;
+
+$installer->startSetup();
+
+$installer->run("
+ 
+-- DROP TABLE IF EXISTS {$this->getTable('freelunchlabs_mailgun/email')};
+CREATE TABLE {$this->getTable('freelunchlabs_mailgun/email')} (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `customer_id` int(11) NULL,
+  `mailgun_id` varchar(255) NOT NULL default '',
+  `email_address` varchar(255) NOT NULL default '',
+  `subject` text,
+  `body` text,
+  `date_sent` timestamp NOT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- DROP TABLE IF EXISTS {$this->getTable('freelunchlabs_mailgun/event')};
+CREATE TABLE {$this->getTable('freelunchlabs_mailgun/event')} (
+  `id` int(11) unsigned NOT NULL auto_increment,
+  `email_id` int(11) NULL,
+  `event_type` varchar(255) NOT NULL default '',
+  `timestamp` varchar(255)
+  PRIMARY KEY (`id`),
+  CONSTRAINT `fk_event_tracking` FOREIGN KEY (`email_id`) REFERENCES `{$this->getTable('freelunchlabs_mailgun/email')}` (`id`) ON DELETE CASCADE
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+");
+
+$installer->endSetup();
\ No newline at end of file
diff --git a/app/design/adminhtml/default/default/layout/mailgun.xml b/app/design/adminhtml/default/default/layout/mailgun.xml
new file mode 100644
index 0000000..dfe2f66
--- /dev/null
+++ b/app/design/adminhtml/default/default/layout/mailgun.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<layout>
+    <adminhtml_customer_edit>
+        <reference name="customer_edit_tabs">
+            <action method="addTab">
+                <name>customer_tab_mailgun</name>
+                <block>freelunchlabs_mailgun/adminhtml_customer_tab_mailgun</block>
+            </action>
+        </reference>
+    </adminhtml_customer_edit>
+    <adminhtml_emailtracking_index>
+        <reference name="content">
+            <block type="freelunchlabs_mailgun/adminhtml_emailtracking" name="emailtracking" template="mailgun/globalemailgrid.phtml"></block>
+        </reference>
+    </adminhtml_emailtracking_index>
+    <adminhtml_emailtracking_emaildetail>
+        <reference name="content">
+            <block type="freelunchlabs_mailgun/adminhtml_emailtracking" name="emailtracking" template="mailgun/emaildetail.phtml"></block>
+        </reference>
+    </adminhtml_emailtracking_emaildetail>
+</layout>
\ No newline at end of file
diff --git a/app/design/adminhtml/default/default/template/mailgun/customer/tab/tab.phtml b/app/design/adminhtml/default/default/template/mailgun/customer/tab/tab.phtml
new file mode 100644
index 0000000..84dd32d
--- /dev/null
+++ b/app/design/adminhtml/default/default/template/mailgun/customer/tab/tab.phtml
@@ -0,0 +1 @@
+<?php echo $this->getGrid(); ?>
\ No newline at end of file
diff --git a/app/design/adminhtml/default/default/template/mailgun/emaildetail.phtml b/app/design/adminhtml/default/default/template/mailgun/emaildetail.phtml
new file mode 100644
index 0000000..eff3597
--- /dev/null
+++ b/app/design/adminhtml/default/default/template/mailgun/emaildetail.phtml
@@ -0,0 +1,90 @@
+<?php $_emailDetail = $this->getEmailDetail(); ?>
+<div class="content-header">
+    <table cellspacing="0">
+        <tr>
+            <td>
+                <h3><?php echo Mage::helper('adminhtml')->__('Email Details') ?></h3>
+            </td>
+            <td class="form-buttons">
+                <?php echo $this->getBackButtonHtml(); ?>
+                <?php echo $this->getViewEmailBodyButtonHtml($_emailDetail->getId()); ?>
+            </td>
+        </tr>
+    </table>
+</div>
+<div class="box-left">
+    <div class="entry-edit">
+        <div class="entry-edit-head">
+            <h4 class="icon-head head-account"><?php echo Mage::helper('adminhtml')->__('Email Information') ?></h4>
+        </div>
+        <div class="fieldset">
+            <table cellspacing="0" class="form-list">
+                <tbody>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Date Sent') ?></label></td>
+                        <td class="value"><strong><?php echo Mage::helper('core')->formatDate($_emailDetail->getDateSent(), 'full', true); ?></strong></td>
+                    </tr>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Subject') ?></label></td>
+                        <td class="value"><strong><?php echo $_emailDetail->getSubject(); ?></strong></td>
+                    </tr>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Mailgun ID') ?></label></td>
+                        <td class="value"><strong><?php echo $_emailDetail->getMailgunId(); ?></strong></td>
+                    </tr>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Recipient') ?></label></td>
+                        <td class="value"><strong><?php echo $_emailDetail->getEmailAddress(); ?></strong></td>
+                    </tr>
+                </tbody>
+            </table>
+        </div>
+    </div>
+</div>
+<div class="box-right">
+    <div class="entry-edit">
+        <div class="entry-edit-head">
+            <h4 class="icon-head head-account"><?php echo Mage::helper('adminhtml')->__('Customer Information') ?></h4>
+        </div>
+        <div class="fieldset">
+            <?php if($_emailDetail->getCustomer()): ?>
+            <table cellspacing="0" class="form-list">
+                <tbody>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Customer') ?></label></td>
+                        <td class="value">
+                            <a href="<?php echo $this->getEditCustomerUrl($_emailDetail->getCustomer()->getId()); ?>" title="Edit Customer">
+                                <strong><?php echo $_emailDetail->getCustomer()->getName(); ?></strong>
+                            </a>
+                        </td>  
+                    </tr>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Store') ?></label></td>
+                        <td class="value"><strong><?php echo $_emailDetail->getCustomer()->getStore()->getName(); ?></strong></td>
+                    </tr>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Customer Group') ?></label></td>
+                        <td class="value"><strong><?php echo $this->getCustomerGroupName($_emailDetail->getCustomer()->getGroupId()); ?></strong></td>
+                    </tr>
+                    <tr>
+                        <td class="label"><label><?php echo Mage::helper('adminhtml')->__('Customer Since') ?></label></td>
+                        <td class="value"><strong><?php echo $this->formatCustomerCreateDate($_emailDetail->getCustomer()->getCreatedAt()); ?></strong></td>
+                    </tr>
+                </tbody>
+            </table>
+            <?php else: ?>
+            <p>No Customer Data Available.</p>
+            <?php endif; ?>
+        </div>
+    </div>
+</div>
+<div class="content-header">
+    <table cellspacing="0">
+        <tr>
+            <td>
+                <h3><?php echo Mage::helper('adminhtml')->__('Email Events') ?></h3>
+            </td>
+        </tr>
+    </table>
+</div>
+<?php echo $this->getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_event_container')->getGridHtml(); ?>
diff --git a/app/design/adminhtml/default/default/template/mailgun/globalemailgrid.phtml b/app/design/adminhtml/default/default/template/mailgun/globalemailgrid.phtml
new file mode 100644
index 0000000..d3a8452
--- /dev/null
+++ b/app/design/adminhtml/default/default/template/mailgun/globalemailgrid.phtml
@@ -0,0 +1,15 @@
+<div class="content-header">
+    <table cellspacing="0">
+        <tr>
+            <td>
+                <h3><?php echo Mage::helper('adminhtml')->__('Email Activity') ?></h3>
+            </td>
+            <td class="form-buttons">
+                <?php echo $this->getFetch24HoursOfEmailActivityButton(); ?>
+                <?php echo $this->getDeleteEmailTrackingLogsDaysButton(); ?>
+                <?php echo $this->getDeleteAllEmailTrackingLogsButton(); ?>
+            </td>
+        </tr>
+    </table>
+</div>
+<?php echo $this->getLayout()->createBlock('freelunchlabs_mailgun/adminhtml_global_container')->getGridHtml(); ?>
\ No newline at end of file
diff --git a/app/etc/modules/FreeLunchLabs_MailGun.xml b/app/etc/modules/FreeLunchLabs_MailGun.xml
new file mode 100644
index 0000000..b1e245f
--- /dev/null
+++ b/app/etc/modules/FreeLunchLabs_MailGun.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<config>
+    <modules>
+        <FreeLunchLabs_MailGun>
+            <active>true</active>
+            <codePool>community</codePool>
+        </FreeLunchLabs_MailGun>
+    </modules>
+</config>
-- 
GitLab