-
-
Save dammyammy/142a7d02cbdc4dda9bcbe8bd0f76b415 to your computer and use it in GitHub Desktop.
Setting up Sendy with Laravel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Setting up Sendy with Laravel | |
(there might be bugs, I striped out some parts of my code because what I have is more complicated then that, so, sorry if it's broken!) | |
-- | |
I would recommand creating a database for Sendy only. | |
Add Sendy's database into your database.php (1) | |
Create the Campaign model (2), and specify that you want to use Sendy's database (Campaigns are the only thing we really need to create, other things like creating lists can be done through Sendy interface, and there is a PHP library to add subscribers) | |
Now, it's time to install Sendy, usually somewhere like yourapp.com/sendy or yourapp.com/newsletter | |
Following those instructions should do the trick : http://sendy.co/get-started | |
The Amazon part takes time. You will have to verify your domain and all. While you wait for your domain to authenticate, you can do the rest of the code (3, 4, 5, 6). | |
There would be a lot to say, but I think that my code will speak for itself. I have a lot of functions as I have multiple templates and that my app is bilingual, but that should help! | |
You have to setup cronjob for Sendy if you want to schedule your newsletter. Create a dummy newsletter form Sendy, then you will see the Schedule button and instructions about how to setup that! | |
If you want, I've included the code (7 and 8) so you can run "php artisan newsletter:generate" and tadam! You can also run a cronjob to trigger it, that's magic, I know. More on that here : http://stackoverflow.com/questions/16374513/cron-job-in-laravel | |
And if you want to read about the Sendy PHP Library used into SendyLibrary.php (5) : https://github.com/JacobBennett/SendyPHPLibrary |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app/config/database.php | |
<?php | |
return array( | |
'connections' => array( | |
'mysql' => array( | |
'driver' => 'mysql', | |
'host' => 'localhost', | |
'database' => 'laravel', | |
'username' => 'username', | |
'password' => 'password', | |
'charset' => 'utf8', | |
'collation' => 'utf8_unicode_ci', | |
'prefix' => '', | |
), | |
'newsletter' => array( | |
'driver' => 'mysql', | |
'host' => 'localhost', | |
'database' => 'sendy', | |
'username' => 'username', | |
'password' => 'password', | |
'charset' => 'utf8', | |
'collation' => 'utf8_unicode_ci', | |
'prefix' => '', | |
), | |
) | |
); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app/model/campaign.php | |
<?php | |
class Campaign extends Eloquent { | |
protected $connection = 'newsletter'; | |
public $timestamps = false; | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app/Acme/Newsletter/Sendy.php | |
<?php namespace Acme\Newsletter; | |
use App; | |
use Campaign; | |
use Carbon; | |
class Sendy extends Newsletter { | |
// The id and key of your list can be found once you created a new list through Sendy. Each list has a custom "key" (like : fsakjbfa2r3tg) and id (like : 1) If you have multiple lists, you could use an array or fetch it from Sendy database. | |
private $list_id = array(1 => "rbcNeGuRfff4e0sDJds5brQ"); | |
/** | |
* Subscribe a user to a list | |
* | |
* @param string $email | |
* | |
* @return string | |
*/ | |
public function subscribe($email){ | |
$sendy = new SendyLibrary($this->list_id[1]); | |
$result = $sendy->subscribe(array( | |
'email' => $email | |
)); | |
return $result['message']; | |
} | |
/** | |
* A user can usubscribe from a list following the link generated with the <unsubscribe> tag into a newsletter | |
/** | |
* Create the campaign | |
* | |
* @return bool | |
*/ | |
public function create() | |
{ | |
$data = $this->generateHTML(); | |
$campaign = new Campaign(); | |
$campaign->userID = 1; | |
$campaign->app = 1; | |
$campaign->from_name = "Your name"; | |
$campaign->from_email = "[email protected]"; | |
$campaign->reply_to = "[email protected]"; | |
$campaign->title = $data['title']; | |
$campaign->html_text = $data['html']; | |
$campaign->wysiwyg = 0; | |
// Use your timezone! | |
$campaign->timezone = "America/Montreal"; | |
// You can target multiple lists with an array of ids, like array(1,3,7) | |
$campaign->lists = 1; | |
// That will schedule your newsletter to send in 5mn, so you can have a quick look before it goes live | |
$campaign->send_date = Carbon::now()->addMinutes(5)->timestamp; | |
if($campaign->save()){ | |
return true; | |
} | |
return false; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app/Acme/Newsletter/SendyLibrary.php | |
<?php | |
namespace Acme\Newsletter; | |
class SendyLibrary | |
{ | |
private $installation_url = 'http://yourapp.com/sendy'; | |
private $api_key = 'your_api_key'; | |
private $list_id; | |
function __construct($list_id) | |
{ | |
//error checking | |
if (!isset($list_id)) {throw new Exception("Required config parameter [list_id] is not set", 1);} | |
if (!isset($this->installation_url)) {throw new Exception("Required config parameter [installation_url] is not set", 1);} | |
if (!isset($this->api_key)) {throw new Exception("Required config parameter [api_key] is not set", 1);} | |
$this->list_id = $list_id; | |
} | |
public function subscribe(array $values) { | |
$type = 'subscribe'; | |
//Send the subscribe | |
$result = strval($this->buildAndSend($type, $values)); | |
//Handle results | |
switch ($result) { | |
case '1': | |
return array( | |
'status' => true, | |
'message' => 'Subscribed' | |
); | |
break; | |
case 'Already subscribed.': | |
return array( | |
'status' => true, | |
'message' => 'Already subscribed.' | |
); | |
break; | |
default: | |
return array( | |
'status' => false, | |
'message' => $result | |
); | |
break; | |
} | |
} | |
public function unsubscribe($email) { | |
$type = 'unsubscribe'; | |
//Send the unsubscribe | |
$result = strval($this->buildAndSend($type, array('email' => $email))); | |
//Handle results | |
switch ($result) { | |
case '1': | |
return array( | |
'status' => true, | |
'message' => 'Unsubscribed' | |
); | |
break; | |
default: | |
return array( | |
'status' => false, | |
'message' => $result | |
); | |
break; | |
} | |
} | |
public function substatus($email) { | |
$type = 'api/subscribers/subscription-status.php'; | |
//Send the request for status | |
$result = $this->buildAndSend($type, array('email' => $email, 'api_key' => $this->api_key, 'list_id' => $this->list_id)); | |
//Handle the results | |
switch ($result) { | |
case 'Subscribed': | |
case 'Unsubscribed': | |
case 'Unconfirmed': | |
case 'Bounced': | |
case 'Soft bounced': | |
case 'Complained': | |
return array( | |
'status' => true, | |
'message' => $result | |
); | |
break; | |
default: | |
return array( | |
'status' => false, | |
'message' => $result | |
); | |
break; | |
} | |
} | |
public function subcount($list = "") { | |
$type = 'api/subscribers/active-subscriber-count.php'; | |
//handle exceptions | |
if($list== "" && $this->list_id == "") {throw new Exception("method [subcount] requires parameter [list] or [$this->list_id] to be set.", 1);} | |
//if a list is passed in use it, otherwise use $this->list_id | |
if($list == "") {$list = $this->list_id;} | |
//Send request for subcount | |
$result = $this->buildAndSend($type, array('api_key' => $this->api_key, 'list_id' => $list)); | |
//Handle the results | |
if (is_int($result)) { | |
return array( | |
'status' => true, | |
'message' => $result | |
); | |
} | |
//Error | |
return array( | |
'status' => false, | |
'message' => $result | |
); | |
} | |
private function buildAndSend($type, array $values) { | |
//error checking | |
if (!isset($type)) {throw new Exception("Required config parameter [type] is not set", 1);} | |
if (!isset($values)) {throw new Exception("Required config parameter [values] is not set", 1);} | |
//Global options for return | |
$return_options = array( | |
'list' => $this->list_id, | |
'boolean' => 'true' | |
); | |
//Merge the passed in values with the options for return | |
$content = array_merge($values, $return_options); | |
//build a query using the $content | |
$postdata = http_build_query($content); | |
$opts = array('http' => array('method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => $postdata)); | |
$context = stream_context_create($opts); | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_POST, true); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata ); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //Set curl to return the data instead of printing it to the browser. | |
curl_setopt($ch, CURLOPT_URL, $this->installation_url .'/'. $type); | |
$data = curl_exec($ch); | |
curl_close($ch); | |
return $data; | |
$result = file_get_contents($this->installation_url .'/'. $type, false, $context); | |
return $result; | |
} | |
/** | |
* Magic methods below | |
* http://www.php.net/manual/en/language.oop5.overloading.php | |
*/ | |
public function __get($property) { | |
if (property_exists($this, $property)) { | |
return $this->$property; | |
} | |
} | |
public function __set($property, $value) { | |
if (property_exists($this, $property)) { | |
$this->$property = $value; | |
} | |
return $this; | |
} | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app/Acme/Newsletter/template/template.blade.php | |
I'd recommand starting with http://zurb.com/playground/responsive-email-templates or http://zurb.com/ink/ | |
Create your HTML page that will be send as your newsletter! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app/start/artisan.php | |
<?php | |
Artisan::add(new GenerateNewsletter); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment