A PHP library for the Campaign Monitor API

Overview

createsend Build Status

A PHP library which implements the complete functionality of the Campaign Monitor API.

Installation

Composer

If you use Composer, you can run the following command from the root of your project:

composer require campaignmonitor/createsend-php

Or add campaignmonitor/createsend-php to your composer.json file:

{
    "require": {
        "campaignmonitor/createsend-php": "{version}"
    }
}

Followed by running:

composer update

Manual Installation

Otherwise you can simply download the library and include it in your project.

After you have installed the library, simply include the relevant API class, as follows:

require_once 'csrest_campaigns.php'

Authenticating

The Campaign Monitor API supports authentication using either OAuth or an API key.

Using OAuth

Depending on the environment you are developing in, you may wish to use a PHP OAuth library to get access tokens for your users. If you don't use an OAuth library, you will need to get access tokens for your users by following the instructions included in the Campaign Monitor API documentation. This package provides functionality to help you do this, as described below. You may also wish to reference this example application, which is implemented using Slim but could easily be adapted for use with any PHP framework.

The first thing your application should do is redirect your user to the Campaign Monitor authorization URL where they will have the opportunity to approve your application to access their Campaign Monitor account. You can get this authorization URL by using the CS_REST_General::authorize_url() method, like so:

require_once 'csrest_general.php';

$authorize_url = CS_REST_General::authorize_url(
    'Client ID for your application',
    'Redirect URI for your application',
    'The permission level your application requires',
    'Optional state data to be included'
);
# Redirect your users to $authorize_url.

If your user approves your application, they will then be redirected to the redirect_uri you specified, which will include a code parameter, and optionally a state parameter in the query string. Your application should implement a handler which can exchange the code passed to it for an access token, using CS_REST_General::exchange_token() like so:

require_once 'csrest_general.php';

$result = CS_REST_General::exchange_token(
    'Client ID for your application',
    'Client Secret for your application',
    'Redirect URI for your application',
    'A unique code for your user' # Get the code parameter from the query string
);

if ($result->was_successful()) {
    $access_token = $result->response->access_token;
    $expires_in = $result->response->expires_in;
    $refresh_token = $result->response->refresh_token;
    # Save $access_token, $expires_in, and $refresh_token.
} else {
    echo 'An error occurred:\n';
    echo $result->response->error.': '.$result->response->error_description."\n";
    # Handle error...
}

At this point you have an access token and refresh token for your user which you should store somewhere convenient so that your application can look up these values when your user wants to make future Campaign Monitor API calls.

Once you have an access token and refresh token for your user, you can authenticate and make further API calls like so:

require_once 'csrest_general.php';

$auth = array(
    'access_token' => 'your access token',
    'refresh_token' => 'your refresh_token');
$wrap = new CS_REST_General($auth);

$result = $wrap->get_clients();
var_dump($result->response);

All OAuth tokens have an expiry time, and can be renewed with a corresponding refresh token. If your access token expires when attempting to make an API call, you will receive an error response, so your code should handle this. Here's an example of how you could do this:

require_once 'csrest_general.php';

$auth = array(
    'access_token' => 'your access token',
    'refresh_token' => 'your refresh token'
);
$wrap = new CS_REST_General($auth);
$result = $wrap->get_clients();
if (!$result->was_successful()) {
    # If you receive '121: Expired OAuth Token', refresh the access token
    if ($result->response->Code == 121) {
        list($new_access_token, $new_expires_in, $new_refresh_token) = 
            $wrap->refresh_token();
        # Save $new_access_token, $new_expires_in, and $new_refresh_token
    }
    # Make the call again
    $result = $wrap->get_clients();
}
var_dump($result->response);

Using an API key

require_once 'csrest_general.php';

$auth = array('api_key' => 'your API key');
$wrap = new CS_REST_General($auth);

$result = $wrap->get_clients();
var_dump($result->response);

API Call Timeout

You can set your local API call timeout time in createsend-php\class\transport.php line 11, in the CS_REST_CALL_TIMEOUT variable. Currently the default is 20 secs.

Examples

Samples for creating or accessing all resources can be found in the samples directory. These samples can be used as the basis for your own application and provide an outline of the expected inputs for each API call.

Further documentation of the inputs and outputs of each call can be found in the documentation in each of the csrest_*.php files or simply by examining the var_dump results in each of the provided samples.

Contributing

Please check the guidelines for contributing to this repository.

Releasing

Please check the instructions for releasing this library.

Comments
  • Curl Exception

    Curl Exception

    Hi. I looped through an array of 13 elements sending 13 different emails. Below is an example of the last two elements and the foreach() loop. Looks like I got a curl error on the last iteration of the loop.
    *Fatal error:* Uncaught exception 'CurlException' with message 'Error making request with curl_error: Operation timed out after 10000 milliseconds with 0 bytes received' in /domain.com/php/createsend-php-master/class/transport.php:165 Stack trace: #0 /domain.com/php/createsend-php-master/class/base_classes.php(289): CS_REST_CurlTransport->make_call(Array) #1 /domain.com/php/createsend-php-master/class/base_classes.php(224): CS_REST_Wrapper_Base->_call(Array, 'POST', 'https://api.cre...', Array) #2 /domain.com/php/createsend-php-master/csrest_transactional_smartemail.php(144): CS_REST_Wrapper_Base->post_request('https://api.cre...', Array) #3 /domain.com/roster/preshow-email.php(55): CS_REST_Transactional_SmartEmail->send(Array) #4 {main} thrown in /domain.com/php/createsend-php-master/class/transport.php on line 165

                Array
                (
                    [11] => Array
                        (
                            [email] => [email protected]
                            [name] => Brett Loudermilk
                        )
    
                    [12] => Array
                        (
                            [email] => [email protected]
                            [name] => David Deeble
                        )
    
                )
    
    
                foreach($a as $act){
                    # Create a new mailer and define your message
                    $recipient =  "{$act['name']} <{$act['email']}>";
                    print $recipient;
                    $wrap = new CS_REST_Transactional_SmartEmail($smart_email_id, $auth);
                    $message = array(
                        "To" => $recipient,
                        "Data" => array(
                            'SHOWDATE' => $db,
                            'SHOWORDER' => 'http://boobietrapshow.com/',
                            'PERFORMERPAGE' => 'http://boobietrapshow.com/',
                        ),
                    );
                    # Send the message and save the response
                    $result = $wrap->send($message);
                    echo "<br/><pre>" , print_r($result), "</pre>";
                }
    
    opened by scotnery 7
  • impossible to set custom timeout

    impossible to set custom timeout

    using: v3.1.3

    I'm sending 1000 subscribers at a time to import() and I keep getting:

    Fatal Error Error: Error making request with curl_error: Operation timed out after 10000 milliseconds with 0 bytes received in [CampaignMonitor\class\transport.php, line 158]

    Why not do something like:

    if (!defined(''CS_REST_CALL_TIMEOUT')) { define('CS_REST_CALL_TIMEOUT', 10); }

    or something?

    So it was possible to set a custom timeout

    opened by gemal 7
  • ErrorCode 50 - Must supply a valid HTTP Basic Authorization header

    ErrorCode 50 - Must supply a valid HTTP Basic Authorization header

    Since some time we get the error

    {
      "Code": 50,
      "Message": "Must supply a valid HTTP Basic Authorization header"
    }
    

    A similar problem was reported in closed issues campaignmonitor/createsend-php#15 and campaignmonitor/createsend-php#33 I tried to fire a sample request like shown on getting-started with my own api-key, and I get the same response.

      echo file_get_contents('https://api.createsend.com/api/v3.2/clients.json?pretty=true', false, stream_context_create(
        array('http'=>array(
        'method'=>"GET",
        'ignore_errors'=>true,
        'header'=> "Authorization: Basic ".base64_encode($auth['api_key'].':x')."\r\n"
        ))
      ));
    

    I can ensure that:

    • no proxy or firewall is stripping the Authorization header
    • I have no trailing or leading whitespace in the APIKey string

    This errorcode is not listed in API Docs - response-status-codes, but I checked the Authorization that is delivered by you API class and by my exmpla with native php file_get_contents. Both seem to send a valid Basic auth header, that contains my correct api-key.

    Is it possible that there could be a problem with the API-Endpoint or any changes in the auth-methods?

    opened by Radon8472 5
  • Defer Services_Json inclusion/initialization until really needed

    Defer Services_Json inclusion/initialization until really needed

    Alternatively, I'd consider dropping Services_Json altogether. Since php 5.2 php comes in with bundled json ext so it should be available everywhere.

    The motivation for this is that requireing this file always not only registers a class definition but also produces some undesired side-effects - namely, global constants definitions

    opened by sserbin 5
  • add Subscribe - confirmed 201 - but not adding to the list

    add Subscribe - confirmed 201 - but not adding to the list

    I was using the add Subscribe function fine, but a few hours ago it stopped working.

    The response indicates a successful entry - but when I view the list on campaign monitor the subscribers are blank.

    function addSubscriber($list_id, $emailAddress, $name, $title, $showName, $showDate, $showTime){ //create subscriber $subscriber = array( 'EmailAddress' => $emailAddress, 'Name' => $name, 'CustomFields' => array( array( 'Key' => "Title", 'Value' => $title ), array( 'Key' => "ShowName", 'Value' => $showName ), array( 'Key' => "ShowDate", 'Value' => $showDate ), array( 'Key' => "ShowTime", 'Value' => $showTime ) ), 'Resubscribe' => true, 'RestartSubscriptionBasedAutoResponders' => true );

        //print_r($subscriber);
    
        $subwrap = new CS_REST_Subscribers($list_id, $this->auth);
        $result = $subwrap->add($subscriber); 
        //var_dump($result->response);
    
        echo "Result of POST /api/v3.1/subscribers/{list id}.{format}\n<br />";
        if($result->was_successful()) {
            echo "Subscribed with code ".$result->http_status_code;
        } else {
            echo 'Failed with code '.$result->http_status_code."\n<br /><pre>";
            var_dump($result->response);
            echo '</pre>';
        }
        return $result->response;
    }
    
    opened by theoldcounty 5
  • Wrapped timeout constants in conditional checks

    Wrapped timeout constants in conditional checks

    CS_REST_SOCKET_TIMEOUT and CS_REST_CALL_TIMEOUT constant definitions are now wrapped in conditional checks to see if the values have been defined earlier to allow larger requests to not timeout.

    This was needed to allow subscriber imports to function without timing out.

    opened by iainsaxon 4
  • Supplied examples:

    Supplied examples: "Must supply a valid HTTP Basic Authorization header"

    I am using the supplied example to test the API:

    require_once 'csrest_general.php';
    
    $auth = array('api_key' => 'your API key');
    $wrap = new CS_REST_General($auth);
    
    $result = $wrap->get_clients();
    var_dump($result->response);
    

    However, the response I get is;

    array(
       'Code' => 50,
       'Message' => 'Must supply a valid HTTP Basic Authorization header',
    )
    

    I have also tried using the supplied example for adding subscribers, with the same result.

    How do I set the Basic Auth header? Given the docs say that Basic Auth simply requires the API key as the username and a blank password, I assumed the library would handle that if I just give it an API key, as the samples do.

    opened by philipjohn 4
  • Class Name Conflict?

    Class Name Conflict?

    This is my relevant code

    require_once('campaign/csrest_general.php');
    $auth = array('api_key' => $_POST['code']);
    $wrap = new CS_REST_General($auth);
    

    I am getting this error on the first line itself

    Fatal error: Cannot redeclare class cs_rest_wrapper_result in campaign/class/base_classes.php on line 19

    Any ideas? The code has not been edited in any way.

    opened by nCrafts 4
  • Import limits

    Import limits

    Hi,

    first thanks for the great package to work with the CM API!

    I am having now some problems with the import limit. There is a limit of 1000 subscribers / import. Is there way to handle more data?

    I tried to make several imports through a loop but this didn't work:

    Error making request with curl_error: Operation timed out after 10000 milliseconds  with 0 out of 144 bytes received
    

    Do you have any advice on how to handle this? Thx and cheers Christoph

    PS: I am working with Laravel 4

    opened by christophrumpel 4
  • Custom Fields needs better examples

    Custom Fields needs better examples

    The examples feature this lovely gem:

    $result = $wrap->add(array( 'EmailAddress' => 'Subscriber email', 'Name' => 'Subscriber name', 'CustomFields' => array( array( 'Key' => 'Field Key', 'Value' => 'Field Value' ) ), 'Resubscribe' => true ));

    Great! Except what if I a want to add more than one custom field? Surely the following makes good sense, no?

    $result = $wrap->add(array( 'EmailAddress' => 'Subscriber email', 'Name' => 'Subscriber name', 'CustomFields' => array( array( 'field1' => 'value 1', 'field2' => 'value 2' ) ), 'Resubscribe' => true ));

    But that does not work. So I think you need to demonstrate your data structure here more thoroughly. EXAMPLES ARE GOD.

    What I think you mean is this:

    $result = $wrap->add(array( 'EmailAddress' => 'Subscriber email', 'Name' => 'Subscriber name', 'CustomFields' => array( array( 'Key' => 'Field Key', 'Value' => 'Field Value' ), array( 'Key' => 'Field 2 Key', 'Value' => 'Field 2 Value' ), // ... etc ... ), 'Resubscribe' => true ));

    I think ???

    opened by fireproofsocks 4
  • PHP Fatal error on IIS: Call to a member function make_call()

    PHP Fatal error on IIS: Call to a member function make_call()

    I have a user who's using an addon of mine that uses the Campaign Monitor API PHP wrapper on IIS and when the API is called, he's receiving this PHP fatal error:

    Call to a member function make_call() on a non-object in C:\Inetpub\xxxxx\xxxxxxxxx\expressionengine\third_party\subscriber\libraries\class\base_classes.php on line 220

    It seems to work just fine on Apache servers. Do you know it would fail on IIS?

    opened by wesbaker 4
  • Please enable javascript in your browser

    Please enable javascript in your browser

    Hi! This is maybe not the right place, but I can't find any other way to reach out to you guys. My client is using campaign monitor and when I'm trying to embed one of the forms on their website I get this error:

    Oops! Something went wrong.
    We could not process your request. Please enable Javascript in your browser. and try again.
    
    Skjermbilde 2022-04-06 kl  10 08 25

    Javascript is of course enabled and all I've done is copied the code generated for me. How can i debug this? Or how can I get in touch with support?

    opened by helleholmsen 1
  • Transactional Statistics result format is wrong

    Transactional Statistics result format is wrong

    Documentation states the result is in this format:

         * @return CS_REST_Wrapper_Result A successful response will be an array of the form
         *     array(
         *         array(
         *             "MessageID" => string
         *             "Status" => string
         *             "SentAt" => string
         *             "Recipient" => string
         *             "From" => string
         *             "Subject" => string
         *             "TotalOpens" => integer
         *             "TotalClicks" => integer
         *             "CanBeResent" => boolean
         *             "Group" => string, optional
         *             "SmartEmailID" => string, optional
         *         )
         *     )
         */
    

    Actual Response is: CS_REST_Wrapper_Result {#64 ▼ +response: {#65 ▼ +"Query": {#66 ...} +"Sent": 14 +"Bounces": 0 +"Delivered": 14 +"Opened": 9 +"Clicked": 2 } +http_status_code: 200

    opened by rhyd42 0
  • TLS v1.2

    TLS v1.2

    Campaign Monitor recently sent out an email asking all customers to switch over to TLS v1.2 before October 12, 2020. Our website is using this code. How do I know what version of TLS we are using? Does this code support TLS v1.2?

    opened by herrmann30 2
  • Support file_get_contents() as a transport

    Support file_get_contents() as a transport

    When PHP configuration option allow_url_fopen is truthy (the default), it's easy to use it as a transport. It's probably less error-prone than a raw socket, too.

    $response_body = file_get_contents(
    	"https://api.createsend.com/api/v3.2/${endpoint}.json"
    	, false
    	, stream_context_create([
    		'http' => [
    			'method' => 'POST',
    			'header' => [
    				'Authentication: Basic ' . base64_encode("${api_key}:"),
    				'Content-Type: application/json',
    			],
    			'content' => json_encode($request_data),
    			'ignore_errors' => true, # prevents returning boolean false for error http statuses
    		],
    	])
    );
    $response_headers = $http_response_header; # https://www.php.net/manual/en/reserved.variables.httpresponseheader.php
    

    Obviously it'd need a little bit more logic to choose HTTP method, be more generic, etc., but the code's a lot simpler than cURL and raw sockets.

    opened by Roy-Orbison 1
  • Added ConsentToTrack

    Added ConsentToTrack

    The ConsentToTrack field is mandatory and should be a valid value ('yes' or 'no'). If you don't add it, the API will return an error that it is mandatory.

    opened by morksinaanab 0
  • PHP 7.4 warning: Array and string offset access syntax with curly braces (version 5).

    PHP 7.4 warning: Array and string offset access syntax with curly braces (version 5).

    Deprecated function: Array and string offset access syntax with curly braces is deprecated in require_once() (line 4 of vendor/campaignmonitor/createsend-php/class/serialisation.php).

    Version: 5.1.3

    opened by VladimirAus 3
Releases(v6.1.2)
Lightweight PHP library for WhatsApp API to send the whatsapp messages in PHP provided by ultramsg.com

Ultramsg.com WhatsApp API PHP SDK Lightweight PHP library for WhatsApp API to send the whatsappp messages in PHP provided by Ultramsg.com Installation

Ultramsg 96 Sep 8, 2022
Google-api-php-client - A PHP client library for accessing Google APIs

Google APIs Client Library for PHP Reference Docs https://googleapis.github.io/google-api-php-client/main/ License Apache 2.0 The Google API Client Li

Google APIs 8.3k Sep 27, 2022
Wise-php - This library is written to accommodate the wise API's use in php projects With Wise

Wise-php - This library is written to accommodate the wise API's use in php projects With Wise you can automate payments, connect your business tools, and create ways to manage your finances. You can also power your cross-border and domestic payouts.

Albert Xhani 14 Aug 24, 2022
BeckhoffPLCSoapClient - SoapClient to communicate with BeckHoff PLC. Library made in PHP based on TcAdsWebService JavaScript Library.

BeckhoffPLCSoapClient - SoapClient to communicate with BeckHoff PLC. Library made in PHP based on TcAdsWebService JavaScript Library.

null 3 May 18, 2022
PHP library for the Stripe API.

Stripe PHP bindings The Stripe PHP library provides convenient access to the Stripe API from applications written in the PHP language. It includes a p

Stripe 3.2k Sep 23, 2022
A PHP library for communicating with the Twilio REST API and generating TwiML.

twilio-php The default branch name for this repository has been changed to main as of 07/27/2020. Documentation The documentation for the Twilio API c

Twilio 1.4k Sep 28, 2022
PHP 5.3+ library which helps you to interact with the DigitalOcean API

DigitalOcean The version 2 of the API will be available soon ! Please visit DigitalOceanV2 and contribute :) This PHP 5.3+ library helps you to intera

Antoine Kirk 156 Jul 30, 2022
PHP library for the GitHub API v3

GitHub API v3 - PHP Library Currently under construction. Overview Provides access to GitHub API v3 via an Object Oriented PHP library. The goal of th

Darren Rees 62 Jul 28, 2022
PHP library to use IOTA REST API to help node management and tangle queries

iota.php About PHP library to use IOTA REST API to help node management and tangle queries. Please be aware that this library is in an early developme

IOTA Community 44 Aug 17, 2022
PHP library for the ArvanCloud API

PHP ArvanCloud API PHP library for the ArvanCloud API. This package supports PHP 7.3+. For Laravel integration you can use mohammadv184/arvancloud-lar

Mohammad Abbasi 5 Apr 29, 2022
A library written in PHP to interact with Coinbase Pro via API.

A library written in PHP to interact with Coinbase Pro via API.

Blake Hamilton 4 Mar 31, 2022
Upload Vimeo video with CodeIgniter, Official PHP library for the Vimeo API

Upload Vimeo video with CodeIgniter, Official PHP library for the Vimeo API. Vimeo Video upload with API using Official PHP library for the Vimeo API.

WordPress theme and Plugins developers 2 Oct 10, 2021
The library provides convenient access to the Epoint.az API from applications written in the PHP language.

Tural/Epoint library/SDK The library provides convenient access to the Epoint.az API from applications written in the PHP language. It includes a pre-

Tural 5 Jan 20, 2022
The library provides convenient access to the Epoint.az API from applications written in the PHP language.

Tural/Epoint library/SDK The library provides convenient access to the Epoint.az API from applications written in the PHP language. It includes a pre-

Tural 5 Jan 20, 2022
This library allows you to quickly and easily use the Twilio SendGrid Web API v3 via PHP

This library allows you to quickly and easily use the Twilio SendGrid Web API v3 via PHP

Twilio SendGrid 1.4k Sep 21, 2022
The best PHP library for VK Users Longpoll Api (Page Bots).

vk-page-bot-lib Description: There are 2 commands and a logger. There is a logger of new messages and a logger that a friend has entered/left in/from

KirillChimbur 6 Jul 25, 2022
PHP library for the Notion API

Notion SDK for PHP PHP version of the official NOTION API. It works the same way as the reference JavaScript SDK ?? Installation Install this package

Berdrigue 34 Sep 7, 2022
Just a simple API PHP library with basic functions and config.

Installation Clone this Repository in your PHP Project git clone https://github.com/maximilianosinski/simple-api-php-library.git Change your Project n

Maximilian Osinski 1 May 9, 2022
PHP library with ready-to-use Yunbi API implementation.

yunbi-client-php A simple PHP client for Crypto Trade Site Yunbi.com Quick example <?php require_once('lib/yunbi-client.php'); try { $client = new

null 6 Dec 2, 2019