Skip to content

Instantly share code, notes, and snippets.

@nadar
Last active June 5, 2024 17:05
Show Gist options
  • Save nadar/68a347d2d1de586e4393 to your computer and use it in GitHub Desktop.
Save nadar/68a347d2d1de586e4393 to your computer and use it in GitHub Desktop.
Post a message to a slack channel with PHP
<?php
/**
* Send a Message to a Slack Channel.
*
* In order to get the API Token visit:
*
* 1.) Create an APP -> https://api.slack.com/apps/
* 2.) See menu entry "Install App"
* 3.) Use the "Bot User OAuth Token"
*
* The token will look something like this `xoxb-2100000415-0000000000-0000000000-ab1ab1`.
*
* @param string $message The message to post into a channel.
* @param string $channel The name of the channel prefixed with #, example #foobar
* @return boolean
*/
function slack($message, $channel)
{
$ch = curl_init("https://slack.com/api/chat.postMessage");
$data = http_build_query([
"token" => "YOUR_API_TOKEN",
"channel" => $channel, //"#mychannel",
"text" => $message, //"Hello, Foo-Bar channel message.",
"username" => "MySlackBot",
]);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
// Example message will post "Hello world" into the random channel
slack('Hello world', '#random');
@jlwin
Copy link

jlwin commented Jun 29, 2015

Hey thanks for posting the code here, which helped me a lot to post relevant data to one of my channels. Just a minor note: the closing tag of the overall php ("?>") is missing at the end ;-)

@dasDaniel
Copy link

Omitting the php closing tag is actually part of best practices
http://www.php-fig.org/psr/psr-2/#2-2-files

@jtuei
Copy link

jtuei commented Nov 25, 2015

Hi dasDaniel. I'm not sure I understand why omitting the closting tag is best practices? Care to educate me a bit? Thanks!

Copy link

ghost commented Dec 4, 2015

Omitting the PHP closing tag is optional and there are not many practical differences including or omitting it. However if your PHP script contains HTML after it you will need a closing tag, if it's pure PHP as the example above is there is no need to include one. Although a lot of developers will fiercely argue for or against closing tags, the reality is it's down to personal preference as there are no major functional or performance reasons on either side. My personal preference is to keep my code as slim as possible so I tend not to use them on PHP only files. There is a good article here which explores this discussion point: http://www.sitepoint.com/closing-php-tags-debate/

@databyss
Copy link

databyss commented Dec 9, 2015

You have double opening braces for the function.

https://gist.github.com/nadar/68a347d2d1de586e4393#file-postmessagetoslackchannel-php-L11

This is great though, thanks!

@nadar
Copy link
Author

nadar commented Dec 17, 2015

Thanks @databyss!

@curry684
Copy link

curry684 commented Aug 1, 2016

@mattstone-ascot @jlwin it's most certainly not a matter of preference. The PHP Framework Interoperability Group (PHP-FIG), participated in by the maintainers of such insignificant PHP projects as Symfony, Laravel, Yii, Zend, Composer, Drupal, Joomla, Magento, phpBB and CakePHP, has set some universally accepted standards, amongst which the coding standards PSR-1 and PSR-2.

Opening PSR-2 at section 2.2 we find:

The closing ?> tag MUST be omitted from files containing only PHP.

The only developers arguing fiercely in favor of closing tags are inexperienced non-professional PHP programmers who have never spent 2 hours finding out why their 500-file project suddenly started throwing "Headers already sent" errors due to a trailing newline.

It should be noted that PSR-1 and PSR-2 both became accepted standards and therefore mandatory in the professional PHP community on June 4th 2012, so the debate is kind of stone cold by now, but your SitePoint article is from 2010 so the author is forgiven.

@SneakyWhoami
Copy link

Yep "headers already sent".. if you're setting a header after including a file, and that included file has a closing PHP tag, occasionally things will go bad. Just save yourself a possible headache one day and don't type those two pointless extra keystrokes when you're already at the end of the file anyway.

I like that "personal preference" argument. Yup, 99.99% of the time it will never make the slightest difference, so not really worth losing sleep over either way if you're just out for a quick hack :-)

But yes, technically... adding it can break things, and omitting it can not.

@evanmcd
Copy link

evanmcd commented May 19, 2017

Note that the page for creating single use tokens has moved from https://api.slack.com/web to https://api.slack.com/custom-integrations/legacy-tokens

@nadar
Copy link
Author

nadar commented May 19, 2017

Thank you @evanmcd i changed the PHPDoc according to your message.

@AhsanMalikGit
Copy link

Thank you @nadar posting the code here, which helped me.

@macksvp
Copy link

macksvp commented Aug 2, 2017

Thanks You
How to get all Slack channel messages on my site ?

@boxingnguyen
Copy link

This great!. I can send message easier and more flexible than incoming webhooks way. Thank you so much @nadar

@enrico-atzeni
Copy link

Awesome, so easy and fast to include in my code! Thank you @nadar!

@carefine
Copy link

carefine commented May 1, 2018

@jtuei If a file is pure PHP code, it is preferable to omit the PHP closing tag at the end of the file. This prevents accidental whitespace or new lines being added after the PHP closing tag, which may cause unwanted effects because PHP will start output buffering when there is no intention from the programmer to send any output at that point in the script.

@nicgordon
Copy link

This didn't work for me until I set CURLOPT_SSL_VERIFYPEER to true. Just thought I'd leave this here in case it helps anyone else.

@nadar
Copy link
Author

nadar commented Jun 17, 2018

Thanks for the mention @nicgordon, if someone wants to read more about CURLOPT_SSL_VERIFYPEER => https://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html

Copy link

ghost commented Sep 30, 2018

Thank you. Really Interesting.

@jameshwartlopez
Copy link

Is there a way to make this function can handle new line?

@jameshwartlopez
Copy link

Fix it using PHP_EOL. Thanks for this simple and working function that does not include a lot of other codes.

@MantasVaitkunas
Copy link

I did get invalid_payload response. Issue was with $data, I had to pass it as json:

    function slack($message, $channel)
    {
        $url = getenv('SLACK_WEBHOOK_URL');
        $ch = curl_init($url);
        $data = [
            'channel' => $channel,
            'text' => $message,
            'username' => 'SlackBot',
        ];
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_THROW_ON_ERROR, 512));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

        $result = curl_exec($ch);
        curl_close($ch);

        return $result;
    }

@Zhigalin
Copy link

Legacy tokens creation disabled...

@eugenefvdm
Copy link

Yeah from:

https://api.slack.com/legacy/custom-integrations/legacy-tokens

Legacy token management
Tokens may no longer be created, but you can re-issue existing tokens here.

I needed a simple test so now have to look for another PHP example...

@nadar
Copy link
Author

nadar commented Nov 10, 2021

The code still works but you have to use Bot User OAuth Token which requires to:

1.) Create an APP -> https://api.slack.com/apps/
2.) See menu entry "Install App"
3.) Use the "Bot User OAuth Token"

@Niek
Copy link

Niek commented Apr 12, 2024

The file_get_contents() version:

function slack($message, $channel)
{
  $url = "https://slack.com/api/chat.postMessage";

  $data = http_build_query([
    "token" => getenv('SLACK_BOT_TOKEN'), // the "Bot User OAuth Token" value
    "channel" => $channel,
    "text" => $message,
    "username" => "NotificationBot",
  ]);

  $context = stream_context_create([
    'http' => [
      'method'  => 'POST',
      'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
      'content' => $data,
      'ignore_errors' => true // This is useful to get the content of the response even if the status code is not 200
    ]
  ]);

  $result = file_get_contents($url, false, $context);

  return $result;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment