diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9256b31 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +temp/* +vendor/* diff --git a/README.md b/README.md new file mode 100644 index 0000000..9354a6e --- /dev/null +++ b/README.md @@ -0,0 +1,40 @@ +# Slack messaging tools + +![GitHub release](https://img.shields.io/github/release/FrancoisChaumont/slack-api-tools.svg) +[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/FrancoisChaumont/slack-api-tools/issues) + +Set of messaging tools using Slack API. + +## Requirements + +- [Composer](https://getcomposer.org) +- PHP 7.4+ + +## Installation + +``` +composer install +``` + +## Tools + +### Post a message to a channel +See [post-message.php](post-message.php) +``` +post-messsage.php -h/--help +``` +See [README.post-message.md](READMEs/README.post-message.md) for more details. + +## Built with +* Visual Studio Code + +## Authors +* **Francois Chaumont** - *Initial work* - [FrancoisChaumont](https://github.com/FrancoisChaumont) + +See also the list of [contributors](https://github.com/FrancoisChaumont/db/graphs/contributors) who participated in this project. + +## License +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. + +## Notes +Todo: Add more tools diff --git a/READMEs/README.post-message.md b/READMEs/README.post-message.md new file mode 100644 index 0000000..b282e9e --- /dev/null +++ b/READMEs/README.post-message.md @@ -0,0 +1,16 @@ +# Post a message to a Slack channel + +## Introduction + +**Create a Slack app** +See [create app](https://api.slack.com/start/overview#creating) documentation. + +Grant permission: `chat:write` + +**Sending a message** +See [sending message](https://api.slack.com/messaging/sending) documentation. + +**Find channel ID** +- In the Slack desktop app, right-click on the channel and select copy link. The last part of the URL is the ID. +- In the browser version, navigate to the channel and check the URL. The last part of the URL is the ID. + diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..9ee0f51 --- /dev/null +++ b/composer.json @@ -0,0 +1,19 @@ +{ + "name": "francoischaumont/slack", + "description": "Message functionalities through Slack API and apps", + "authors": [ + { + "name": "Francois Chaumont", + "role": "main developer" + } + ], + "require": { + "php": "^7.4", + "guzzlehttp/guzzle": "^7.2" + }, + "autoload": { + "psr-4": { + "FC\\Slack\\": "src/Slack/" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..9d81a31 --- /dev/null +++ b/composer.lock @@ -0,0 +1,402 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "5a69468575cbb252f132282187f4f1cb", + "packages": [ + { + "name": "guzzlehttp/guzzle", + "version": "7.2.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/0aa74dfb41ae110835923ef10a9d803a22d50e79", + "reference": "0aa74dfb41ae110835923ef10a9d803a22d50e79", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.4", + "guzzlehttp/psr7": "^1.7", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "psr/log": "^1.1" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.2.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + } + ], + "time": "2020-10-10T11:47:56+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "60d379c243457e073cff02bc323a2a86cb355631" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", + "reference": "60d379c243457e073cff02bc323a2a86cb355631", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.4.0" + }, + "time": "2020-09-30T07:37:28+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.7.0" + }, + "time": "2020-09-30T07:37:11+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.4" + }, + "platform-dev": [], + "plugin-api-version": "2.0.0" +} diff --git a/post-message.php b/post-message.php new file mode 100644 index 0000000..f86a9b4 --- /dev/null +++ b/post-message.php @@ -0,0 +1,37 @@ +!"); } + else { $appToken = $options[OPTION_TOKEN]; } + if (!isset($options[OPTION_CHANNEL])) { throw new \Exception("Missing option !"); } + else { $channel = $options[OPTION_CHANNEL]; } + if (!isset($options[OPTION_MESSAGE])) { throw new \Exception("Missing option !"); } + else { $message = $options[OPTION_MESSAGE]; } + + // init Guzzle client + $client = new \GuzzleHttp\Client(); + + // init Slack App + $slackApp = new \FC\Slack\SlackApp($appToken); + + // post message + $r = $slackApp->postMessage($client, $channel, $message); + if ($r === true) { + exit(0); + } else { + throw new \Exception("Failed to post message: $r"); + } + +} catch (\Exception $e) { + echo $e->getMessage() . PHP_EOL; + exit(1); +} diff --git a/src/Slack/SlackApp.php b/src/Slack/SlackApp.php new file mode 100644 index 0000000..02f3b5d --- /dev/null +++ b/src/Slack/SlackApp.php @@ -0,0 +1,60 @@ +appToken = $appToken; + } + + /** + * Post a message to a channel + * + * @param \GuzzleHttp\Client $client Guzzle client to handle HTTP requests + * @param string $channelId ID of the channel to post the message to + * @param string $text Message to be posted + * @return bool|string true on success, HTTP response code + reason on failure + */ + public function postMessage(\GuzzleHttp\Client $client, string $channelId, string $text) + { + $message = <<< EOS + { + "channel": "$channelId", + "text": "$text" + } + EOS; + + $headers = [ + 'Authorization' => 'Bearer ' . $this->appToken, + 'Content-type' => 'application/json' + ]; + + $response = $client->request( + 'POST', + self::POST_MESSAGE_URL, [ + 'headers' => $headers, + 'json' => json_decode($message, true) + ] + ); + + $code = $response->getStatusCode(); // 200 + $reason = $response->getReasonPhrase(); // OK + + if ($code == 200) { return true; } + else { return $code . " - " . $reason; } + } +} + diff --git a/usage/post-message.usage.php b/usage/post-message.usage.php new file mode 100644 index 0000000..d4f708e --- /dev/null +++ b/usage/post-message.usage.php @@ -0,0 +1,53 @@ +