├── .gitignore
├── .travis.yml
├── LICENCE
├── README.md
├── composer.json
├── makephar
├── phpunit.xml.dist
├── src
├── Attachment.php
├── Exceptions
│ ├── SlackBotException.php
│ └── SlackRequestException.php
├── Handlers
│ ├── CurlHandler.php
│ └── RequestHandler.php
├── Message.php
├── Mrkdwn.php
├── SlackBot.php
├── SlackRequest.php
├── Transferrable.php
└── WebColors.php
└── tests
├── AttachmentTest.php
├── MessageTest.php
├── Mocks
└── MockHandler.php
├── MrkdwnTest.php
├── RequestTest.php
└── SlackBotTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### JetBrains template
3 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
4 |
5 | *.iml
6 |
7 | ## Directory-based project format:
8 | .idea/
9 | # if you remove the above rule, at least ignore the following:
10 |
11 | # User-specific stuff:
12 | # .idea/workspace.xml
13 | # .idea/tasks.xml
14 | # .idea/dictionaries
15 |
16 | # Sensitive or high-churn files:
17 | # .idea/dataSources.ids
18 | # .idea/dataSources.xml
19 | # .idea/sqlDataSources.xml
20 | # .idea/dynamic.xml
21 | # .idea/uiDesigner.xml
22 |
23 | # Gradle:
24 | # .idea/gradle.xml
25 | # .idea/libraries
26 |
27 | # Mongo Explorer plugin:
28 | # .idea/mongoSettings.xml
29 |
30 | ## File-based project format:
31 | *.ipr
32 | *.iws
33 |
34 | ## Plugin-specific files:
35 |
36 | # IntelliJ
37 | /out/
38 |
39 | # mpeltonen/sbt-idea plugin
40 | .idea_modules/
41 |
42 | # JIRA plugin
43 | atlassian-ide-plugin.xml
44 |
45 | # Crashlytics plugin (for Android Studio and IntelliJ)
46 | com_crashlytics_export_strings.xml
47 | crashlytics.properties
48 | crashlytics-build.properties
49 |
50 |
51 | ### Composer template
52 | composer.phar
53 | vendor/
54 | composer.lock
55 |
56 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
57 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
58 | # composer.lock
59 |
60 |
61 |
62 | /phpslackbot.phar
63 | phpunit.local.xml
64 | /.gitignore
65 |
66 | # Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
67 | # You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
68 | # composer.lock
69 |
70 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 |
3 | language: php
4 | php:
5 | - '5.3'
6 | - '5.4'
7 | - '5.5'
8 |
9 | before_script: composer install
10 |
11 | script: phpunit --coverage-clover=coverage.clover
12 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Vlad Lyga
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PHP-SlackBot [](https://packagist.org/packages/lygav/php-slackbot)
2 |
3 | [](https://travis-ci.org/lygav/php-slackbot)
4 | []()
5 | [](https://packagist.org/packages/lygav/php-slackbot)
6 | [](https://packagist.org/packages/lygav/php-slackbot)
7 |
8 |
9 |
10 |
11 | Simple, easy to use, PHP package for sending messages to Slack.
12 | Send pretty, colourful messages with rich attachments quickly with this friendly API.
13 |
14 | Compatible with PHP >= 5.3
15 |
16 | ## Installation
17 | ### Via composer
18 | ```json
19 | "require": {
20 | "lygav/php-slackbot": "0.0.*"
21 | }
22 | ```
23 |
24 | ### Without composer, via PHAR
25 | From the command line, enter into the cloned repository dir and run:
26 | ```
27 | php makephar
28 | ```
29 | You will see that a new file was created named "phpslackbot.phar".
30 | Then in your application:
31 | ```php
32 | include 'path/to/phpslackbot.phar';
33 | ```
34 | The rest is the same as when installed with 'composer'
35 |
36 | ## Your first message
37 | ```PHP
38 | $bot = new Slackbot("https://hooks.slack.com/services/your/incoming/hook");
39 | $bot->text("Hi")->send();
40 | ```
41 | ## Direct messages
42 | ```PHP
43 | $bot->text("Hi all!")
44 | ->from("username")
45 | ->toChannel("mychannel")
46 | ->send();
47 | ```
48 | ## Create pretty, colorful attachments easily
49 | ```PHP
50 | $bot->attach(
51 | $bot->buildAttachment("fallback text")
52 | ->enableMarkdown()
53 | ->setText("We can have *mrkdwn* `code` _italic_ also in attachments")
54 | )
55 | ->toGroup("mygroup")
56 | ->send();
57 | ```
58 |
59 | ## Customise freely
60 | ```PHP
61 | $attachment = $bot->buildAttachment("fallback text"/* mandatory by slack */)
62 | ->setPretext("pretext line")
63 | ->setText("attachment body text")
64 | /*
65 | Human web-safe colors automatically
66 | translated into HEX equivalent
67 | */
68 | ->setColor("lightblue")
69 | ->setAuthor("me")
70 | ->addField("short field", "i'm inline", TRUE)
71 | ->addField("short field 2", "i'm also inline", TRUE)
72 | ->setImageUrl("http://my-website.com/path/to/image.jpg");
73 |
74 | $bot->attach($attachment)->send();
75 | ```
76 |
77 | ## Set/ Override every possible setting
78 | ```PHP
79 | $options = array(
80 | 'username' => 'my-bot-name',
81 | 'icon_emoji' => ':icon name:',
82 | 'icon_url' => 'http://someicon.com',
83 | 'channel' => '#test-channel'
84 | );
85 |
86 | $bot = new Slackbot($url, $options);
87 | $bot->text("check out bot new icon")->send();
88 |
89 | // Choose to override 'last minute' (ex. when dealing with multiple consequtive messages)
90 | $bot->text("check out bot new icon")->send(array("username" => "other-bot-name"));
91 | ```
92 |
93 | # Advanced Usage
94 |
95 | ## Use custom transfer handlers
96 | ```PHP
97 | $handler = new MockHandler();
98 | $bot = new SlackBot($url, ['handler' => $handler]);
99 | $bot->text("some text")
100 | ->from("my-test-bot")
101 | ->toGroup("bot-testing")
102 | ->send();
103 | ```
104 |
105 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lygav/php-slackbot",
3 | "description": "Simple, easy to use, PHP package for sending messages to Slack. Send pretty, colourful messages with rich attachments quickly with this friendly API",
4 | "minimum-stability": "stable",
5 | "homepage": "https://github.com/lygav/php-slackbot",
6 | "keywords": [
7 | "slack",
8 | "slackbot",
9 | "php-slackbot"
10 | ],
11 | "license": "MIT",
12 | "type": "library",
13 | "authors": [
14 | {
15 | "name": "Vladimir (Vladi) Lyga",
16 | "homepage": "https://github.com/lygav",
17 | "email": "lyvladi@gmail.com"
18 | }
19 | ],
20 |
21 | "require": {
22 | "php": ">=5.3"
23 | },
24 |
25 | "require-dev": {
26 | "phpunit/phpunit": "3.7.*"
27 | },
28 |
29 | "autoload": {
30 | "psr-4": {
31 | "lygav\\slackbot\\": "src/"
32 | }
33 | },
34 |
35 | "autoload-dev": {
36 | "psr-4": { "lygav\\slackbot\\tests\\": "tests/" }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/makephar:
--------------------------------------------------------------------------------
1 | buildFromDirectory(dirname(__FILE__));
6 | $stub = '
7 |
17 | ';
18 |
19 | spl_autoload_register(function($class) {
20 | $filepath = str_replace("lygav\\slackbot", "src/", $class);
21 | $filepath = str_replace("\\", "/", $filepath);
22 | $path = dirname(__FILE__)."/".$filepath.".php";
23 | include $path;
24 | });
25 |
26 |
27 | $phar->setStub($stub);
28 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | ./tests
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/Attachment.php:
--------------------------------------------------------------------------------
1 | options["fallback"] = (string) $fallback;
15 | }
16 |
17 | public static function fromOptions(array $options)
18 | {
19 | if ( ! isset($options['fallback'])) {
20 | throw new SlackBotException("'fallback' is mandatory for
21 | attachments");
22 | }
23 | $attachment = new self($options['fallback']);
24 | if (isset($options['color'])) {
25 | $attachment->setColor($options['color']);
26 | unset($options['color']);
27 | }
28 | $attachment->options = array_replace($attachment->options, $options);
29 | return $attachment;
30 | }
31 |
32 | public function serialize()
33 | {
34 | return $this->options;
35 | }
36 |
37 | public function enableMarkdown(array $in_options = array())
38 | {
39 | if (empty($in_options)) {
40 | $this->applyOption("mrkdwn_in", array_keys($this->options));
41 | } else {
42 | $this->applyOption("mrkdwn_in", $in_options);
43 | }
44 | return $this;
45 | }
46 |
47 | public function setTitle($title)
48 | {
49 | $this->applyOption('title', $title);
50 | return $this;
51 | }
52 |
53 | public function addField($title, $text, $is_short = FALSE)
54 | {
55 | if ( ! isset($this->options['fields'])
56 | OR ! is_array($this->options['fields'])
57 | ) {
58 | $this->options['fields'] = array();
59 | }
60 | array_push($this->options['fields'], array(
61 | 'title' => $title,
62 | 'value' => $text,
63 | 'short' => $is_short
64 | ));
65 | return $this;
66 | }
67 |
68 | public function setAuthor($name, $link = NULL, $icon = NULL)
69 | {
70 | $this->applyOption('author_name', $name);
71 | $this->applyOption('author_link', $link);
72 | $this->applyOption('author_icon', $icon);
73 | return $this;
74 | }
75 |
76 | public function setColor($color)
77 | {
78 | $this->applyOption('color', WebColors::human2hex($color) ? : $color);
79 | return $this;
80 | }
81 |
82 | public function setText($text)
83 | {
84 | $this->applyOption('text', $text);
85 | return $this;
86 | }
87 |
88 | /**
89 | * @param string $pretext
90 | */
91 | public function setPretext($pretext)
92 | {
93 | $this->applyOption('pretext', $pretext);
94 | return $this;
95 | }
96 |
97 | /**
98 | * @param null $image_url
99 | */
100 | public function setImageUrl($image_url)
101 | {
102 | $this->applyOption('image_url', $image_url);
103 | return $this;
104 | }
105 |
106 | /**
107 | * @param null $thumb_url
108 | */
109 | public function setThumbUrl($thumb_url)
110 | {
111 | $this->applyOption('thumb_url', $thumb_url);
112 | return $this;
113 | }
114 |
115 | private function applyOption($name, $value)
116 | {
117 | $this->options[$name] = $value;
118 | return $this;
119 | }
120 | }
--------------------------------------------------------------------------------
/src/Exceptions/SlackBotException.php:
--------------------------------------------------------------------------------
1 | $request->url(),
17 | CURLOPT_POSTFIELDS => $request->body(),
18 | CURLOPT_SSL_VERIFYPEER => FALSE,
19 | CURLOPT_SSL_VERIFYHOST => FALSE,
20 | CURLOPT_POST => TRUE,
21 | CURLOPT_RETURNTRANSFER => TRUE,
22 | )
23 | );
24 | $result = curl_exec($ch);
25 | curl_close($ch);
26 | return $result;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/Handlers/RequestHandler.php:
--------------------------------------------------------------------------------
1 | text = (string) $text;
14 | $this->options = $options;
15 | }
16 |
17 | public function attach(Attachment $attachment)
18 | {
19 | array_push($this->attachments, $attachment->serialize());
20 | }
21 |
22 | public function serialize()
23 | {
24 | $ret = array_merge(array('text' => $this->text), $this->options);
25 | if ( ! empty($this->attachments)) {
26 | $ret['attachments'] = $this->attachments;
27 | }
28 | return $ret;
29 | }
30 | }
--------------------------------------------------------------------------------
/src/Mrkdwn.php:
--------------------------------------------------------------------------------
1 | ", (strpos($slackname, "@") === 0 ? "" : "@") . $slackname);
11 | }
12 |
13 | public static function channelRef($channel)
14 | {
15 | $channel = self::normalize($channel);
16 | return sprintf("<%s>", (strpos($channel, "#") === 0 ? "" : "#") . $channel);
17 | }
18 |
19 | public static function code($text)
20 | {
21 | return sprintf("`%s`", $text);
22 | }
23 |
24 | public static function pre($text)
25 | {
26 | return sprintf("```%s```", $text);
27 | }
28 |
29 | public static function link($url, $alias)
30 | {
31 | $url = self::normalize($url);
32 | $alias = self::normalize($alias);
33 | return sprintf("<%s|%s>", $url, $alias);
34 | }
35 |
36 | private static function normalize($string)
37 | {
38 | return preg_replace(
39 | array("#(^\s|\s$)+#", "#[\r\n\s\s]+#"), array("", " "), $string);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/SlackBot.php:
--------------------------------------------------------------------------------
1 | webhook_url = $webhook_url;
21 | if (isset($options['handler'])) {
22 | $this->handler = $options['handler'];
23 | unset($options['handler']);
24 | }
25 | $this->global_options = $options;
26 | }
27 |
28 | public function text($text)
29 | {
30 | $this->text = $text;
31 | return $this;
32 | }
33 |
34 | public function from($name)
35 | {
36 | $this->setRequestOption('username', $name);
37 | return $this;
38 | }
39 |
40 | public function attach(Attachment $attachment)
41 | {
42 | array_push($this->attachments, $attachment);
43 | return $this;
44 | }
45 |
46 | public function buildAttachment($fallback_text)
47 | {
48 | return new Attachment($fallback_text);
49 | }
50 |
51 | public function toChannel($name)
52 | {
53 | $this->setRequestChannel($name);
54 | return $this;
55 | }
56 |
57 | public function toGroup($name)
58 | {
59 | $this->setRequestChannel($name);
60 | return $this;
61 | }
62 |
63 | public function toPerson($name)
64 | {
65 | $this->setRequestChannel($name, TRUE);
66 | return $this;
67 | }
68 |
69 | public function send(array $options = array())
70 | {
71 | $options = array_replace($this->global_options, $this->request_options, $options);
72 | $message = new Message($this->text, $options);
73 | if ( ! empty($this->attachments)) {
74 | array_map(array($message, 'attach'), $this->attachments);
75 | }
76 | $request = new SlackRequest($this->webhook_url, $message);
77 | $this->transfer($request);
78 | $this->reset();
79 | }
80 |
81 | public function disableMarkdown()
82 | {
83 | $this->setRequestOption('mrkdwn', FALSE);
84 | return $this;
85 | }
86 |
87 | public function enableMarkdown()
88 | {
89 | $this->setRequestOption('mrkdwn', TRUE);
90 | return $this;
91 | }
92 |
93 | private function transfer(SlackRequest $request)
94 | {
95 | $result = call_user_func($this->handler(), $request);
96 | if ($result !== 'ok') {
97 | throw new SlackRequestException($result);
98 | } else {
99 | return $result;
100 | }
101 | }
102 |
103 | private function reset()
104 | {
105 | $this->attachments = array();
106 | $this->text = "";
107 | $this->request_options = array();
108 | }
109 |
110 | private function handler()
111 | {
112 | return $this->handler ? : new CurlHandler();
113 | }
114 |
115 | private function setRequestChannel($name, $private = FALSE)
116 | {
117 | if ($private) {
118 | $this->setRequestOption('channel', strpos($name, "@") === 0 ? : "@".$name);
119 | } else {
120 | $this->setRequestOption('channel', strpos($name, "#") === 0 ? : "#".$name);
121 | }
122 | }
123 |
124 | private function setRequestOption($name, $value)
125 | {
126 | $this->request_options[$name] = $value;
127 | }
128 | }
--------------------------------------------------------------------------------
/src/SlackRequest.php:
--------------------------------------------------------------------------------
1 | url = $url;
16 | $this->setBody($message->serialize());
17 | }
18 |
19 | public function body()
20 | {
21 | return $this->payload_for($this->body);
22 | }
23 |
24 | private function setBody(array $body)
25 | {
26 | $empty_body = array('text' => '');
27 | if ($body === $empty_body) {
28 | throw new SlackRequestException("Trying to construct SlackRequest with empty message");
29 | }
30 | $this->body = $body;
31 | }
32 |
33 | public function url()
34 | {
35 | return $this->url;
36 | }
37 |
38 | private function payload_for($body)
39 | {
40 | return http_build_query(
41 | array("payload" => json_encode($body))
42 | );
43 | }
44 | }
--------------------------------------------------------------------------------
/src/Transferrable.php:
--------------------------------------------------------------------------------
1 | "#F0F8FF",
9 | "antiquewhite" => "#FAEBD7",
10 | "aqua" => "#00FFFF",
11 | "aquamarine" => "#7FFFD4",
12 | "azure" => "#F0FFFF",
13 | "beige" => "#F5F5DC",
14 | "bisque" => "#FFE4C4",
15 | "black" => "#000000",
16 | "blanchedalmond" => "#FFEBCD",
17 | "blue" => "#0000FF",
18 | "blueviolet" => "#8A2BE2",
19 | "brown" => "#A52A2A",
20 | "burlywood" => "#DEB887",
21 | "cadetblue" => "#5F9EA0",
22 | "chartreuse" => "#7FFF00",
23 | "chocolate" => "#D2691E",
24 | "coral" => "#FF7F50",
25 | "cornflowerblue" => "#6495ED",
26 | "cornsilk" => "#FFF8DC",
27 | "crimson" => "#DC143C",
28 | "cyan" => "#00FFFF",
29 | "darkblue" => "#00008B",
30 | "darkcyan" => "#008B8B",
31 | "darkgoldenrod" => "#B8860B",
32 | "darkgray" => "#A9A9A9",
33 | "darkgreen" => "#006400",
34 | "darkkhaki" => "#BDB76B",
35 | "darkmagenta" => "#8B008B",
36 | "darkolivegreen" => "#556B2F",
37 | "darkorange" => "#FF8C00",
38 | "darkorchid" => "#9932CC",
39 | "darkred" => "#8B0000",
40 | "darksalmon" => "#E9967A",
41 | "darkseagreen" => "#8FBC8F",
42 | "darkslateblue" => "#483D8B",
43 | "darkslategray" => "#2F4F4F",
44 | "darkturquoise" => "#00CED1",
45 | "darkviolet" => "#9400D3",
46 | "deeppink" => "#FF1493",
47 | "deepskyblue" => "#00BFFF",
48 | "dimgray" => "#696969",
49 | "dodgerblue" => "#1E90FF",
50 | "firebrick" => "#B22222",
51 | "floralwhite" => "#FFFAF0",
52 | "forestgreen" => "#228B22",
53 | "fuchsia" => "#FF00FF",
54 | "gainsboro" => "#DCDCDC",
55 | "ghostwhite" => "#F8F8FF",
56 | "gold" => "#FFD700",
57 | "goldenrod" => "#DAA520",
58 | "gray" => "#808080",
59 | "green" => "#008000",
60 | "greenyellow" => "#ADFF2F",
61 | "honeydew" => "#F0FFF0",
62 | "hotpink" => "#FF69B4",
63 | "indianred" => "#CD5C5C",
64 | "indigo" => "#4B0082",
65 | "ivory" => "#FFFFF0",
66 | "khaki" => "#F0E68C",
67 | "lavender" => "#E6E6FA",
68 | "lavenderblush" => "#FFF0F5",
69 | "lawngreen" => "#7CFC00",
70 | "lemonchiffon" => "#FFFACD",
71 | "lightblue" => "#ADD8E6",
72 | "lightcoral" => "#F08080",
73 | "lightcyan" => "#E0FFFF",
74 | "lightgoldenrodyellow" => "#FAFAD2",
75 | "lightgray" => "#D3D3D3",
76 | "lightgreen" => "#90EE90",
77 | "lightpink" => "#FFB6C1",
78 | "lightsalmon" => "#FFA07A",
79 | "lightseagreen" => "#20B2AA",
80 | "lightskyblue" => "#87CEFA",
81 | "lightslategray" => "#778899",
82 | "lightsteelblue" => "#B0C4DE",
83 | "lightyellow" => "#FFFFE0",
84 | "lime" => "#00FF00",
85 | "limegreen" => "#32CD32",
86 | "linen" => "#FAF0E6",
87 | "magenta" => "#FF00FF",
88 | "maroon" => "#800000",
89 | "mediumaquamarine" => "#66CDAA",
90 | "mediumblue" => "#0000CD",
91 | "mediumorchid" => "#BA55D3",
92 | "mediumpurple" => "#9370DB",
93 | "mediumseagreen" => "#3CB371",
94 | "mediumslateblue" => "#7B68EE",
95 | "mediumspringgreen" => "#00FA9A",
96 | "mediumturquoise" => "#48D1CC",
97 | "mediumvioletred" => "#C71585",
98 | "midnightblue" => "#191970",
99 | "mintcream" => "#F5FFFA",
100 | "mistyrose" => "#FFE4E1",
101 | "moccasin" => "#FFE4B5",
102 | "navajowhite" => "#FFDEAD",
103 | "navy" => "#000080",
104 | "oldlace" => "#FDF5E6",
105 | "olive" => "#808000",
106 | "olivedrab" => "#6B8E23",
107 | "orange" => "#FFA500",
108 | "orangered" => "#FF4500",
109 | "orchid" => "#DA70D6",
110 | "palegoldenrod" => "#EEE8AA",
111 | "palegreen" => "#98FB98",
112 | "paleturquoise" => "#AFEEEE",
113 | "palevioletred" => "#DB7093",
114 | "papayawhip" => "#FFEFD5",
115 | "peachpuff" => "#FFDAB9",
116 | "peru" => "#CD853F",
117 | "pink" => "#FFC0CB",
118 | "plum" => "#DDA0DD",
119 | "powderblue" => "#B0E0E6",
120 | "purple" => "#800080",
121 | "rebeccapurple" => "#663399",
122 | "red" => "#FF0000",
123 | "rosybrown" => "#BC8F8F",
124 | "royalblue" => "#4169E1",
125 | "saddlebrown" => "#8B4513",
126 | "salmon" => "#FA8072",
127 | "sandybrown" => "#F4A460",
128 | "seagreen" => "#2E8B57",
129 | "seashell" => "#FFF5EE",
130 | "sienna" => "#A0522D",
131 | "silver" => "#C0C0C0",
132 | "skyblue" => "#87CEEB",
133 | "slateblue" => "#6A5ACD",
134 | "slategray" => "#708090",
135 | "snow" => "#FFFAFA",
136 | "springgreen" => "#00FF7F",
137 | "steelblue" => "#4682B4",
138 | "tan" => "#D2B48C",
139 | "teal" => "#008080",
140 | "thistle" => "#D8BFD8",
141 | "tomato" => "#FF6347",
142 | "turquoise" => "#40E0D0",
143 | "violet" => "#EE82EE",
144 | "wheat" => "#F5DEB3",
145 | "white" => "#FFFFFF",
146 | "whitesmoke" => "#F5F5F5",
147 | "yellow" => "#FFFF00",
148 | "YellowGreen" => "#9ACD32"
149 | );
150 |
151 | public static function human2hex($color_name)
152 | {
153 | $color_name = strtolower((string) $color_name);
154 | if (array_key_exists($color_name, self::$color_map)) {
155 | return self::$color_map[$color_name];
156 | }
157 | return FALSE;
158 | }
159 |
160 | public static function hex2human($color_code)
161 | {
162 | $color_code = strtoupper((string) $color_code);
163 | if (FALSE !== ($index = array_search($color_code, self::$color_map))) {
164 | return $index;
165 | }
166 | return FALSE;
167 | }
168 | }
--------------------------------------------------------------------------------
/tests/AttachmentTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(array ('fallback' => 'test fallback text'), $attachment->serialize());
16 | }
17 |
18 | public function testCanCreateFromFullOptionsArray()
19 | {
20 | $options = array(
21 | 'fallback' => 'fallback test',
22 | 'color' => '#000000',
23 | 'author_name' => 'bobby',
24 | 'author_link' => 'http://flickr.com/bobby/',
25 | 'author_icon' => 'http://flickr.com/icons/bobby.jpg',
26 | 'title' => 'Optional title',
27 | 'text' => 'optional text',
28 | 'pretext' => 'optional pretext',
29 | 'image_url' => 'http://my-website.com/path/to/image.jpg',
30 | 'thumb_url' => 'http://example.com/path/to/thumb.png'
31 | );
32 | $attachment = Attachment::fromOptions($options);
33 | $this->assertEquals($options, $attachment->serialize());
34 | }
35 |
36 | public function testEnableMarkdownForAllOptions()
37 | {
38 | $options = array(
39 | 'fallback' => 'fallback text',
40 | 'text' => 'my bold *text*',
41 | 'pretext' => 'some _italic_ markdown here'
42 | );
43 | $attachment = Attachment::fromOptions($options);
44 | $attachment->enableMarkdown();
45 | $this->assertEquals(array (
46 | 'fallback' => 'fallback text',
47 | 'text' => 'my bold *text*',
48 | 'pretext' => 'some _italic_ markdown here',
49 | 'mrkdwn_in' =>
50 | array (
51 | 'fallback',
52 | 'text',
53 | 'pretext',
54 | ),
55 | ), $attachment->serialize());
56 | }
57 |
58 | public function testEnableMarkdownOnlyForSelectedOptions()
59 | {
60 | $options = array(
61 | 'fallback' => 'fallback text',
62 | 'text' => 'my bold *text*',
63 | 'pretext' => 'some _italic_ markdown here'
64 | );
65 | $attachment = Attachment::fromOptions($options);
66 | $attachment->enableMarkdown(array('text'));
67 | $this->assertEquals(array (
68 | 'fallback' => 'fallback text',
69 | 'text' => 'my bold *text*',
70 | 'pretext' => 'some _italic_ markdown here',
71 | 'mrkdwn_in' =>
72 | array (
73 | 'text'
74 | ),
75 | ), $attachment->serialize());
76 | }
77 |
78 | public function testReplaceHumanColorNameWithHexCode()
79 | {
80 | $options = array('fallback' => 'fallback text', 'color' => 'black');
81 | $attachment = Attachment::fromOptions($options);
82 | $options['color'] = WebColors::human2hex($options['color']);
83 | $this->assertEquals($options, $attachment->serialize());
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/tests/MessageTest.php:
--------------------------------------------------------------------------------
1 | assertEquals(
16 | array("text" => $text),
17 | $message->serialize()
18 | );
19 | }
20 |
21 | public function testSerializeWithOptions()
22 | {
23 | $text = "hello world";
24 | $options = array(
25 | 'username' => 'my-bot-name',
26 | 'icon_emoji' => ':icon name:',
27 | 'icon_url' => 'http://someicon.com',
28 | 'channel' => '#test-channel'
29 | );
30 | $message = new Message($text, $options);
31 | $this->assertEquals(
32 | array_merge(array("text" => $text), $options),
33 | $message->serialize()
34 | );
35 | }
36 |
37 | public function testSerializeWithAttachment()
38 | {
39 | $text = "hello worlds";
40 | $message = new Message($text);
41 | $message->attach(new Attachment('plain text fallback'));
42 | $this->assertEquals(
43 | array(
44 | "text" => $text,
45 | "attachments" => array(
46 | array("fallback" => "plain text fallback")
47 | )
48 | ),
49 | $message->serialize()
50 | );
51 | }
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/tests/Mocks/MockHandler.php:
--------------------------------------------------------------------------------
1 | request = $request;
14 | return 'ok';
15 | }
16 |
17 | public function lastRequest()
18 | {
19 | return $this->request;
20 | }
21 | }
--------------------------------------------------------------------------------
/tests/MrkdwnTest.php:
--------------------------------------------------------------------------------
1 | '),
14 | array('@withsign', '<@withsign>')
15 | );
16 | }
17 |
18 | /**
19 | * @dataProvider userNames
20 | */
21 | public function testFormatsNameStringIntoUserReference($unformatted, $expected)
22 | {
23 | $this->assertEquals(
24 | $expected,
25 | Mrkdwn::userRef($unformatted)
26 | );
27 | }
28 |
29 | public function chanelNames()
30 | {
31 | return array(
32 | array('withoutatsign', '<#withoutatsign>'),
33 | array('#withsign', '<#withsign>')
34 | );
35 | }
36 |
37 | /**
38 | * @dataProvider chanelNames
39 | */
40 | public function testFormatNameStringIntoChannelReference($unformatted, $expected)
41 | {
42 | $this->assertEquals(
43 | $expected,
44 | Mrkdwn::channelRef($unformatted)
45 | );
46 | }
47 |
48 | public function strings()
49 | {
50 | return array(
51 | array("http://google.com", "search google", ""),
52 | array("http://google.com", "search google", ""),
53 | array(" http://google.com ", " search google ", ""),
54 | array("http://google.com", "search\ngoogle", ""),
55 | array("http://google.com", "search\r\ngoogle", ""),
56 | );
57 | }
58 |
59 | /**
60 | * @dataProvider strings
61 | */
62 | public function testNormalizeText($link, $alias, $expected)
63 | {
64 | $this->assertEquals(
65 | $expected,
66 | Mrkdwn::link($link, $alias)
67 | );
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/tests/RequestTest.php:
--------------------------------------------------------------------------------
1 | assertEquals('payload={"text":"hello world"}',
18 | urldecode($request->body()));
19 | }
20 |
21 | public function testCreatePayloadForMessageWithAttachment()
22 | {
23 | $message = new Message('hello world');
24 | $message->attach(new Attachment("fallback text"));
25 | $request = new SlackRequest('http://url.com', $message);
26 |
27 | $this->assertEquals('payload={"text":"hello world","attachments":[{"fallback":"fallback text"}]}',
28 | urldecode($request->body()));
29 | }
30 |
31 | public function emptyMessageProvider()
32 | {
33 | return array(
34 | array(new Message(NULL)),
35 | array(new Message(""))
36 | );
37 | }
38 |
39 | /**
40 | * @dataProvider emptyMessageProvider
41 | * @expectedException lygav\slackbot\Exceptions\SlackRequestException
42 | */
43 | public function testExceptionOnEmptyMessage(Message $message)
44 | {
45 | new SlackRequest("www.url.com", $message);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/tests/SlackBotTest.php:
--------------------------------------------------------------------------------
1 | handler = new MockHandler();
25 | $this->slackbot = new SlackBot($this->url, array('handler' => $this->handler));
26 | }
27 |
28 | public function testSupplyCustomHandler()
29 | {
30 | $handler = new MockHandler();
31 | $bot = new SlackBot($this->url, array('handler' => $handler));
32 | $bot->text("some text")
33 | ->from("my-test-bot")
34 | ->toGroup("bot-testing")
35 | ->send();
36 | $this->assertInstanceOf("lygav\\slackbot\\SlackRequest", $handler->lastRequest());
37 | }
38 |
39 | public function testOverrideOptionsOnSend()
40 | {
41 | $slack = $this->defaultTestBot();
42 | $slack->text("some text")->send(array(
43 | "username" => "overriden-bot-name"
44 | ));
45 | }
46 |
47 | public function testSendMessageWithSimpleAttachment()
48 | {
49 | $slack = $this->defaultTestBot();
50 | $slack->text("Markdown formatted text with *bold* `code` _italic_")
51 | ->attach(
52 | $slack->buildAttachment("fallback text")
53 | ->enableMarkdown()
54 | ->setText("We can have *mrkdwn* `code` _italic_ also in attachments")
55 | )
56 | ->toGroup("bot-testing")
57 | ->send();
58 | }
59 |
60 | public function testCreateCompleteAttachments()
61 | {
62 | $slack = $this->defaultTestBot();
63 | $attachment = $slack->buildAttachment("fallback text"/* mandatory by slack */)
64 | ->setPretext("pretext line")
65 | ->setText("attachment body text")
66 | /*
67 | Human web-safe colors automatically
68 | translated into HEX equivalent
69 | */
70 | ->setColor("lightblue")
71 | ->setAuthor("tester")
72 | ->addField("short field", "i'm inline", TRUE)
73 | ->addField("short field 2", "i'm also inline", TRUE)
74 | ->setImageUrl("http://my-website.com/path/to/image.jpg");
75 |
76 | $slack->attach($attachment)->send();
77 | }
78 |
79 | /**
80 | * @expectedException lygav\slackbot\Exceptions\SlackRequestException
81 | */
82 | public function testThrowExceptionOnEmptyRequest()
83 | {
84 | $bot = new SlackBot($this->url);
85 | $bot->send();
86 | }
87 |
88 | /**
89 | * @return SlackBot
90 | */
91 | public function defaultTestBot()
92 | {
93 | return $this->slackbot;
94 | }
95 | }
--------------------------------------------------------------------------------