Passed
Branch development (0290f6)
by Robert
06:05
created

LiveEngageLaravel::engagementHistory()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 12
cts 12
cp 1
rs 9.6333
c 0
b 0
f 0
cc 3
nc 1
nop 3
crap 3
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
48
	private $retry_limit = 5;
49
	private $retry_counter = 0;
50
51 5
	public function __get($attribute)
52
	{
53 5
		return $this->$attribute;
54
	}
55
56 8
	public function __construct()
57
	{
58 8
		$this->account = config("{$this->config}.account");
59
		//$this->domain = config("{$this->config}.domain");
60 8
		$this->version = config("{$this->config}.version") ?: $this->version;
61 8
	}
62
63 1
	public function key($key = 'default')
64
	{
65 1
		$this->config = "services.liveperson.$key";
66 1
		$this->__construct();
67
68 1
		return $this;
69
	}
70
	
71 1
	public function nonInteractive()
72
	{
73 1
		$this->interactive = false;
74 1
		return $this;
75
	}
76
	
77 1
	public function active()
78
	{
79 1
		$this->ended = false;
80 1
		return $this;
81
	}
82
83 1
	public function limit($limit)
84
	{
85 1
		$this->history_limit = $limit;
86
87 1
		return $this;
88
	}
89
90 1
	public function retry($limit)
91
	{
92 1
		$this->retry_limit = $limit;
93
94 1
		return $this;
95
	}
96
97 1
	public function account($accountid)
98
	{
99 1
		$this->account = $accountid;
100
101 1
		return $this;
102
	}
103
104 1
	public function domain($service)
105
	{
106 1
		$response = $this->requestV1("https://api.liveperson.net/api/account/{$this->account}/service/{$service}/baseURI.json?version={$this->version}", 'GET');
107
		
108 1
		$this->domain = $response->baseURI;
109
110 1
		return $this;
111
	}
112
113
	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
		
132
		$url = "https://{$this->domain}/api/account/{$this->account}/chat/request?v=1&NC=true";
133
		
134
		$args = [
135
			
136
		];
137
		$payload = new Payload($args);
138
		
139
		$response = $this->requestV1($url, 'POST', $payload);
140
		
141
		return $response;
142
	}
143
144 1
	final public function retrieveHistory(Carbon $start, Carbon $end, $url = false)
145
	{
146 1
		$this->domain('engHistDomain');
147
148 1
		$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 1
		$end_str = $end->toW3cString();
152
153 1
		$data = new Payload([
154 1
			'interactive' => $this->interactive,
155 1
			'ended' => $this->ended,
156
			'start' => [
157 1
				'from' => strtotime($start_str) . '000',
158 1
				'to' => strtotime($end_str) . '000',
159
			],
160 1
			'skillIds' => $this->skills
161
		]);
162
163 1
		return $this->requestV1($url, 'POST', $data);
164
	}
165
166 1
	final public function retrieveMsgHistory(Carbon $start, Carbon $end, $url = false)
167
	{
168 1
		$this->domain('msgHist');
169
170 1
		$url = $url ?: "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/search?limit={$this->history_limit}&offset=0&sort=start:desc";
171
172 1
		$start_str = $start->toW3cString();
173 1
		$end_str = $end->toW3cString();
174
175 1
		$data = new Payload([
176 1
			'status' => $this->ended ? ['CLOSE'] : ['OPEN', 'CLOSE'],
177
			'start' => [
178 1
				'from' => strtotime($start_str) . '000',
179 1
				'to' => strtotime($end_str) . '000',
180
			],
181 1
			'skillIds' => $this->skills
182
		]);
183
		
184 1
		return $this->requestV1($url, 'POST', $data);
185
	}
186
	
187 1
	public function skills()
188
	{
189 1
		$this->domain('accountConfigReadOnly');
190
		
191 1
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/skills?v=4.0";
192
		
193 1
		return new Skills($this->requestV2($url, 'GET'));
194
	}
195
	
196
	public function getSkill($skillId)
197
	{
198
		$this->domain('accountConfigReadOnly');
199
		
200
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/skills/{$skillId}?v=4.0";
201
		
202
		return new Skill((array) $this->requestV2($url, 'GET'));
203
	}
204
	
205
	public function getAgent($userId)
206
	{
207
		$this->domain('accountConfigReadOnly');
208
		
209
		$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
	
214
	public function updateAgent($userId, $properties)
215
	{
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
		
218
		$this->domain('accountConfigReadWrite');
219
		
220
		$url = "https://{$this->domain}/api/account/{$this->account}/configuration/le-users/users/{$userId}?v=4.0";
221
		$headers = [
222
			'X-HTTP-Method-Override' => 'PUT',
223
			'if-Match' => '*'
224
		];
225
		
226
		return new Agent((array) $this->requestV2($url, 'PUT', $properties, $headers));
227
	}
228
	
229
	public function agents()
230
	{
231
		$this->domain('accountConfigReadOnly');
232
		
233
		$select = implode(',', [
234
			'id',
235
			'pid',
236
			'deleted',
237
			'loginName',
238
			'skills',
239
			'nickname',
240
			'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 1
	public function getAgentStatus($skills)
267
	{
268 1
		$skills = is_array($skills) ? $skills : [$skills];
269
	
270 1
		$this->domain('msgHist');
271
		
272 1
		$url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/agent-view/status";
273
		
274 1
		$data = ['skillIds' => $skills];
275
		
276 1
		$response = $this->requestV1($url, 'POST', $data);
277 1
		$collection = new AgentParticipants($response->agentStatusRecords);
278 1
		$collection->metaData = new MetaData((array) $response->_metadata);
279
		
280 1
		return $collection;
281
		
282
	}
283
	
284 1
	public function conversationHistory(Carbon $start = null, Carbon $end = null, $skills = [])
285
	{
286 1
		$this->retry_counter = 0;
287 1
		$this->skills = $skills;
288
289 1
		$start = $start ?: (new Carbon())->today();
290 1
		$end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
291
292 1
		$results_object = $this->retrieveMsgHistory($start, $end);
293
		
294 1
		$results_object->_metadata->start = $start;
295 1
		$results_object->_metadata->end = $end;
296
	
297 1
		$meta = new MetaData((array) $results_object->_metadata);
298
		
299 1
		$collection = new ConversationHistory($results_object->conversationHistoryRecords);
300 1
		$collection->metaData = $meta;
301
		
302 1
		return $collection;
303
			
304
	}
305
	
306
	public function getConversation($conversationId)
307
	{
308
		$this->domain('msgHist');
309
		
310
		$url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/conversation/search";
311
		
312
		$data = new Payload([
313
			'conversationId' => $conversationId
314
		]);
315
		
316
		$result = $this->requestV1($url, 'POST', $data);
317
		if (!count($result->conversationHistoryRecords)) {
318
			return null;
319
		}
320
		
321
		return new Conversation((array) $result->conversationHistoryRecords[0]);
322
	}
323
324 1
	public function engagementHistory(Carbon $start = null, Carbon $end = null, $skills = [])
325
	{
326 1
		$this->retry_counter = 0;
327 1
		$this->skills = $skills;
328
329 1
		$start = $start ?: (new Carbon())->today();
330 1
		$end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
331
332 1
		$results_object = $this->retrieveHistory($start, $end);
333
		
334 1
		$results_object->_metadata->start = $start;
335 1
		$results_object->_metadata->end = $end;
336
	
337 1
		$meta = new MetaData((array) $results_object->_metadata);
338
		
339 1
		$collection = new EngagementHistory($results_object->interactionHistoryRecords);
340 1
		$collection->metaData = $meta;
341
		
342 1
		return $collection;
343
			
344
	}
345
	
346 1
	public function status()
347
	{
348 1
		$url = "https://status.liveperson.com/json?site={$this->account}";
349
		
350 1
		$response = $this->requestV1($url, 'GET');
351
		
352 1
		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 2
	private function requestClient()
405
	{
406 2
		$consumer_key = config("{$this->config}.key");
407 2
		$consumer_secret = config("{$this->config}.secret");
408 2
		$token = config("{$this->config}.token");
409 2
		$secret = config("{$this->config}.token_secret");
410
411 2
		$stack = HandlerStack::create();
412 2
		$auth = new Oauth1([
413 2
			'consumer_key'	=> $consumer_key,
414 2
			'consumer_secret' => $consumer_secret,
415 2
			'token'		   => $token,
416 2
			'token_secret'	=> $secret,
417 2
			'signature_method'=> Oauth1::SIGNATURE_METHOD_HMAC,
418
		]);
419 2
		$stack->push($auth);
420
421 2
		$client = new Client([
422 2
			'handler' => $stack,
423
		]);
424
		
425 2
		return $client;
426
	}
427
	
428 1
	private function requestV1($url, $method, $payload = [])
429
	{
430 1
		$client = $this->requestClient();
431
432
		$args = [
433 1
			'auth' => 'oauth',
434
			'headers' => [
435
				'content-type' => 'application/json',
436
			],
437 1
			'body' => json_encode($payload)
438
		];
439
440
		try {
441 1
			$res = $client->request($method, $url, $args);
442 1
			$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 1
		return $response;
454
	}
455
}
456