Passed
Branch master (61755c)
by Robert
02:34
created

LiveEngageLaravel::__set()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
c 0
b 0
f 0
rs 10
cc 1
eloc 1
nc 1
nop 2
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\Payload;
11
use LivePersonInc\LiveEngageLaravel\Models\Visitor;
12
use LivePersonInc\LiveEngageLaravel\Models\Agent;
13
use LivePersonInc\LiveEngageLaravel\Models\Campaign;
14
use LivePersonInc\LiveEngageLaravel\Models\Engagement;
15
use LivePersonInc\LiveEngageLaravel\Models\Conversation;
16
use LivePersonInc\LiveEngageLaravel\Collections\EngagementHistory;
17
use LivePersonInc\LiveEngageLaravel\Collections\Humans;
18
use LivePersonInc\LiveEngageLaravel\Exceptions\LiveEngageException;
19
use LivePersonInc\LiveEngageLaravel\Collections\ConversationHistory;
20
21
class LiveEngageLaravel
22
{
23
    private $account = false;
24
    private $results = [];
25
    private $skills = [];
26
    private $next = false;
27
    private $prev = false;
28
    private $start;
29
    private $end;
30
    private $config = 'services.liveperson.default';
31
    private $version = '1.0';
32
    private $history_limit = 50;
33
    private $history = false;
34
    private $context = 'interactionHistoryRecords';
35
    private $interactive = true;
36
    private $ended = true;
37
    private $bearer = false;
38
39
    private $domain = false;
40
41
    private $retry_limit = 5;
42
    private $retry_counter = 0;
43
44
    public function __get($attribute)
45
    {
46
        return $this->$attribute;
47
    }
48
49
    public function __set($attribute, $value)
50
    {
51
        return $this->$attribute = $value;
52
    }
53
54
    public function __construct()
55
    {
56
        $this->account = config("{$this->config}.account");
57
        //$this->domain = config("{$this->config}.domain");
58
        $this->version = config("{$this->config}.version") ?: $this->version;
59
    }
60
61
    public function key($key = 'default')
62
    {
63
        $this->config = "services.liveperson.$key";
64
65
        return $this;
66
    }
67
    
68
    public function nonInteractive()
69
    {
70
	    $this->interactive = false;
71
	    return $this;
72
    }
73
    
74
    public function active()
75
    {
76
	    $this->ended = false;
77
	    return $this;
78
    }
79
80
    public function limit($limit)
81
    {
82
        $this->history_limit = $limit;
83
84
        return $this;
85
    }
86
87
    public function skills($skills)
88
    {
89
        $this->skills = $skills;
90
91
        return $this;
92
    }
93
94
    public function retry($limit)
95
    {
96
        $this->retry_limit = $limit;
97
98
        return $this;
99
    }
100
101
    public function get()
102
    {
103
        return $this->results;
104
    }
105
106
    public function account($accountid)
107
    {
108
        $this->account = $accountid;
109
110
        return $this;
111
    }
112
113
    public function domain($service)
114
    {
115
        $response = $this->requestV1("https://api.liveperson.net/api/account/{$this->account}/service/{$service}/baseURI.json?version={$this->version}", 'GET');
116
        if (is_a($response, 'Exception')) {
0 ignored issues
show
Bug introduced by
It seems like $response can also be of type mixed; however, parameter $object of is_a() does only seem to accept object|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

116
        if (is_a(/** @scrutinizer ignore-type */ $response, 'Exception')) {
Loading history...
117
            throw new \Exception('Unable to get LivePerson account domain', 101);
118
        } else {
119
            $this->domain = $response->baseURI;
120
121
            return $this;
122
        }
123
    }
124
125
    public function visitor($visitorID, $sessionID, $setData = false)
126
    {
127
        $this->domain('smt');
128
129
        if ($setData) {
130
            $url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/events?v=1&sid={$sessionID}";
131
132
            return $this->requestV1($url, 'POST', $setData);
133
        } else {
134
            $url = "https://{$this->domain}/api/account/{$this->account}/monitoring/visitors/{$visitorID}/visits/current/state?v=1&sid={$sessionID}";
135
136
            return $this->requestV1($url, 'GET');
137
        }
138
    }
139
140
    final public function retrieveHistory(Carbon $start, Carbon $end, $url = false)
141
    {
142
        $this->domain('engHistDomain');
143
144
        $url = $url ?: "https://{$this->domain}/interaction_history/api/account/{$this->account}/interactions/search?limit={$this->history_limit}&offset=0";
145
146
        $start_str = $start->toW3cString();
147
        $end_str = $end->toW3cString();
148
149
        $data = [
150
            'interactive' => $this->interactive,
151
            'ended' => $this->ended,
152
            'start' => [
153
                'from' => strtotime($start_str).'000',
154
                'to' => strtotime($end_str).'000',
155
            ],
156
        ];
157
        if (count($this->skills)) {
158
            $data['skillIds'] = $this->skills;
159
        }
160
161
        $data = new Payload($data);
162
163
        return $this->requestV1($url, 'POST', $data);
164
    }
165
166
    final public function retrieveMsgHistory(Carbon $start, Carbon $end, $url = false)
167
    {
168
        $this->domain('msgHist');
169
170
        $url = $url ?: "https://{$this->domain}/messaging_history/api/account/{$this->account}/conversations/search?limit={$this->history_limit}&offset=0";
171
172
        $start_str = $start->toW3cString();
173
        $end_str = $end->toW3cString();
174
175
        $data = [
176
            'interactive' => $this->interactive,
177
            'ended' => $this->ended,
178
            'start' => [
179
                'from' => strtotime($start_str).'000',
180
                'to' => strtotime($end_str).'000',
181
            ],
182
        ];
183
        if (count($this->skills)) {
184
            $data['skillIds'] = $this->skills;
185
        }
186
187
        $data = new Payload($data);
188
189
        return $this->requestV1($url, 'POST', $data);
190
    }
191
    
192
    public function getAgentStatus(array $skills)
193
    {
194
	
195
	    $this->domain('msgHist');
196
        
197
        $url = "https://{$this->domain}/messaging_history/api/account/{$this->account}/agent-view/status";
198
        
199
        $data['skillIds'] = $skills;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.
Loading history...
200
        
201
        $response = $this->requestV1($url, 'POST', $data);
202
        $agents = [];
203
        
204
        foreach ($response->agentStatusRecords as $agent) {
0 ignored issues
show
Bug introduced by
The property agentStatusRecords does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
Bug introduced by
The property agentStatusRecords does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
205
	        $agents[] = new Agent((array) $agent);
206
        }
207
        
208
        $collection = new Humans($agents);
209
        $collection->metaData = $response->_metadata;
0 ignored issues
show
Bug introduced by
The property metaData does not seem to exist on LivePersonInc\LiveEngageLaravel\Collections\Humans.
Loading history...
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
210
        
211
        return $collection;
212
        
213
    }
214
215
    public function messagingHistory(Carbon $start = null, Carbon $end = null)
216
    {
217
        $this->retry_counter = 0;
218
219
        $start = $start ?: (new Carbon())->today();
220
        $end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
221
222
        $this->start = $start;
223
        $this->end = $end;
224
225
		if (is_object($results_object)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $results_object does not exist. Did you maybe mean $results?
Loading history...
226
227
	        $results_object = $this->retrieveMsgHistory($start, $end);
228
	        $results = $results_object->conversationHistoryRecords;
0 ignored issues
show
Bug introduced by
The property conversationHistoryRecords does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
Bug introduced by
The property conversationHistoryRecords does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
229
	        if (property_exists($results_object->_metadata, 'next')) {
0 ignored issues
show
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
230
	            $this->next = $results_object->_metadata->next->href;
231
	        }
232
	        if (property_exists($results_object->_metadata, 'prev')) {
233
	            $this->prev = $results_object->_metadata->prev->href;
234
	        }
235
	
236
	        $history = [];
237
	        foreach ($results as $item) {
238
	            if (property_exists($item, 'info')) {
239
	                $item->info = new Info((array) $item->info);
240
	            }
241
	
242
	            if (property_exists($item, 'visitorInfo')) {
243
	                $item->visitorInfo = new Visitor((array) $item->visitorInfo);
244
	            }
245
	
246
	            if (property_exists($item, 'campaign')) {
247
	                $item->campaign = new Campaign((array) $item->campaign);
248
	            }
249
	
250
	            $history[] = new Conversation((array) $item);
251
	        }
252
	
253
	        $collection = new ConversationHistory($history, $this);
254
	        $collection->metaData = $results_object->_metadata;
0 ignored issues
show
Bug introduced by
The property metaData does not seem to exist on LivePersonInc\LiveEngage...ons\ConversationHistory.
Loading history...
255
	        
256
	        return $collection;
257
	        
258
	    } else {
259
		    return false;
260
	    }
261
    }
262
263
    public function history(Carbon $start = null, Carbon $end = null)
264
    {
265
        $this->retry_counter = 0;
266
267
        $start = $start ?: (new Carbon())->today();
268
        $end = $end ?: (new Carbon())->today()->addHours(23)->addMinutes(59);
269
270
        $this->start = $start;
271
        $this->end = $end;
272
273
        $results_object = $this->retrieveHistory($start, $end);
274
        
275
        if (is_object($results_object)) {
276
        
277
	        $results = $results_object->interactionHistoryRecords;
0 ignored issues
show
Bug introduced by
The property interactionHistoryRecords does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
Bug introduced by
The property interactionHistoryRecords does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
278
	        if (property_exists($results_object->_metadata, 'next')) {
0 ignored issues
show
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
Bug introduced by
The property _metadata does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
279
	            $this->next = $results_object->_metadata->next->href;
280
	        }
281
	        if (property_exists($results_object->_metadata, 'prev')) {
282
	            $this->prev = $results_object->_metadata->prev->href;
283
	        }
284
	
285
	        $history = [];
286
	        foreach ($results as $item) {
287
	            if (property_exists($item, 'info')) {
288
	                $item->info = new Info((array) $item->info);
289
	            }
290
	
291
	            if (property_exists($item, 'visitorInfo')) {
292
	                $item->visitorInfo = new Visitor((array) $item->visitorInfo);
293
	            }
294
	
295
	            if (property_exists($item, 'campaign')) {
296
	                $item->campaign = new Campaign((array) $item->campaign);
297
	            }
298
	
299
	            $history[] = new Engagement((array) $item);
300
	        }
301
	        
302
	        $collection = new EngagementHistory($history, $this);
303
	        $collection->metaData = $results_object->_metadata;
0 ignored issues
show
Bug introduced by
The property metaData does not seem to exist on LivePersonInc\LiveEngage...tions\EngagementHistory.
Loading history...
304
	        
305
	        return $collection;
306
	        
307
        } else {
308
	        return false;
309
        }
310
    }
311
    
312
    public function login()
313
    {
314
	    $this->domain('agentVep');
315
	    
316
	    $consumer_key = config("{$this->config}.key");
317
        $consumer_secret = config("{$this->config}.secret");
318
        $token = config("{$this->config}.token");
319
        $secret = config("{$this->config}.token_secret");
320
        $username = config("{$this->config}.user_name");
321
        
322
        $auth = [
323
	        'username'          => $username,
324
            'appKey'            => $consumer_key,
325
            'secret'            => $consumer_secret,
326
            'accessToken'		=> $token,
327
            'accessTokenSecret' => $secret,
328
        ];
329
        
330
        $url = "https://{$this->domain}/api/account/{$this->account}/login?v=1.3";
331
        
332
        $response = $this->requestV1($url, 'POST', $auth);
333
        
334
        $this->bearer = $response->bearer;
0 ignored issues
show
Bug introduced by
The property bearer does not seem to exist on GuzzleHttp\Exception\ConnectException.
Loading history...
Bug introduced by
The property bearer does not seem to exist on GuzzleHttp\Exception\ClientException.
Loading history...
335
        
336
        return $this;
337
    }
338
    
339
    private function requestV2($url, $method, $payload = false)
0 ignored issues
show
Unused Code introduced by
The method requestV2() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
340
    {
341
	    if (!$this->bearer) $this->login();
342
	    
343
	    $client = new Client();
344
	    $args = [
345
		    'headers' => [
346
			    'Authorization' => $this->bearer
347
		    ]
348
	    ];
349
	    
350
	    if ($payload !== false) {
351
            $args['body'] = json_encode($payload);
352
        }
353
	    
354
	    try {
355
		    $res = $client->request($method, $url, $args);
356
	    } catch (\Exception $e) {
357
		    throw $e;
358
	    } 
359
	    
360
	    return json_decode($res->getBody());
361
    }
362
363
    private function requestV1($url, $method, $payload = false)
364
    {
365
        $consumer_key = config("{$this->config}.key");
366
        $consumer_secret = config("{$this->config}.secret");
367
        $token = config("{$this->config}.token");
368
        $secret = config("{$this->config}.token_secret");
369
370
        $stack = HandlerStack::create();
371
        $auth = new Oauth1([
372
            'consumer_key'    => $consumer_key,
373
            'consumer_secret' => $consumer_secret,
374
            'token'           => $token,
375
            'token_secret'    => $secret,
376
            'signature_method'=> Oauth1::SIGNATURE_METHOD_HMAC,
377
        ]);
378
        $stack->push($auth);
379
380
        $client = new Client([
381
            'handler' => $stack,
382
        ]);
383
384
        $args = [
385
            'auth' => 'oauth',
386
            'headers' => [
387
                'content-type' => 'application/json',
388
            ],
389
        ];
390
391
        if ($payload !== false) {
392
            $args['body'] = json_encode($payload);
393
        }
394
395
        try {
396
            $res = $client->request($method, $url, $args);
397
398
            $response = json_decode($res->getBody());
399
        } catch (\GuzzleHttp\Exception\ConnectException $connection) {
400
            return $connection;
401
        } catch (\GuzzleHttp\Exception\ClientException $clientException) {
402
	        return $clientException;
403
        } catch (\Exception $e) {
404
            if ($this->retry_counter < $this->retry_limit || $this->retry_limit == -1) {
405
                usleep(1500);
406
                $this->retry_counter++;
407
                $response = $this->requestV1($url, $payload);
408
            } else {
409
                throw $e; //new LiveEngageException("Retry limit has been exceeded ($this->retry_limit)", 100);
410
            }
411
        }
412
413
        return $response;
414
    }
415
}
416