Ey, we are doing great stuffs.
23 | 24 | 25 | "; 26 | $template = $this->klaviyo->template->create('Register template', $tmpl); 27 | $this->klaviyo->template->delete($template->id); 28 | 29 | $this->assertEquals('Register template', $template->name); 30 | $this->assertEquals('email-template', $template->object); 31 | } 32 | 33 | public function testClone() 34 | { 35 | $tmpl = " 36 | 37 | 38 |Ey, we are doing great stuffs.
40 | 41 | 42 | "; 43 | $template = $this->klaviyo->template->create('Register template', $tmpl); 44 | $cloned = $this->klaviyo->template->clone($template->id, 'Register template clone'); 45 | 46 | $this->assertEquals('Register template', $template->name); 47 | $this->assertEquals('email-template', $template->object); 48 | $this->assertEquals('Register template clone', $cloned->name); 49 | $this->assertEquals('email-template', $cloned->object); 50 | 51 | $this->klaviyo->template->delete($template->id); 52 | $this->klaviyo->template->delete($cloned->id); 53 | } 54 | 55 | public function testGetAll() 56 | { 57 | $tmpl = " 58 | 59 | 60 |Ey, we are doing great stuffs.
62 | 63 | 64 | "; 65 | $template = $this->klaviyo->template->create('Register template', $tmpl); 66 | $cloned = $this->klaviyo->template->clone($template->id, 'Register template clone'); 67 | $allTmpls = $this->klaviyo->template->getAll(); 68 | 69 | $this->klaviyo->template->delete($template->id); 70 | $this->klaviyo->template->delete($cloned->id); 71 | 72 | $this->assertObjectHasAttribute('total', $allTmpls); 73 | $this->assertIsArray($allTmpls->data); 74 | } 75 | 76 | public function testDelete() 77 | { 78 | $tmpl = " 79 | 80 | 81 |Ey, we are doing great stuffs.
83 | 84 | 85 | "; 86 | $template = $this->klaviyo->template->create('Register template', $tmpl); 87 | $cloned = $this->klaviyo->template->clone($template->id, 'Register template clone'); 88 | $allTmpls = $this->klaviyo->template->getAll(); 89 | 90 | $this->assertObjectHasAttribute('total', $allTmpls); 91 | $this->assertIsArray( $allTmpls->data); 92 | 93 | $this->klaviyo->template->delete($template->id); 94 | $this->klaviyo->template->delete($cloned->id); 95 | $allTmpls = $this->klaviyo->template->getAll(); 96 | 97 | $this->assertObjectHasAttribute('total', $allTmpls); 98 | $this->assertIsArray( $allTmpls->data); 99 | } 100 | 101 | public function testUpdateName() 102 | { 103 | $tmpl = " 104 | 105 | 106 |Ey, we are doing great stuffs.
108 | 109 | 110 | "; 111 | $template = $this->klaviyo->template->create('Register template', $tmpl); 112 | $updated = $this->klaviyo->template->update($template->id, 'Register template updated', $tmpl); 113 | 114 | $this->klaviyo->template->delete($updated->id); 115 | $allTmpls = $this->klaviyo->template->getAll(); 116 | 117 | $this->assertObjectHasAttribute('total', $allTmpls); 118 | $this->assertIsArray($allTmpls->data); 119 | } 120 | 121 | /* 122 | public function testRender() 123 | { 124 | $tmpl = " 125 | 126 | 127 |Ey, we are doing great stuffs.
129 | 130 | 131 | "; 132 | $template = $this->klaviyo->template->create('Register template', $tmpl); 133 | 134 | $this->klaviyo->template->delete($template->id); 135 | 136 | // $this->assertEquals(7, $allTmpls->total); 137 | // $this->assertIsArray($allTmpls->data); 138 | } 139 | */ 140 | } 141 | -------------------------------------------------------------------------------- /src/Siro/Klaviyo/KlaviyoEvent.php: -------------------------------------------------------------------------------- 1 | $this->apiKey, 31 | 'event' => $event, 32 | 'customer_properties' => $customerProperties, 33 | 'properties' => $properties, 34 | 'time' => $timestamp 35 | ]; 36 | 37 | $response = $this->client->get( 38 | '/api/track', 39 | [ 40 | 'query' => [ 41 | 'data' => base64_encode(json_encode($data)) 42 | ] 43 | ] 44 | ); 45 | 46 | return $this->sendResponseAsObject($response); 47 | } 48 | 49 | /** 50 | * Asynchronous track event version. 51 | * GET /api/track 52 | * 53 | * @param string $event The event name. For example, 'register'. 54 | * @param array $customerProperties An array containing the email (client email). 55 | * @param array $properties An array containing all extra data of the client, as 56 | * name, surname, language, city, etc. 57 | * @param mixed $timestamp the time in UNIX timestamp format. null by default. 58 | * @return \GuzzleHttp\Promise\PromiseInterface a promise than must be treated. 59 | */ 60 | public function trackAsync($event, array $customerProperties, array $properties, $timestamp = null) 61 | { 62 | $data = [ 63 | 'token' => $this->apiKey, 64 | 'event' => $event, 65 | 'customer_properties' => $customerProperties, 66 | 'properties' => $properties, 67 | 'time' => $timestamp 68 | ]; 69 | 70 | return $this->client->getAsync( 71 | '/api/track', 72 | [ 73 | 'query' => [ 74 | 'data' => base64_encode(json_encode($data)) 75 | ] 76 | ] 77 | ); 78 | } 79 | 80 | /** 81 | * The Identify API endpoint is /api/identify, which is used to track properties 82 | * about an individual without tracking an associated event. 83 | * It encodes the following data in a dictionary or hash. 84 | * GET /api/identify 85 | * 86 | * @param array $properties 87 | * @return object 88 | * @throws \Exception 89 | */ 90 | public function identify(array $properties) 91 | { 92 | if ((!array_key_exists('$email', $properties) || empty($properties['$email'])) 93 | && (!array_key_exists('$id', $properties) || empty($properties['$id'])) 94 | ) { 95 | throw new \Exception('You must identify a user by email or ID.'); 96 | } 97 | $data = [ 98 | 'token' => $this->apiKey, 99 | 'properties' => $properties 100 | ]; 101 | 102 | $response = $this->client->get( 103 | '/api/identify', 104 | [ 105 | 'query' => [ 106 | 'data' => base64_encode(json_encode($data)) 107 | ] 108 | ] 109 | ); 110 | 111 | return $this->sendResponseAsObject($response); 112 | } 113 | 114 | /** 115 | * The Identify API endpoint in a asynchronous version. 116 | * GET /api/identify. 117 | * 118 | * @param array $properties an array of properties listed in https://www.klaviyo.com/docs/http-api. 119 | * @return GuzzleHttp\Promise\PromiseInterface a promise than must be treated. 120 | * @throws \Exception 121 | */ 122 | public function identifyAsync(array $properties) 123 | { 124 | if ((!array_key_exists('$email', $properties) || empty($properties['$email'])) 125 | && (!array_key_exists('$id', $properties) || empty($properties['$id'])) 126 | ) { 127 | throw new \Exception('You must identify a user by email or ID.'); 128 | } 129 | $data = [ 130 | 'token' => $this->apiKey, 131 | 'properties' => $properties 132 | ]; 133 | 134 | return $this->client->getAsync( 135 | '/api/identify', 136 | [ 137 | 'query' => [ 138 | 'data' => base64_encode(json_encode($data)) 139 | ] 140 | ] 141 | ); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/Siro/Klaviyo/KlaviyoCampaign.php: -------------------------------------------------------------------------------- 1 | client->get( 17 | "/api/v1/campaigns", 18 | [ 19 | 'query' => [ 20 | 'api_key' => $this->apiKey, 21 | 'page' => $page, 22 | 'count' => $count 23 | ] 24 | ] 25 | ); 26 | 27 | return $this->sendResponseAsObject($response); 28 | } 29 | 30 | /** 31 | * POST /api/v1/campaigns 32 | */ 33 | public function create($listId, $templateId, $fromEmail, $fromName, $subject, $name = '', $useSmartSending = true, $addGoogleAnalytics = false) 34 | { 35 | $requestParams = [ 36 | 'form_params' => [ 37 | 'api_key' => $this->apiKey, 38 | 'list_id' => $listId, 39 | 'template_id' => $templateId, 40 | 'from_email' => $fromEmail, 41 | 'from_name' => $fromName, 42 | 'subject' => $subject, 43 | 'use_smart_sending' => $useSmartSending, 44 | 'add_google_analytics' => $addGoogleAnalytics, 45 | ] 46 | ]; 47 | 48 | if (!empty($name)) { 49 | $requestParams['form_params']['name'] = $name; 50 | } 51 | 52 | $response = $this->client->post("/api/v1/campaigns", $requestParams); 53 | 54 | return $this->sendResponseAsObject($response); 55 | } 56 | 57 | /** 58 | * GET /api/v1/campaign/{{ CAMPAIGN_ID }} 59 | */ 60 | public function get($campaignId) 61 | { 62 | $response = $this->client->get( 63 | "/api/v1/campaign/{$campaignId}", 64 | [ 65 | 'query' => [ 66 | 'api_key' => $this->apiKey 67 | ] 68 | ] 69 | ); 70 | 71 | return $this->sendResponseAsObject($response); 72 | } 73 | 74 | /** 75 | * PUT /api/v1/campaign/{{ CAMPAIGN_ID }} 76 | */ 77 | public function update($campaignId, $listId = null, $templateId = null, $fromEmail = null, $fromName = null, $subject = null, $name = null, $useSmartSending = null, $addGoogleAnalytics = null) 78 | { 79 | $requestParams = [ 80 | 'form_params' => [ 81 | 'api_key' => $this->apiKey, 82 | ] 83 | ]; 84 | if (!is_null($listId)) { 85 | $requestParams['form_params']['list_id'] = $listId; 86 | } 87 | if (!is_null($templateId)) { 88 | $requestParams['form_params']['template_id'] = $templateId; 89 | } 90 | if (!is_null($fromEmail)) { 91 | $requestParams['form_params']['from_email'] = $fromEmail; 92 | } 93 | if (!is_null($fromName)) { 94 | $requestParams['form_params']['from_name'] = $fromName; 95 | } 96 | if (!is_null($subject)) { 97 | $requestParams['form_params']['subject'] = $subject; 98 | } 99 | if (!is_null($useSmartSending)) { 100 | $requestParams['form_params']['use_smart_sending'] = $useSmartSending; 101 | } 102 | if (!is_null($name)) { 103 | $requestParams['form_params']['name'] = $name; 104 | } 105 | if (!is_null($addGoogleAnalytics)) { 106 | $requestParams['form_params']['add_google_analytics'] = $addGoogleAnalytics; 107 | } 108 | 109 | $response = $this->client->put("/api/v1/campaign/{$campaignId}", $requestParams); 110 | 111 | return $this->sendResponseAsObject($response); 112 | } 113 | 114 | /** 115 | * POST /api/v1/campaign/{{ CAMPAIGN_ID }}/send 116 | */ 117 | public function sendNow($campaignId) 118 | { 119 | $response = $this->client->post( 120 | "/api/v1/campaign/{$campaignId}/send", 121 | [ 122 | 'query' => [ 123 | 'api_key' => $this->apiKey 124 | ] 125 | ] 126 | ); 127 | 128 | return $this->sendResponseAsObject($response); 129 | } 130 | 131 | /** 132 | * POST /api/v1/campaign/{{ CAMPAIGN_ID }}/schedule 133 | */ 134 | public function schedule($campaignId, $sendTime) 135 | { 136 | $options = [ 137 | 'form_params' => [ 138 | 'api_key' => $this->apiKey, 139 | ] 140 | ]; 141 | if (is_int($sendTime)) { 142 | $options['form_params']['send_time'] = date("Y-m-d H:i:s", $sendTime); 143 | } else { 144 | $options['form_params']['send_time'] = $sendTime; 145 | } 146 | 147 | $response = $this->client->post("/api/v1/campaign/{$campaignId}/schedule", $options); 148 | return $this->sendResponseAsObject($response); 149 | } 150 | 151 | /** 152 | * POST /api/v1/campaign/{{ CAMPAIGN_ID }}/cancel 153 | */ 154 | public function cancel($campaignId) 155 | { 156 | $options = [ 157 | 'form_params' => [ 158 | 'api_key' => $this->apiKey 159 | ] 160 | ]; 161 | $response = $this->client->post("/api/v1/campaign/{$campaignId}/cancel", $options); 162 | return $this->sendResponseAsObject($response); 163 | } 164 | 165 | /** 166 | * POST /api/v1/campaign/{{ CAMPAIGN_ID }}/clone 167 | */ 168 | public function clone($campaignId, $newName, $listId) 169 | { 170 | $options = [ 171 | 'form_params' => [ 172 | 'api_key' => $this->apiKey, 173 | 'name' => $newName, 174 | 'list_id' => $listId 175 | ] 176 | ]; 177 | $response = $this->client->post("/api/v1/campaign/{$campaignId}/clone", $options); 178 | return $this->sendResponseAsObject($response); 179 | } 180 | 181 | /** 182 | * GET /api/v1/campaign/{{ CAMPAIGN_ID }}/recipients 183 | */ 184 | public function getRecipients($campaignId, $count = 5000, $sort = 'asc', $offset = '') 185 | { 186 | $options = [ 187 | 'query' => [ 188 | 'count' => $count, 189 | 'api_key' => $this->apiKey, 190 | 'sort' => $sort, 191 | ] 192 | ]; 193 | if (!empty($offset)) { 194 | $options['query']['offset'] = $offset; 195 | } 196 | $response = $this->client->get("/api/v1/campaign/{$campaignId}/recipients", $options); 197 | 198 | return $this->sendResponseAsObject($response); 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /src/Siro/Klaviyo/KlaviyoList.php: -------------------------------------------------------------------------------- 1 | client->get( 45 | "/api/v2/lists", 46 | [ 47 | 'form_params' => [ 48 | 'api_key' => $this->apiKey, 49 | ] 50 | ] 51 | ); 52 | 53 | return $this->sendResponseAsObject($response); 54 | } 55 | 56 | /** 57 | * Create a new list. Currently this resources only supports creating standard lists. 58 | * 59 | * @param string $name 60 | * POST /api/v2/lists 61 | */ 62 | public function create($name) 63 | { 64 | $requestParams = [ 65 | 'form_params' => [ 66 | 'api_key' => $this->apiKey, 67 | 'list_name' => $name, 68 | ] 69 | ]; 70 | $response = $this->client->post("/api/v2/lists", $requestParams); 71 | 72 | return $this->sendResponseAsObject($response); 73 | } 74 | 75 | /** 76 | * Summary information for the list specified that includes 77 | * the name, ID, type, number of members, when it was created and last updated. 78 | * 79 | * GET /api/v2/list/{{ LIST_ID }} 80 | * 81 | * @param string $listId 82 | */ 83 | public function get($listId) 84 | { 85 | $response = $this->client->get( 86 | "/api/v2/list/{$listId}", 87 | [ 88 | 'query' => [ 89 | 'api_key' => $this->apiKey 90 | ] 91 | ] 92 | ); 93 | 94 | return $this->sendResponseAsObject($response); 95 | } 96 | 97 | /** 98 | * Update details of the list. Currently this only support updating the 99 | * name of the list. 100 | * 101 | * PUT /api/v2/list/{{ LIST_ID }} 102 | * 103 | * @param string $listId The list ID. 104 | * @param string $name New name. 105 | * @return mixed Null if the request fails or an stdclass object if is successful. 106 | */ 107 | public function update($listId, $name) 108 | { 109 | $requestParams = [ 110 | 'form_params' => [ 111 | 'api_key' => $this->apiKey, 112 | 'list_name' => $name 113 | ] 114 | ]; 115 | $response = $this->client->put("/api/v2/list/{$listId}", $requestParams); 116 | 117 | return $this->sendResponseAsObject($response); 118 | } 119 | 120 | /** 121 | * PUT /api/v2/list/{{ LIST_ID }} 122 | */ 123 | public function delete($listId) 124 | { 125 | $response = $this->client->delete( 126 | "/api/v2/list/{$listId}", 127 | [ 128 | 'query' => [ 129 | 'api_key' => $this->apiKey 130 | ] 131 | ] 132 | ); 133 | 134 | return $this->sendResponseAsObject($response); 135 | } 136 | 137 | /** 138 | * GET /api/v2/list/{$listId}/members 139 | */ 140 | public function memberExistsInList($listId, $email) 141 | { 142 | $emails = $email; 143 | if (!is_array($email)) { 144 | $emails = [$email]; 145 | } 146 | $options = [ 147 | 'form_params' => [ 148 | 'api_key' => $this->apiKey, 149 | 'emails' => $emails 150 | ] 151 | ]; 152 | $response = $this->client->get("/api/v2/list/{$listId}/members", [ 153 | RequestOptions::JSON => $options['form_params'], 154 | $options 155 | ]); 156 | 157 | return count($this->sendResponseAsObject($response)) === count($emails); 158 | } 159 | 160 | /** 161 | * GET /api/v1/segment/{{ SEGMENT_ID }}/members 162 | */ 163 | public function memberExistsInSegment($segmentId, $email) 164 | { 165 | $emailFormat = $email; 166 | if (is_array($email)) { 167 | $emailFormat = implode(',', $email); 168 | } 169 | $options = [ 170 | 'query' => [ 171 | 'api_key' => $this->apiKey, 172 | 'email' => $emailFormat 173 | ] 174 | ]; 175 | $response = $this->client->get("/api/v2/segment/{$segmentId}/members", $options); 176 | 177 | if ($response->getStatusCode() === 200) { 178 | $resObj = json_decode((string) $response->getBody()); 179 | if (is_array($email)) { 180 | return $resObj->total === count($email); 181 | } 182 | 183 | return (bool) $resObj->total; 184 | } 185 | 186 | return null; 187 | } 188 | 189 | /** 190 | * Checks if the email/s are submited in a list or segment 191 | * 192 | * @param string $id The segment or list ID. 193 | * @param mixed $email The user email to check if exists. 194 | * @param string $type List or segment 195 | * @return bool True if all emails are inside the list or segment. 196 | */ 197 | public function memberExists($id, $email, $type = 'list') 198 | { 199 | if ($type === 'list') { 200 | return $this->memberExistsInList($id, $email); 201 | } elseif ($type === 'segment') { 202 | return $this->memberExistsInSegment($id, $email); 203 | } else { 204 | throw new Exception('type not allowed. Only "list" and "segment"'); 205 | } 206 | } 207 | 208 | /** 209 | * Adds a new person to the specified list. If a person with that 210 | * email address does not already exist, a new person is first added to Klaviyo. 211 | * If someone is unsubscribed from the specified list, they will not be subscribed. 212 | * To re-subscribe someone, you must manually remove them from the 213 | * unsubscribe list in Klaviyo on the members page for the specified list. 214 | * POST /api/v2/list/{{ LIST_ID }}/members 215 | * 216 | * @param string $listId The id of the id. 217 | * @param array $profiles An array of properties such as names. 218 | * @return mixed Null if the request fails or an stdclass object if is successful 219 | */ 220 | public function addMember($listId, array $profiles) 221 | { 222 | foreach ($profiles as $profile) { 223 | if (!array_key_exists('email', $profile)) { 224 | throw new Exception('"email" key not found'); 225 | } 226 | } 227 | $formParams = [ 228 | 'form_params' => [ 229 | 'api_key' => $this->apiKey, 230 | 'profiles' => $profiles 231 | ], 232 | ]; 233 | 234 | $response = $this->client->post("/api/v2/list/{$listId}/members", [ 235 | RequestOptions::JSON => $formParams['form_params'], 236 | $formParams 237 | ]); 238 | return $this->sendResponseAsObject($response); 239 | } 240 | 241 | /** 242 | * Batch Removing People from a List 243 | * Removes multiple people from the specified list. For each person, 244 | * if a person with that email address is a member of that list, 245 | * they are removed. 246 | * DELETE /api/v2/list/{{ LIST_ID }}/members/batch 247 | * 248 | * @param string $listId The list id. 249 | * @param array $emails The list of user emails to delete. 250 | * @return mixed Null if the request fails or an stdclass object if is successful. 251 | */ 252 | public function deleteMembers($listId, array $emails) 253 | { 254 | $options = [ 255 | 'form_params' => [ 256 | 'api_key' => $this->apiKey, 257 | 'emails' => $emails 258 | ] 259 | ]; 260 | $response = $this->client->delete("/api/v2/list/{$listId}/members", [ 261 | RequestOptions::JSON => $options['form_params'], 262 | $options 263 | ]); 264 | 265 | return $this->sendResponseAsObject($response); 266 | } 267 | 268 | /** 269 | * POST https://a.klaviyo.com/api/v2/list/{LIST_ID}/subscribe 270 | */ 271 | public function subscribe($listId, array $profiles) 272 | { 273 | foreach ($profiles as $profile) { 274 | if (!array_key_exists('email', $profile)) { 275 | throw new Exception('"email" key not found'); 276 | } 277 | } 278 | $options = [ 279 | 'form_params' => [ 280 | 'api_key' => $this->apiKey, 281 | 'profiles' => $profiles 282 | ] 283 | ]; 284 | $response = $this->client->post("/api/v2/list/{$listId}/subscribe", [ 285 | RequestOptions::JSON => $options['form_params'], 286 | $options 287 | ]); 288 | 289 | return $this->sendResponseAsObject($response); 290 | } 291 | 292 | /** 293 | * GET https://a.klaviyo.com/api/v2/list/{LIST_ID}/subscribe 294 | */ 295 | public function checkSubscriptions($listId, array $emails) 296 | { 297 | $options = [ 298 | 'form_params' => [ 299 | 'api_key' => $this->apiKey, 300 | 'emails' => $emails 301 | ] 302 | ]; 303 | 304 | $response = $this->client->get( 305 | "/api/v2/list/{$listId}/subscribe", 306 | [ 307 | RequestOptions::JSON => $options['form_params'], 308 | $options 309 | ] 310 | ); 311 | 312 | return $this->sendResponseAsObject($response); 313 | } 314 | 315 | /** 316 | * Unsubscribe and remove profiles from a list. 317 | * DELETE https://a.klaviyo.com/api/v2/list/{LIST_ID}/subscribe 318 | */ 319 | public function unsubscribe($listId, array $emails) 320 | { 321 | $options = [ 322 | 'form_params' => [ 323 | 'api_key' => $this->apiKey, 324 | 'emails' => $emails 325 | ] 326 | ]; 327 | 328 | $response = $this->client->delete( 329 | "/api/v2/list/{$listId}/subscribe", 330 | [ 331 | RequestOptions::JSON => $options['form_params'], 332 | $options 333 | ] 334 | ); 335 | 336 | return $this->sendResponseAsObject($response); 337 | } 338 | 339 | /** 340 | * Get all of the emails that have been excluded from a list along 341 | * with the exclusion reason and exclusion time. 342 | * This endpoint uses batching to return the records, so for a large list 343 | * multiple calls will need to be made to get all of the records. 344 | * 345 | * GET https://a.klaviyo.com/api/v2/list/{LIST_ID}/exclusions/all 346 | */ 347 | public function getAllExclusions($listId, $marker = null) 348 | { 349 | $options = [ 350 | 'form_params' => [ 351 | 'api_key' => $this->apiKey 352 | ] 353 | ]; 354 | 355 | if (!is_null($marker)) { 356 | $options['form_params']['marker'] = (int) $marker; 357 | } 358 | 359 | $response = $this->client->get( 360 | "/api/v2/list/{$listId}/exclusions/all", 361 | [ 362 | RequestOptions::JSON => $options['form_params'], 363 | $options 364 | ] 365 | ); 366 | 367 | return $this->sendResponseAsObject($response); 368 | } 369 | 370 | /** 371 | * GET /api/v2/group/{LIST_ID or SEGMENT_ID}/members/all 372 | */ 373 | public function getListMembers($listId, $marker = null) 374 | { 375 | $formParams = [ 376 | 'form_params' => [ 377 | 'api_key' => $this->apiKey 378 | ] 379 | ]; 380 | 381 | if ($marker) { 382 | $formParams['form_params']['marker'] = $marker; 383 | } 384 | 385 | $response = $this->client->get( 386 | "/api/v2/group/{$listId}/members/all", 387 | $formParams 388 | ); 389 | return $this->sendResponseAsObject($response); 390 | } 391 | } 392 | --------------------------------------------------------------------------------