Completed
Pull Request — master (#34)
by
unknown
02:09
created

Client::setResponseType()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
namespace Maknz\Slack;
3
4
use GuzzleHttp\Client as Guzzle;
5
use RuntimeException;
6
7
/**
8
 * @method Message to(string $channel)
9
 * @method Message send(string $text = null)
10
 */
11
class Client
12
{
13
    /**
14
     * The Slack incoming webhook endpoint.
15
     *
16
     * @var string
17
     */
18
    protected $endpoint;
19
20
    /**
21
     * The default channel to send messages to.
22
     *
23
     * @var string
24
     */
25
    protected $channel;
26
27
    /**
28
     * The default username to send messages as.
29
     *
30
     * @var string
31
     */
32
    protected $username;
33
34
    /**
35
     * The default icon to send messages with.
36
     *
37
     * @var string
38
     */
39
    protected $icon;
40
41
    /**
42
     * Whether the response should be viewable by others
43
     * when posted to a channel. 'ephemeral' | 'in_channel'.
44
     *
45
     * @var string
46
     */
47
    protected $response_type = 'ephemeral';
48
49
    /**
50
     * Whether to link names like @regan or leave
51
     * them as plain text.
52
     *
53
     * @var bool
54
     */
55
    protected $link_names = false;
56
57
    /**
58
     * Whether Slack should unfurl text-based URLs.
59
     *
60
     * @var bool
61
     */
62
    protected $unfurl_links = false;
63
64
    /**
65
     * Whether Slack should unfurl media URLs.
66
     *
67
     * @var bool
68
     */
69
    protected $unfurl_media = true;
70
71
    /**
72
     * Whether message text should be formatted with Slack's
73
     * Markdown-like language.
74
     *
75
     * @var bool
76
     */
77
    protected $allow_markdown = true;
78
79
    /**
80
     * The attachment fields which should be formatted with
81
     * Slack's Markdown-like language.
82
     *
83
     * @var array
84
     */
85
    protected $markdown_in_attachments = [];
86
87
    /**
88
     * The Guzzle HTTP client instance.
89
     *
90
     * @var \GuzzleHttp\Client
91
     */
92
    protected $guzzle;
93
94
    /**
95
     * Option name to setter method map.
96
     *
97
     * @var array
98
     */
99
    protected static $optionSetter = [
100
        'channel'                 => 'setDefaultChannel',
101
        'username'                => 'setDefaultUsername',
102
        'icon'                    => 'setDefaultIcon',
103
        'response_type'           => 'setResponseType',
104
        'link_names'              => 'setLinkNames',
105
        'unfurl_links'            => 'setUnfurlLinks',
106
        'unfurl_media'            => 'setUnfurlMedia',
107
        'allow_markdown'          => 'setAllowMarkdown',
108
        'markdown_in_attachments' => 'setMarkdownInAttachments',
109
    ];
110
111
    /**
112
     * Instantiate a new Client.
113
     *
114
     * @param string                  $endpoint
115
     * @param array                   $options
116
     * @param \GuzzleHttp\Client|null $guzzle
117
     *
118
     * @throws \InvalidArgumentException
119
     * @throws \RuntimeException
120
     */
121 9
    public function __construct($endpoint, array $options = [], Guzzle $guzzle = null)
122
    {
123 9
        $this->endpoint = $endpoint;
124
125 9
        $this->setOptions($options);
126
127 9
        $this->guzzle = $guzzle ?: new Guzzle();
128 9
    }
129
130
    /**
131
     * Returns property setter method by given option name.
132
     *
133
     * @param string $option
134
     *
135
     * @return mixed|null
136
     */
137 5
    private static function getOptionSetter(string $option)
138
    {
139 5
        return static::$optionSetter[$option] ?? null;
140
    }
141
142
    /**
143
     * Pass any unhandled methods through to a new Message
144
     * instance.
145
     *
146
     * @param string $name      The name of the method
147
     * @param array  $arguments The method arguments
148
     *
149
     * @return \Maknz\Slack\Message
150
     */
151 3
    public function __call($name, $arguments)
152
    {
153 3
        return call_user_func_array([$this->createMessage(), $name], $arguments);
154
    }
155
156
    /**
157
     * Get the Slack endpoint.
158
     *
159
     * @return string
160
     */
161 1
    public function getEndpoint()
162
    {
163 1
        return $this->endpoint;
164
    }
165
166
    /**
167
     * Set the Slack endpoint.
168
     *
169
     * @param string $endpoint
170
     *
171
     * @return void
172
     */
173
    public function setEndpoint($endpoint)
174
    {
175
        $this->endpoint = $endpoint;
176
    }
177
178
    /**
179
     * Get the default channel messages will be created for.
180
     *
181
     * @return string
182
     */
183 8
    public function getDefaultChannel()
184
    {
185 8
        return $this->channel;
186
    }
187
188
    /**
189
     * Set the default channel messages will be created for.
190
     *
191
     * @param string $channel
192
     *
193
     * @return void
194
     */
195 5
    public function setDefaultChannel($channel)
196
    {
197 5
        $this->channel = $channel;
198 5
    }
199
200
    /**
201
     * Get the default username messages will be created for.
202
     *
203
     * @return string
204
     */
205 8
    public function getDefaultUsername()
206
    {
207 8
        return $this->username;
208
    }
209
210
    /**
211
     * Set the default username messages will be created for.
212
     *
213
     * @param string $username
214
     *
215
     * @return void
216
     */
217 5
    public function setDefaultUsername($username)
218
    {
219 5
        $this->username = $username;
220 5
    }
221
222
    /**
223
     * Get the default icon messages will be created with.
224
     *
225
     * @return string
226
     */
227 8
    public function getDefaultIcon()
228
    {
229 8
        return $this->icon;
230
    }
231
232
    /**
233
     * Set the default icon messages will be created with.
234
     *
235
     * @param string $icon
236
     *
237
     * @return void
238
     */
239 2
    public function setDefaultIcon($icon)
240
    {
241 2
        $this->icon = $icon;
242 2
    }
243
244
    /**
245
     * Get whether the response should be viewable by others
246
     * when posted to a channel. 'ephemeral' | 'in_channel'.
247
     *
248
     * @return string
249
     */
250 5
    public function getResponseType()
251
    {
252 5
        return $this->response_type;
253
    }
254
255
    /**
256
     * Set whether the response should be viewable by others
257
     * when posted to a channel. 'ephemeral' | 'in_channel'.
258
     *
259
     * @param string $value
260
     *
261
     * @return void
262
     */
263 1
    public function setResponseType($value)
264
    {
265 1
        $this->response_type = $value;
266 1
    }
267
268
    /**
269
     * Get whether messages sent will have names (like @regan)
270
     * will be converted into links.
271
     *
272
     * @return bool
273
     */
274 6
    public function getLinkNames()
275
    {
276 6
        return $this->link_names;
277
    }
278
279
    /**
280
     * Set whether messages sent will have names (like @regan)
281
     * will be converted into links.
282
     *
283
     * @param bool $value
284
     *
285
     * @return void
286
     */
287 1
    public function setLinkNames($value)
288
    {
289 1
        $this->link_names = (bool)$value;
290 1
    }
291
292
    /**
293
     * Get whether text links should be unfurled.
294
     *
295
     * @return bool
296
     */
297 6
    public function getUnfurlLinks()
298
    {
299 6
        return $this->unfurl_links;
300
    }
301
302
    /**
303
     * Set whether text links should be unfurled.
304
     *
305
     * @param bool $value
306
     *
307
     * @return void
308
     */
309 1
    public function setUnfurlLinks($value)
310
    {
311 1
        $this->unfurl_links = (bool)$value;
312 1
    }
313
314
    /**
315
     * Get whether media links should be unfurled.
316
     *
317
     * @return bool
318
     */
319 6
    public function getUnfurlMedia()
320
    {
321 6
        return $this->unfurl_media;
322
    }
323
324
    /**
325
     * Set whether media links should be unfurled.
326
     *
327
     * @param bool $value
328
     *
329
     * @return void
330
     */
331 1
    public function setUnfurlMedia($value)
332
    {
333 1
        $this->unfurl_media = (bool)$value;
334 1
    }
335
336
    /**
337
     * Get whether message text should be formatted with
338
     * Slack's Markdown-like language.
339
     *
340
     * @return bool
341
     */
342 8
    public function getAllowMarkdown()
343
    {
344 8
        return $this->allow_markdown;
345
    }
346
347
    /**
348
     * Set whether message text should be formatted with
349
     * Slack's Markdown-like language.
350
     *
351
     * @param bool $value
352
     *
353
     * @return void
354
     */
355 1
    public function setAllowMarkdown($value)
356
    {
357 1
        $this->allow_markdown = (bool)$value;
358 1
    }
359
360
    /**
361
     * Get the attachment fields which should be formatted
362
     * in Slack's Markdown-like language.
363
     *
364
     * @return array
365
     */
366 8
    public function getMarkdownInAttachments()
367
    {
368 8
        return $this->markdown_in_attachments;
369
    }
370
371
    /**
372
     * Set the attachment fields which should be formatted
373
     * in Slack's Markdown-like language.
374
     *
375
     * @param array $fields
376
     *
377
     * @return void
378
     */
379 1
    public function setMarkdownInAttachments(array $fields)
380
    {
381 1
        $this->markdown_in_attachments = $fields;
382 1
    }
383
384
    /**
385
     * Create a new message with defaults.
386
     *
387
     * @return \Maknz\Slack\Message
388
     */
389 7
    public function createMessage()
390
    {
391 7
        $message = new Message($this);
392
393 7
        $message->setChannel($this->getDefaultChannel());
394
395 7
        $message->setUsername($this->getDefaultUsername());
396
397 7
        $message->setIcon($this->getDefaultIcon());
398
399 7
        $message->setAllowMarkdown($this->getAllowMarkdown());
400
401 7
        $message->setMarkdownInAttachments($this->getMarkdownInAttachments());
402
403 7
        return $message;
404
    }
405
406
    /**
407
     * Send a message.
408
     *
409
     * @param \Maknz\Slack\Message $message
410
     *
411
     * @throws \RuntimeException
412
     */
413 1
    public function sendMessage(Message $message)
414
    {
415 1
        $payload = $this->preparePayload($message);
416
417 1
        $encoded = json_encode($payload, JSON_UNESCAPED_UNICODE);
418
419 1
        if ($encoded === false) {
420 1
            throw new RuntimeException(sprintf('JSON encoding error %s: %s', json_last_error(), json_last_error_msg()));
421
        }
422
423
        $this->guzzle->post($this->endpoint, ['body' => $encoded]);
424
    }
425
426
    /**
427
     * Prepares the payload to be sent to the webhook.
428
     *
429
     * @param \Maknz\Slack\Message $message The message to send
430
     *
431
     * @return array
432
     */
433 5
    public function preparePayload(Message $message)
434
    {
435
        $payload = [
436 5
            'text'         => $message->getText(),
437 5
            'channel'      => $message->getChannel(),
438 5
            'username'     => $message->getUsername(),
439 5
            'response_type'=> $this->getResponseType(),
440 5
            'link_names'   => $this->getLinkNames() ? 1 : 0,
441 5
            'unfurl_links' => $this->getUnfurlLinks(),
442 5
            'unfurl_media' => $this->getUnfurlMedia(),
443 5
            'mrkdwn'       => $message->getAllowMarkdown(),
444
        ];
445
446 5
        if ($icon = $message->getIcon()) {
447
            $payload[$message->getIconType()] = $icon;
448
        }
449
450 5
        $payload['attachments'] = $this->getAttachmentsAsArrays($message);
451
452 5
        return $payload;
453
    }
454
455
    /**
456
     * Get the attachments in array form.
457
     *
458
     * @param \Maknz\Slack\Message $message
459
     *
460
     * @return array
461
     */
462 5
    protected function getAttachmentsAsArrays(Message $message)
463
    {
464 5
        $attachments = [];
465
466 5
        foreach ($message->getAttachments() as $attachment) {
467 3
            $attachments[] = $attachment->toArray();
468
        }
469
470 5
        return $attachments;
471
    }
472
473
    /**
474
     * @param array $options
475
     *
476
     * @return \Maknz\Slack\Client
477
     */
478 9
    public function setOptions(array $options)
479
    {
480 9
        foreach ($options as $option => $value) {
481 5
            $this->setOption($option, $value);
482
        }
483
484 9
        return $this;
485
    }
486
487
    /**
488
     * @param $option
489
     * @param $value
490
     */
491 5
    public function setOption($option, $value)
492
    {
493 5
        $setter = self::getOptionSetter($option);
494 5
        if ($setter !== null) {
495 5
            $this->$setter($value);
496
        }
497 5
    }
498
}
499