Test Failed
Branch development (f482bc)
by Robert
06:44
created

LiveEngageLaravel::getSkill()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace LivePersonInc\LiveEngageLaravel;
4
5
use Carbon\Carbon;
6
use GuzzleHttp\Client;
7
use GuzzleHttp\HandlerStack;
8
use GuzzleHttp\Subscriber\Oauth\Oauth1;
9
use LivePersonInc\LiveEngageLaravel\Models\Info;
10
use LivePersonInc\LiveEngageLaravel\Models\MetaData;
11
use LivePersonInc\LiveEngageLaravel\Models\AccountStatus;
12
use LivePersonInc\LiveEngageLaravel\Models\MessagingInfo;
13
use LivePersonInc\LiveEngageLaravel\Models\Payload;
14
use LivePersonInc\LiveEngageLaravel\Models\Visitor;
15
use LivePersonInc\LiveEngageLaravel\Models\Agent;
16
use LivePersonInc\LiveEngageLaravel\Models\Skill;
17
use LivePersonInc\LiveEngageLaravel\Models\Campaign;
18
use LivePersonInc\LiveEngageLaravel\Models\Engagement;
19
use LivePersonInc\LiveEngageLaravel\Models\Conversation;
20
use LivePersonInc\LiveEngageLaravel\Models\Message;
21
use LivePersonInc\LiveEngageLaravel\Collections\EngagementHistory;
22
use LivePersonInc\LiveEngageLaravel\Collections\Skills;
23
use LivePersonInc\LiveEngageLaravel\Collections\AgentParticipants;
24
use LivePersonInc\LiveEngageLaravel\Exceptions\LiveEngageException;
25
use LivePersonInc\LiveEngageLaravel\Collections\ConversationHistory;
26
27
class LiveEngageLaravel
28
{
29
	private $account = false;
30
	private $results = [];
31
	private $skills = [];
32
	private $next = false;
33
	private $prev = false;
34
	private $start;
35
	private $end;
36
	private $config = 'services.liveperson.default';
37
	private $version = '1.0';
38
	private $history_limit = 50;
39
	private $history = false;
40
	private $context = 'interactionHistoryRecords';
41
	private $interactive = true;
42
	private $ended = true;
43
	private $bearer = false;
44
	private $revision = 0;
45
46
	private $domain = false;
47 5
48
	private $retry_limit = 5;
49 5
	private $retry_counter = 0;
50
51
	public function __get($attribute)
52 8
	{
53
		return $this->$attribute;
54 8
	}
55
56 8
	public function __construct()
57 8
	{
58
		$this->account = config("{$this->config}.account");
59 1
		//$this->domain = config("{$this->config}.domain");
60
		$this->version = config("{$this->config}.version") ?: $this->version;
61 1
	}
62 1
63
	public function key($key = 'default')
64 1
	{
65
		$this->config = "services.liveperson.$key";
66
		$this->__construct();
67 1
68
		return $this;
69 1
	}
70 1
	
71
	public function nonInteractive()
72
	{
73 1
		$this->interactive = false;
74
		return $this;
75 1
	}
76 1
	
77
	public function active()
78
	{
79 1
		$this->ended = false;
80
		return $this;
81 1
	}
82
83 1
	public function limit($limit)
84
	{
85
		$this->history_limit = $limit;
86 1
87
		return $this;
88 1
	}
89
90 1
	public function retry($limit)
91
	{
92
		$this->retry_limit = $limit;
93 1
94
		return $this;
95 1
	}
96
97 1
	public function account($accountid)
98
	{
99
		$this->account = $accountid;
100 1
101
		return $this;
102 1
	}
103
104 1
	public function domain($service)
105
	{
106
		$response = $this->requestV1("https://api.liveperson.net/api/account/{$this->account}/service/{$service}/baseURI.json?version={$this->version}", 'GET');
107 1
		
108
		$this->domain = $response->baseURI;
109 1
110
		return $this;
111 1
	}
112
113 1
	public function visitor($visitorID, $sessionID, $setData = false)
114
	{
115
		$this->domain('smt');
116
117
		if ($setData) {
118
			$url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/events?v=1&sid={$sessionID}";
119
120
			return $this->requestV1($url, 'POST', $setData);
121
		} else {
122
			$url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/state?v=1&sid={$sessionID}";
123
124
			return $this->requestV1($url, 'GET');
125
		}
126
	}
127
	
128
	public function chat()
129
	{
130
		$this->domain('conversationVep');
131 1
		
132
		$url = "https://{$this->domain}/api/account/{$this->account}/chat/request?v=1&NC=true";
133 1
		
134
		$args = [
135 1
			
136
		];
137 1
		$payload = new Payload($args);
138 1
		
139
		$response = $this->requestV1($url, 'POST', $payload);
140 1
		
141 1
		return $response;
142 1
	}
143
144 1
	final public function retrieveHistory(Carbon $start, Carbon $end, $url = false)
145 1
	{
146
		$this->domain('engHistDomain');
147 1
148
		$url = $url ?: "https://{$this->domain}/interaction_history/api/account/{$this->account}/interactions/search?limit={$this->history_limit}&offset=0";
149
150 1
		$start_str = $start->toW3cString();
151
		$end_str = $end->toW3cString();
152
153 1
		$data = new Payload([
154
			'interactive' => $this->interactive,
155 1
			'ended' => $this->ended,
156
			'start' => [
157 1
				'from' => strtotime($start_str) . '000',
158
				'to' => strtotime($end_str) . '000',
159 1
			],
160 1
			'skillIds' => $this->skills
161
		]);
162 1
163 1
		return $this->requestV1($url, 'POST', $data);
164
	}
165 1
166 1
	final public function retrieveMsgHistory(Carbon $start, Carbon $end, $url = false)
167
	{
168 1
		$this->domain('msgHist');
169
170
		$url = $url ?: "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/search?limit={$this->history_limit}&offset=0&sort=start:desc";
171 1
172
		$start_str = $start->toW3cString();
173
		$end_str = $end->toW3cString();
174 1
175
		$data = new Payload([
176 1
			'status' => $this->ended ? ['CLOSE'] : ['OPEN', 'CLOSE'],
177
			'start' => [
178 1
				'from' => strtotime($start_str) . '000',
179
				'to' => strtotime($end_str) . '000',
180 1
			],
181
			'skillIds' => $this->skills
182 1
		]);
183
		
184 1
		return $this->requestV1($url, 'POST', $data);
185 1
	}
186 1
	
187
	public function skills()
188 1
	{
189
		$this->domain('accountConfigReadOnly');
190
		
191
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/skills?v=4.0";
192 1
		
193
		return new Skills($this->requestV2($url, 'GET'));
194 1
	}
195
	
196 1
	public function getSkill($skillId)
197 1
	{
198
		$this->domain('accountConfigReadOnly');
199 1
		
200
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/skills/{$skillId}?v=4.0";
201 1
		
202 1
		return new Skill((array) $this->requestV2($url, 'GET'));
203
	}
204 1
	
205
	public function getAgent($userId)
206 1
	{
207 1
		$this->domain('accountConfigReadOnly');
208
		
209 1
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users/{$userId}?v=4.0";
210
		
211
		return new Agent((array) $this->requestV2($url, 'GET'));
212
	}
213 1
	
214
	public function updateAgent($userId, $properties)
215 1
	{
216
		$agent = $this->getAgent($userId);
0 ignored issues
show
Unused Code introduced by
The assignment to $agent is dead and can be removed.
Loading history...
217 1
		
218 1
		$this->domain('accountConfigReadWrite');
219
		
220 1
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users/{$userId}?v=4.0";
221
		$headers = [
222 1
			'X-HTTP-Method-Override' => 'PUT',
223 1
			'if-Match' => '*'
224
		];
225 1
		
226
		return new Agent((array) $this->requestV2($url, 'PUT', $properties, $headers));
227 1
	}
228 1
	
229
	public function agents()
230 1
	{
231
		$this->domain('accountConfigReadOnly');
232
		
233
		$select = implode(',', [
234 1
			'id',
235
			'pid',
236 1
			'deleted',
237
			'loginName',
238 1
			'skills',
239
			'nickname',
240 1
			'dateCreated',
241
			'userTypeId',
242
			'isApiUser',
243
			'profileIds',
244
			'permissionGroups',
245
			'allowedAppKeys',
246
			'changePwdNextLogin',
247
			'maxChats',
248
			'skillIds',
249
			'lpaCreatedUser',
250
			'email',
251
			'lobs',
252
			'profiles',
253
			'fullName',
254
			'employeeId',
255
			'managedAgentGroups',
256
			'dateUpdated',
257
			'isEnabled',
258
			'lastPwdChangeDate'
259
		]);
260
		
261
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users?v=4.0&select=$select";
262
		
263
		return new AgentParticipants($this->requestV2($url, 'GET'));
264
	}
265
	
266
	public function getAgentStatus($skills)
267
	{
268
		$skills = is_array($skills) ? $skills : [$skills];
269
	
270
		$this->domain('msgHist');
271
		
272
		$url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/agent-view/status";
273
		
274
		$data = ['skillIds' => $skills];
275
		
276
		$response = $this->requestV1($url, 'POST', $data);
277
		$collection = new AgentParticipants($response->agentStatusRecords);
278
		$collection->metaData = new MetaData((array) $response->_metadata);
279
		
280
		return $collection;
281
		
282
	}
283
	
284
	public function conversationHistory(Carbon $start = null, Carbon $end = null, $skills = [])
285
	{
286
		$this->retry_counter = 0;
287
		$this->skills = $skills;
288
289
		$start = $start ?: (new Carbon())->today();
290
		$end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
291 2
292
		$results_object = $this->retrieveMsgHistory($start, $end);
293 2
		
294 2
		$results_object->_metadata->start = $start;
295 2
		$results_object->_metadata->end = $end;
296 2
	
297
		$meta = new MetaData((array) $results_object->_metadata);
298 2
		
299 2
		$collection = new ConversationHistory($results_object->conversationHistoryRecords);
300 2
		$collection->metaData = $meta;
301 2
		
302 2
		return $collection;
303 2
			
304 2
	}
305
	
306 2
	public function getConversation($conversationId)
307
	{
308 2
		$this->domain('msgHist');
309 2
		
310
		$url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/conversation/search";
311
		
312 2
		$data = new Payload([
313
			'conversationId' => $conversationId
314
		]);
315 1
		
316
		$result = $this->requestV1($url, 'POST', $data);
317 1
		if (!count($result->conversationHistoryRecords)) {
318
			return null;
319
		}
320 1
		
321
		return new Conversation((array) $result->conversationHistoryRecords[0]);
322
	}
323
324 1
	public function engagementHistory(Carbon $start = null, Carbon $end = null, $skills = [])
325
	{
326
		$this->retry_counter = 0;
327
		$this->skills = $skills;
328 1
329 1
		$start = $start ?: (new Carbon())->today();
330
		$end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
331
332
		$results_object = $this->retrieveHistory($start, $end);
333
		
334
		$results_object->_metadata->start = $start;
335
		$results_object->_metadata->end = $end;
336
	
337
		$meta = new MetaData((array) $results_object->_metadata);
338
		
339
		$collection = new EngagementHistory($results_object->interactionHistoryRecords);
340 1
		$collection->metaData = $meta;
341
		
342
		return $collection;
343
			
344
	}
345
	
346
	public function status()
347
	{
348
		$url = "https://status.liveperson.com/json?site={$this->account}";
349
		
350
		$response = $this->requestV1($url, 'GET');
351
		
352
		return new AccountStatus((array) $response);
353
	}
354
	
355
	public function login()
356
	{
357
		$this->domain('agentVep');
358
		
359
		$consumer_key = config("{$this->config}.key");
360
		$consumer_secret = config("{$this->config}.secret");
361
		$token = config("{$this->config}.token");
362
		$secret = config("{$this->config}.token_secret");
363
		$username = config("{$this->config}.user_name");
364
		
365
		$auth = [
366
			'username'		  => $username,
367
			'appKey'			=> $consumer_key,
368
			'secret'			=> $consumer_secret,
369
			'accessToken'		=> $token,
370
			'accessTokenSecret' => $secret,
371
		];
372
		
373
		$url = "https://{$this->domain}/api/account/{$this->account}/login?v=1.3";
374
		
375
		$response = $this->requestV1($url, 'POST', $auth);
376
		
377
		$this->bearer = $response->bearer;
378
		
379
		return $this;
380
	}
381
	
382
	private function requestV2($url, $method, $payload = [], $headers = [])
383
	{
384
		$this->login();
385
		
386
		$client = new Client();
387
		$args = [
388
			'headers' => array_merge([
389
				'content-type' => 'application/json',
390
				'Authorization' => 'Bearer ' . $this->bearer
391
			], $headers),
392
			'body' => json_encode($payload)
393
		];
394
		
395
		try {
396
			$res = $client->request($method, $url, $args);
397
		} catch (\Exception $e) {
398
			throw $e;
399
		} 
400
		
401
		return json_decode($res->getBody());
402
	}
403
	
404
	private function requestClient()
405
	{
406
		$consumer_key = config("{$this->config}.key");
407
		$consumer_secret = config("{$this->config}.secret");
408
		$token = config("{$this->config}.token");
409
		$secret = config("{$this->config}.token_secret");
410
411
		$stack = HandlerStack::create();
412
		$auth = new Oauth1([
413
			'consumer_key'	=> $consumer_key,
414
			'consumer_secret' => $consumer_secret,
415
			'token'		   => $token,
416
			'token_secret'	=> $secret,
417
			'signature_method'=> Oauth1::SIGNATURE_METHOD_HMAC,
418
		]);
419
		$stack->push($auth);
420
421
		$client = new Client([
422
			'handler' => $stack,
423
		]);
424
		
425
		return $client;
426
	}
427
	
428
	private function requestV1($url, $method, $payload = [])
429
	{
430
		$client = $this->requestClient();
431
432
		$args = [
433
			'auth' => 'oauth',
434
			'headers' => [
435
				'content-type' => 'application/json',
436
			],
437
			'body' => json_encode($payload)
438
		];
439
440
		try {
441
			$res = $client->request($method, $url, $args);
442
			$response = json_decode($res->getBody());
443
		} catch (\Exception $e) {
444
			if ($this->retry_counter < $this->retry_limit || $this->retry_limit == -1) {
445
				usleep(1500);
446
				$this->retry_counter++;
447
				$response = $this->requestV1($url, $payload);
448
			} else {
449
				throw $e; //new LiveEngageException("Retry limit has been exceeded ($this->retry_limit)", 100);
450
			}
451
		}
452
453
		return $response;
454
	}
455
}
456