├── .editorConfig ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── slack.php └── tests.php /.editorConfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | # All files. 4 | [*] 5 | end_of_line = LF 6 | indent_style = space 7 | indent_size = 4 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.php] 13 | indent_size = 4 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Composer 4 | composer.phar 5 | /vendor/ 6 | 7 | # Visual Studio Code 8 | .history 9 | .vscode 10 | .vscode-insiders 11 | *.code-workspace -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Simon Backx 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Slack PHP Webhook 2 | [![Latest Stable Version](https://poser.pugx.org/simonbackx/slack-php-webhook/v/stable)](https://packagist.org/packages/simonbackx/slack-php-webhook) [![License](https://poser.pugx.org/simonbackx/slack-php-webhook/license)](https://packagist.org/packages/simonbackx/slack-php-webhook) 3 | 4 | Easy to use PHP library to post messages in Slack using incoming webhook integrations. 5 | 6 | # Setup 7 | Log in at slack.com with your team. Go to the page with all your integrations. Add a new incoming webhook. 8 | 9 | Select a default channel to post your messages. 10 | ![Setup1](http://www.cloock.be/uploads/slack1.png) 11 | 12 | Confirm "Add Incoming WebHook integration" 13 | Next, you will find your WebHook URL which you need to use this library. Save it somewhere secure. 14 | 15 | ![Setup2](http://www.cloock.be/uploads/slack2.png) 16 | 17 | When you scroll all the way down, you get more options to change your default username, description and icon. You can overwrite these in your code. 18 | 19 | # Usage 20 | ## Installation 21 | 22 | ### Composer 23 | 24 | Add Slack-PHP-Webhook to your composer.json file or run `composer require simonbackx/slack-php-webhook` 25 | 26 | ```json 27 | { 28 | "require": { 29 | "simonbackx/slack-php-webhook": "~1.0" 30 | } 31 | } 32 | ``` 33 | 34 | ### Alternative 35 | 36 | Download slack.php and require/include it in your PHP file. 37 | 38 | ## Simple message 39 | 40 | ```php 41 | // Use the url you got earlier 42 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 43 | 44 | // Create a new message 45 | $message = new SlackMessage($slack); 46 | $message->setText("Hello world!"); 47 | 48 | // Send it! 49 | if ($message->send()) { 50 | echo "Hurray 😄"; 51 | } else { 52 | echo "Failed 😢"; 53 | } 54 | ``` 55 | 56 | ## Send to a channel 57 | ```php 58 | // Use the url you got earlier 59 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 60 | 61 | // Create a new message 62 | $message = new SlackMessage($slack); 63 | $message->setText("Hello world!")->setChannel("#general"); 64 | 65 | // Send it! 66 | $message->send(); 67 | ``` 68 | 69 | ## Send to a user 70 | ```php 71 | // Use the url you got earlier 72 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 73 | 74 | // Create a new message 75 | $message = new SlackMessage($slack); 76 | $message->setText("Hello world!")->setChannel("@simonbackx"); 77 | 78 | // Send it! 79 | $message->send(); 80 | ``` 81 | 82 | ## Overwriting defaults 83 | You can overwrite the defaults on two levels: in a Slack instance (defaults for all messages using this Slack instance) or SlackMessage instances (only for the current message). These methods will not modify your root defaults at Slack.com, but will overwrite them temporary in your code. 84 | 85 | ```php 86 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 87 | $slack->setDefaultUsername("SlackPHP robot"); 88 | $slack->setDefaultChannel("#general"); 89 | 90 | // Unfurl links: automatically fetch and create attachments for detected URLs 91 | $slack->setDefaultUnfurlLinks(true); 92 | 93 | // Set the default icon for messages to a custom image 94 | $slack->setDefaultIcon("http://www.domain.com/robot.png"); 95 | 96 | // Use a 👻 emoji as default icon for messages if it is not overwritten in messages 97 | $slack->setDefaultEmoji(":ghost:"); 98 | 99 | // Create a new message 100 | $message = new SlackMessage($slack); 101 | $message->setText("Hello world!"); 102 | $message->setChannel("#general"); 103 | 104 | // Unfurl links: automatically fetch and create attachments for detected URLs 105 | $message->setUnfurlLinks(false); 106 | 107 | // Set the icon for the message to a custom image 108 | $message->setIcon("http://www.domain.com/robot2.png"); 109 | 110 | // Overwrite the default Emoji (if any) with 😊 111 | $message->setEmoji(":simple_smile:"); 112 | 113 | // Send it! 114 | $message->send(); 115 | 116 | ``` 117 | 118 | ## Attachments 119 | ### Create an attachment 120 | Check out https://api.slack.com/docs/attachments for more details 121 | 122 | ```php 123 | // Use the url you got earlier 124 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 125 | $slack->setDefaultUsername('Fly company'); 126 | 127 | // Create a new message 128 | $message = new SlackMessage($slack); 129 | 130 | $attachment = new SlackAttachment("Required plain-text summary of the attachment."); 131 | $attachment->setColor("#36a64f"); 132 | $attachment->setText("*Optional text* that appears within the attachment"); 133 | $attachment->setPretext("Optional text that appears above the attachment block"); 134 | $attachment->setAuthor( 135 | "Author name", 136 | "http://flickr.com/bobby/", //Optional author link 137 | "http://flickr.com/bobby/picture.jpg" // Optional author icon 138 | ); 139 | $attachment->setTitle("Title", "Optional link e.g. http://www.google.com/"); 140 | $attachment->setImage("http://www.domain.com/picture.jpg"); 141 | 142 | /* 143 | Slack messages may be formatted using a simple markup language similar to Markdown. Supported 144 | formatting includes: ```pre```, `code`, _italic_, *bold*, and even ~strike~.; full details are 145 | available on the Slack help site. 146 | 147 | By default bot message text will be formatted, but attachments are not. To enable formatting on 148 | attachment fields, you can use enableMarkdownFor 149 | */ 150 | $attachment->enableMarkdownFor("text"); 151 | $attachment->enableMarkdownFor("pretext"); 152 | $attachment->enableMarkdownFor("fields"); 153 | 154 | // Add fields, last parameter stand for short (smaller field) and is optional 155 | $attachment->addField("Title", "Value"); 156 | $attachment->addField("Title2", "Value2", true); 157 | $attachment->addField("Title", "Value", false); 158 | 159 | // Add a footer 160 | $attachment->setFooterText('By Simon'); 161 | $attachment->setFooterIcon('https://www.simonbackx.com/favicon.png'); 162 | $attachment->setTimestamp(time()); 163 | 164 | // Add it to your message 165 | $message->addAttachment($attachment); 166 | 167 | // Send 168 | $message->send(); 169 | ``` 170 | [View the result](https://api.slack.com/docs/messages/builder?msg=%7B%0A%20%20%20%20%22text%22%3A%20%22%22%2C%0A%20%20%20%20%22username%22%3A%20%22Fly%20company%22%2C%0A%20%20%20%20%22attachments%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22fallback%22%3A%20%22Required%20plain-text%20summary%20of%20the%20attachment.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22color%22%3A%20%22%2336a64f%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22pretext%22%3A%20%22Optional%20text%20that%20appears%20above%20the%20attachment%20block%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22author_name%22%3A%20%22Author%20name%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22mrkdwn_in%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22text%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22pretext%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22fields%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22author_link%22%3A%20%22http%3A%2F%2Fflickr.com%2Fbobby%2F%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22author_icon%22%3A%20%22http%3A%2F%2Fflickr.com%2Fbobby%2Fpicture.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Title%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22title_link%22%3A%20%22Optional%20link%20e.g.%20http%3A%2F%2Fwww.google.com%2F%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22text%22%3A%20%22%2AOptional%20text%2A%20that%20appears%20within%20the%20attachment%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22fields%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Title%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22value%22%3A%20%22Value%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Title2%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22value%22%3A%20%22Value2%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22short%22%3A%20true%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22title%22%3A%20%22Title%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22value%22%3A%20%22Value%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22short%22%3A%20false%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22image_url%22%3A%20%22http%3A%2F%2Fwww.domain.com%2Fpicture.jpg%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22footer%22%3A%20%22By%20Simon%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22footer_icon%22%3A%20%22https%3A%2F%2Fwww.simonbackx.com%2Ffavicon.png%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22ts%22%3A%201523486931%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%0A%7D) 171 | 172 | ## Add buttons 173 | ```php 174 | // Use the url you got earlier 175 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 176 | $slack->setDefaultUsername('Fly company'); 177 | 178 | // Create a new message 179 | $message = new SlackMessage($slack); 180 | $message->setText("<@W1A2BC3DD> approved your travel request. Book any airline you like by continuing below."); 181 | 182 | // Create a new Attachment with fallback text, a plain-text summary of the attachment. 183 | // This text will be used in clients that don't show formatted text (eg. IRC, mobile 184 | // notifications) and should not contain any markup. 185 | $attachment = new \SlackAttachment('Book your flights at https://flights.example.com/book/r123456'); 186 | $attachment->addButton('Book flights 🛫', 'https://flights.example.com/book/r123456'); 187 | $attachment->addButton('Unsubscribe', 'https://flights.example.com/unsubscribe', 'danger'); 188 | 189 | $message->addAttachment($attachment); 190 | 191 | $message->send(); 192 | ``` 193 | [View the result](https://api.slack.com/docs/messages/builder?msg=%7B%0A%20%20%20%20%22text%22%3A%20%22%3C%40W1A2BC3DD%3E%20approved%20your%20travel%20request.%20Book%20any%20airline%20you%20like%20by%20continuing%20below.%22%2C%0A%20%20%20%20%22username%22%3A%20%22Fly%20company%22%2C%0A%20%20%20%20%22icon_emoji%22%3A%20%22%3Aairplane%3A%22%2C%0A%20%20%20%20%22attachments%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22fallback%22%3A%20%22Book%20your%20flights%20at%20https%3A%2F%2Fflights.example.com%2Fbook%2Fr123456%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22actions%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22button%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22text%22%3A%20%22Book%20flights%20%F0%9F%9B%AB%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20%22https%3A%2F%2Fflights.example.com%2Fbook%2Fr123456%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22type%22%3A%20%22button%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22text%22%3A%20%22Unsubscribe%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22url%22%3A%20%22https%3A%2F%2Fflights.example.com%2Funsubscribe%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22style%22%3A%20%22danger%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%0A%7D) 194 | 195 | ### Add (multiple) attachments 196 | ```php 197 | $message = new SlackMessage($slack); 198 | $message->addAttachment($attachment1); 199 | $message->addAttachment($attachment2); 200 | $message->send(); 201 | ``` 202 | 203 | ## Short syntax 204 | 205 | All methods support a short syntax. E.g.: 206 | 207 | ```php 208 | (new SlackMessage($slack)) 209 | ->addAttachment($attachment1) 210 | ->addAttachment($attachment2) 211 | ->send(); 212 | ``` 213 | 214 | # Warning 215 | Each message initiates a new HTTPS request, which takes some time. Don't send too much messages at once if you are not running your script in a background task. 216 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simonbackx/slack-php-webhook", 3 | "type": "library", 4 | "description": "Post messages to your Slack channels with this easy to use library.", 5 | "keywords": ["Slack", "Webhook", "Channels", "Logging", "Message"], 6 | "homepage": "https://github.com/SimonBackx/Slack-PHP-Webhook", 7 | "license": "MIT", 8 | 9 | "authors": [ 10 | { 11 | "name": "Simon Backx", 12 | "email": "hi@simonbackx.com", 13 | "homepage": "https://www.simonbackx.com", 14 | "role": "Developer" 15 | } 16 | ], 17 | 18 | "support": { 19 | "source": "https://github.com/SimonBackx/Slack-PHP-Webhook", 20 | "issues": "https://github.com/SimonBackx/Slack-PHP-Webhook/issues" 21 | }, 22 | 23 | "autoload": { 24 | "files": ["slack.php"] 25 | } 26 | } -------------------------------------------------------------------------------- /slack.php: -------------------------------------------------------------------------------- 1 | Default username set in Slack Webhook integration settings 35 | public $username; 36 | 37 | // Empty => Default channel set in Slack Webhook integration settings 38 | public $channel; 39 | 40 | // Empty => Default icon set in Slack Webhook integration settings 41 | public $icon_url; 42 | 43 | // Empty => Default icon set in Slack Webhook integration settings 44 | public $icon_emoji; 45 | 46 | // Unfurl links: automatically fetch and create attachments for URLs 47 | // Empty = default (false) 48 | public $unfurl_links; 49 | 50 | function __construct($webhookUrl) { 51 | $this->url = $webhookUrl; 52 | } 53 | 54 | function __isset($property) { 55 | return isset($this->$property); 56 | } 57 | 58 | function send(SlackMessage $message) { 59 | $data = $message->toArray(); 60 | 61 | try { 62 | $json = json_encode($data); 63 | 64 | $curl = curl_init(); 65 | curl_setopt_array($curl, array( 66 | CURLOPT_RETURNTRANSFER => 1, 67 | CURLOPT_URL => $this->url, 68 | CURLOPT_USERAGENT => 'cURL Request', 69 | CURLOPT_POST => 1, 70 | CURLOPT_POSTFIELDS => array('payload' => $json), 71 | )); 72 | $result = curl_exec($curl); 73 | 74 | if (!$result) { 75 | return false; 76 | } 77 | 78 | curl_close($curl); 79 | 80 | if ($result == 'ok') { 81 | return true; 82 | } 83 | 84 | return false; 85 | } catch (Exception $e) { 86 | return false; 87 | } 88 | 89 | } 90 | 91 | function setDefaultUnfurlLinks($unfurl) { 92 | $this->unfurl_links = $unfurl; 93 | return $this; 94 | } 95 | 96 | function setDefaultChannel($channel) { 97 | $this->channel = $channel; 98 | return $this; 99 | } 100 | 101 | function setDefaultUsername($username) { 102 | $this->username = $username; 103 | return $this; 104 | } 105 | 106 | function setDefaultIcon($url) { 107 | $this->icon_url = $url; 108 | return $this; 109 | } 110 | 111 | function setDefaultEmoji($emoji) { 112 | $this->icon_emoji = $emoji; 113 | return $this; 114 | } 115 | } 116 | 117 | class SlackMessage { 118 | private $slack; 119 | 120 | // Message to post 121 | public $text = ""; 122 | 123 | // Empty => Default username set in Slack instance 124 | public $username; 125 | 126 | // Empty => Default channel set in Slack instance 127 | public $channel; 128 | 129 | // Empty => Default icon set in Slack instance 130 | public $icon_url; 131 | 132 | // Empty => Default icon set in Slack instance 133 | public $icon_emoji; 134 | 135 | public $unfurl_links; 136 | 137 | // Array of SlackAttachment instances 138 | public $attachments; 139 | 140 | function __construct(Slack $slack) { 141 | $this->slack = $slack; 142 | } 143 | 144 | /* 145 | Settings 146 | */ 147 | function setText($text) { 148 | $this->text = $text; 149 | return $this; 150 | } 151 | 152 | function setUsername($username) { 153 | $this->username = $username; 154 | return $this; 155 | } 156 | 157 | function setChannel($channel) { 158 | $this->channel = $channel; 159 | return $this; 160 | } 161 | 162 | function setEmoji($emoji) { 163 | $this->icon_emoji = $emoji; 164 | return $this; 165 | } 166 | 167 | function setIcon($url) { 168 | $this->icon_url = $url; 169 | return $this; 170 | } 171 | 172 | function setUnfurlLinks($bool) { 173 | $this->unfurl_links = $bool; 174 | return $this; 175 | } 176 | 177 | function addAttachment(SlackAttachment $attachment) { 178 | if (!isset($this->attachments)) { 179 | $this->attachments = array($attachment); 180 | return $this; 181 | } 182 | 183 | $this->attachments[] = $attachment; 184 | return $this; 185 | } 186 | 187 | function toArray() { 188 | // Loading defaults 189 | if (isset($this->slack->username)) { 190 | $username = $this->slack->username; 191 | } 192 | 193 | if (isset($this->slack->channel)) { 194 | $channel = $this->slack->channel; 195 | } 196 | 197 | if (isset($this->slack->icon_url)) { 198 | $icon_url = $this->slack->icon_url; 199 | } 200 | 201 | if (isset($this->slack->icon_emoji)) { 202 | $icon_emoji = $this->slack->icon_emoji; 203 | } 204 | 205 | if (isset($this->slack->unfurl_links)) { 206 | $unfurl_links = $this->slack->unfurl_links; 207 | } 208 | 209 | // Overwrite/create defaults 210 | if (isset($this->username)) { 211 | $username = $this->username; 212 | } 213 | 214 | if (isset($this->channel)) { 215 | $channel = $this->channel; 216 | } 217 | 218 | if (isset($this->icon_url)) { 219 | $icon_url = $this->icon_url; 220 | } 221 | 222 | if (isset($this->icon_emoji)) { 223 | $icon_emoji = $this->icon_emoji; 224 | } 225 | 226 | if (isset($this->unfurl_links)) { 227 | $unfurl_links = $this->unfurl_links; 228 | } 229 | 230 | $data = array( 231 | 'text' => $this->text, 232 | ); 233 | if (isset($username)) { 234 | $data['username'] = $username; 235 | } 236 | 237 | if (isset($channel)) { 238 | $data['channel'] = $channel; 239 | } 240 | 241 | if (isset($icon_url)) { 242 | $data['icon_url'] = $icon_url; 243 | } else { 244 | if (isset($icon_emoji)) { 245 | $data['icon_emoji'] = $icon_emoji; 246 | } 247 | 248 | } 249 | 250 | if (isset($unfurl_links)) { 251 | $data['unfurl_links'] = $unfurl_links; 252 | } 253 | 254 | if (isset($this->attachments)) { 255 | $attachments = array(); 256 | foreach ($this->attachments as $attachment) { 257 | $attachments[] = $attachment->toArray(); 258 | } 259 | $data['attachments'] = $attachments; 260 | } 261 | return $data; 262 | } 263 | 264 | /* 265 | * Send this message to Slack 266 | */ 267 | function send() { 268 | return $this->slack->send($this); 269 | } 270 | } 271 | 272 | class SlackAttachment { 273 | // Required 274 | public $fallback = ""; 275 | 276 | // Optionals 277 | public $color; 278 | public $pretext; 279 | public $author_name; 280 | public $author_icon; 281 | public $author_link; 282 | public $title; 283 | public $title_link; 284 | public $text; 285 | public $fields; 286 | public $mrkdwn_in; 287 | public $image_url; 288 | public $thumb_url; 289 | 290 | // Footer 291 | public $footer; 292 | public $footer_icon; 293 | public $ts; 294 | 295 | // Actions 296 | public $actions; 297 | 298 | function __construct($fallback) { 299 | $this->fallback = $fallback; 300 | } 301 | 302 | /** 303 | * Accepted values: "good", "warning", "danger" or any hex color code 304 | */ 305 | function setColor($color) { 306 | $this->color = $color; 307 | return $this; 308 | } 309 | 310 | function setText($text) { 311 | $this->text = $text; 312 | return $this; 313 | } 314 | 315 | /** 316 | * Optional text that appears above the attachment block 317 | */ 318 | function setPretext($pretext) { 319 | $this->pretext = $pretext; 320 | return $this; 321 | } 322 | 323 | /** 324 | * The author parameters will display a small section at the top of a message attachment. 325 | * @param string $author_name [description] 326 | * @param optional string $author_link A valid URL that will hyperlink the author_name text mentioned above. Set to NULL to ignore this value. 327 | * @param optional string $author_icon A valid URL that displays a small 16x16px image to the left of the author_name text. Set to NULL to ignore this value. 328 | */ 329 | function setAuthor($author_name, $author_link = NULL, $author_icon = NULL) { 330 | $this->setAuthorName($author_name); 331 | if (isset($author_link)) { 332 | $this->setAuthorLink($author_link); 333 | } 334 | 335 | if (isset($author_icon)) { 336 | $this->setAuthorIcon($author_icon); 337 | } 338 | 339 | return $this; 340 | } 341 | 342 | function setAuthorName($author_name) { 343 | $this->author_name = $author_name; 344 | return $this; 345 | } 346 | 347 | /** 348 | * Enable text formatting for: "pretext", "text" or "fields". 349 | * Setting "fields" will enable markup formatting for the value of each field. 350 | */ 351 | function enableMarkdownFor($mrkdwn_in) { 352 | if (!isset($this->mrkdwn_in_fields)) { 353 | $this->mrkdwn_in_fields = array($mrkdwn_in); 354 | return $this; 355 | } 356 | $this->mrkdwn_in_fields[] = $mrkdwn_in; 357 | return $this; 358 | } 359 | 360 | /** 361 | * A valid URL that displays a small 16x16px image to the left of the author_name text. 362 | */ 363 | function setAuthorIcon($author_icon) { 364 | $this->author_icon = $author_icon; 365 | return $this; 366 | } 367 | 368 | /** 369 | * A valid URL that will hyperlink the author_name text mentioned above. 370 | */ 371 | function setAuthorLink($author_link) { 372 | $this->author_link = $author_link; 373 | return $this; 374 | } 375 | 376 | /** 377 | * The title is displayed as larger, bold text near the top of a message attachment. 378 | * @param string $title 379 | * @param optional string $link By passing a valid URL in the link parameter (optional), the 380 | * title text will be hyperlinked. 381 | */ 382 | function setTitle($title, $link = NULL) { 383 | $this->title = $title; 384 | if (isset($link)) { 385 | $this->title_link = $link; 386 | } 387 | return $this; 388 | } 389 | 390 | /** 391 | * A valid URL to an image file that will be displayed inside a message attachment. We currently 392 | * support the following formats: GIF, JPEG, PNG, and BMP. 393 | * 394 | * Large images will be resized to a maximum width of 400px or a maximum height of 500px, while 395 | * still maintaining the original aspect ratio. 396 | * @param [type] $url [description] 397 | */ 398 | function setImage($url) { 399 | $this->image_url = $url; 400 | return $this; 401 | } 402 | 403 | /** 404 | * A valid URL to an image file that will be displayed as a thumbnail on the right side of a 405 | * message attachment. We currently support the following formats: GIF, JPEG, PNG, and BMP. 406 | * 407 | * The thumbnail's longest dimension will be scaled down to 75px while maintaining the aspect 408 | * ratio of the image. The filesize of the image must also be less than 500 KB. 409 | * 410 | * For best results, please use images that are already 75px by 75px. 411 | * @param string $url HTTP url of the thumbnail 412 | */ 413 | function setThumbnail($url) { 414 | $this->thumb_url = $url; 415 | return $this; 416 | } 417 | 418 | /** 419 | * Add some brief text to help contextualize and identify an attachment. Limited to 300 420 | * characters, and may be truncated further when displayed to users in environments with limited 421 | * screen real estate. 422 | * @param string $text max 300 characters 423 | */ 424 | function setFooterText($text) { 425 | $this->footer = $text; 426 | return $this; 427 | } 428 | 429 | /** 430 | * To render a small icon beside your footer text, provide a publicly accessible URL string in 431 | * the footer_icon field. You must also provide a footer for the field to be recognized. 432 | * 433 | * We'll render what you provide at 16px by 16px. It's best to use an image that is similarly 434 | * sized. 435 | * @param string $url 16x16 image url 436 | */ 437 | function setFooterIcon($url) { 438 | $this->footer_icon = $url; 439 | return $this; 440 | } 441 | 442 | /** 443 | * Does your attachment relate to something happening at a specific time? 444 | * 445 | * By providing the ts field with an integer value in "epoch time", the attachment will display 446 | * an additional timestamp value as part of the attachment's footer. Use ts when referencing 447 | * articles or happenings. Your message will have its own timestamp when published. 448 | * 449 | * Example: Providing 123456789 would result in a rendered timestamp of Nov 29th, 1973. 450 | * @param int $timestamp Integer value in "epoch time" 451 | */ 452 | function setTimestamp($timestamp) { 453 | $this->ts = $timestamp; 454 | return $this; 455 | } 456 | 457 | function addFieldInstance(SlackAttachmentField $field) { 458 | if (!isset($this->fields)) { 459 | $this->fields = array($field); 460 | return $this; 461 | } 462 | $this->fields[] = $field; 463 | return $this; 464 | } 465 | 466 | /** 467 | * Shortcut without defining SlackAttachmentField 468 | */ 469 | function addField($title, $value, $short = NULL) { 470 | return $this->addFieldInstance(new SlackAttachmentField($title, $value, $short)); 471 | } 472 | 473 | private function addAction($action) { 474 | if (!isset($this->actions)) { 475 | $this->actions = array($action); 476 | return $this; 477 | } 478 | $this->actions[] = $action; 479 | return $this; 480 | } 481 | 482 | /** 483 | * @param string $text A UTF-8 string label for this button. Be brief but descriptive and 484 | * actionable. 485 | * @param string $url The fully qualified http or https URL to deliver users to. Invalid URLs 486 | * will result in a message posted with the button omitted 487 | * @param string $style (optional) Setting to primary turns the button green and indicates the 488 | * best forward action to take. Providing danger turns the button red and indicates it some kind 489 | * of destructive action. Use sparingly. Be default, buttons will use the UI's default text 490 | * color. 491 | */ 492 | function addButton($text, $url, $style = null) { 493 | $action = (object) [ 494 | "type" => "button", 495 | "text" => $text, 496 | "url" => $url, 497 | ]; 498 | if (isset($style)) { 499 | $action->style = $style; 500 | } 501 | $this->addAction($action); 502 | return $this; 503 | } 504 | 505 | function toArray() { 506 | $data = array( 507 | 'fallback' => $this->fallback, 508 | ); 509 | if (isset($this->color)) { 510 | $data['color'] = $this->color; 511 | } 512 | 513 | if (isset($this->pretext)) { 514 | $data['pretext'] = $this->pretext; 515 | } 516 | 517 | if (isset($this->author_name)) { 518 | $data['author_name'] = $this->author_name; 519 | } 520 | 521 | if (isset($this->mrkdwn_in_fields)) { 522 | $data['mrkdwn_in'] = $this->mrkdwn_in_fields; 523 | } 524 | 525 | if (isset($this->author_link)) { 526 | $data['author_link'] = $this->author_link; 527 | } 528 | 529 | if (isset($this->author_icon)) { 530 | $data['author_icon'] = $this->author_icon; 531 | } 532 | 533 | if (isset($this->title)) { 534 | $data['title'] = $this->title; 535 | } 536 | 537 | if (isset($this->title_link)) { 538 | $data['title_link'] = $this->title_link; 539 | } 540 | 541 | if (isset($this->text)) { 542 | $data['text'] = $this->text; 543 | } 544 | 545 | if (isset($this->fields)) { 546 | $fields = array(); 547 | foreach ($this->fields as $field) { 548 | $fields[] = $field->toArray(); 549 | } 550 | $data['fields'] = $fields; 551 | } 552 | 553 | if (isset($this->image_url)) { 554 | $data['image_url'] = $this->image_url; 555 | } 556 | 557 | if (isset($this->thumb_url)) { 558 | $data['thumb_url'] = $this->thumb_url; 559 | } 560 | 561 | if (isset($this->footer)) { 562 | $data['footer'] = $this->footer; 563 | } 564 | 565 | if (isset($this->footer_icon)) { 566 | $data['footer_icon'] = $this->footer_icon; 567 | } 568 | 569 | if (isset($this->ts)) { 570 | $data['ts'] = $this->ts; 571 | } 572 | 573 | if (isset($this->actions)) { 574 | $data['actions'] = (array) $this->actions; 575 | } 576 | 577 | return $data; 578 | } 579 | } 580 | 581 | class SlackAttachmentField { 582 | // Required 583 | public $title = ""; 584 | public $value = ""; 585 | 586 | // Optional 587 | public $short; 588 | 589 | function __construct($title, $value, $short = NULL) { 590 | $this->title = $title; 591 | $this->value = $value; 592 | if (isset($short)) { 593 | $this->short = $short; 594 | } 595 | } 596 | 597 | function setShort($bool = true) { 598 | $this->short = $bool; 599 | return $this; 600 | } 601 | 602 | function toArray() { 603 | $data = array( 604 | 'title' => $this->title, 605 | 'value' => $this->value, 606 | ); 607 | if (isset($this->short)) { 608 | $data['short'] = $this->short; 609 | } 610 | return $data; 611 | } 612 | } 613 | ?> 614 | -------------------------------------------------------------------------------- /tests.php: -------------------------------------------------------------------------------- 1 | getMessage(); 14 | die("FAILED\n"); 15 | } 16 | 17 | // Insert example script here to generate a preview URL 18 | $slack = new Slack('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX'); 19 | 20 | // Create a new message 21 | $message = new SlackMessage($slack); 22 | 23 | echo 'https://api.slack.com/docs/messages/builder?msg=' . rawurlencode(json_encode($message->toArray(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); 24 | echo PHP_EOL; --------------------------------------------------------------------------------