如果您在过去一年左右的时间里一直在关注Office通讯工具的开发,那么我相信您已经听说了许多有关Slack的信息 。 从表面上看,Slack只是另一个为企业设计的聊天应用程序,但是由于它对细节的关注和可扩展性,许多评论家已经在说该工具将极大地改变我们未来的工作方式。
作为开发人员,我们处于良好的位置,可以顺应趋势,并思考可以将Slack用作应用程序基于聊天的用户界面的方式。
因此,在本教程中,您将学习如何通过将PHP应用程序发布到Slack通道并响应斜杠命令来开始将PHP应用程序集成到Slack。
您可以从链接的GitHub存储库下载本教程的源代码,也可以在学习本教程时自行创建它。
本教程的代码包括两部分:
- 与Slack通信的基本但完整的界面
- 一个简单的示例脚本,该脚本使用Slack类发送通知并响应斜杠命令
让我们开始吧。
1.创建您的应用程序并将其连接到Slack
Google快速搜索“ Slack PHP”一词会带来其他开发人员创建的几种不同的Slack接口,因此您也可以继续使用现有项目,并将其连接到您的应用程序。
但是API一点也不复杂,因此没有理由不自娱自乐并从头开始。 这样,您将知道API(以及您的集成)中的内容。 揭开神秘面纱总是很好。
本教程的核心是构建Slack接口,但是要使用和测试它,我们还需要一个应用程序。 为此,我决定使用不使用任何框架的简单PHP应用程序。
示例应用程序的工作方式如下:
- 首次运行该应用程序时,您会看到一个“添加到Slack”按钮,用于将应用程序连接到Slack频道。
- 单击该按钮将引导您完成Slack基于OAuth的身份验证。 当应用程序从Slack接收访问令牌时,它将保存到文本文件中,以便以后可以使用它与Slack进行通信。
- 基于OAuth的身份验证完成后,应用程序将显示一个简单的文本字段,可用于向您的Slack频道发送有趣的通知(“哦,是的,我是机器人!”)。
- 最后,在幕后,应用程序将响应您或您的队友在链接的Slack频道上键入的斜杠命令。
您可以在Web上启用PHP的服务器上运行该应用程序,或按照本教程中的说明在本地开发计算机上运行该应用程序。
该演示应用程序仅用于演示目的,因此最后,您可能会采用Slack界面并将其连接到现有的WordPress,Laravel或其他PHP项目。 在整个教程中,我将分享一些有关如何在实际应用程序中而不是我们的简单演示应用程序中使用接口类的想法。
步骤1:建立PHP应用程式
首先,让我们开始创建基本的项目架构并将所有文件放置到位。
如果您已从GitHub下载源代码,则可以快速浏览此步骤以确保您了解代码的组织方式,然后继续下一步。
在项目目录中,创建以下文件结构:
-
index.php
:上述示例应用程序的文件。 -
slack-interface
:一个目录,其中包含我们将在本教程中创建的Slack接口。 该目录将包含三个文件: -
slack-interface/class-slack.php
:Slack接口类。 -
slack-interface/class-slack-access.php
:一个用于保存Slack访问信息并将其通过接口传递给应用程序的类。 -
slack-interface/class-slack-api-exception.php
:一个异常类,用于将错误从接口传递给使用接口的代码。
-
然后,将文件放置在适当的位置,让我们为每个文件添加一些内容,以便我们拥有用于开发实际功能的框架。
首先将主要HTML表单和一些占位符代码添加到index.php
:
<?php
/**
* A lightweight example script for demonstrating how to
* work with the Slack API.
*/
// Include our Slack interface classes
require_once 'slack-interface/class-slack.php';
require_once 'slack-interface/class-slack-access.php';
require_once 'slack-interface/class-slack-api-exception.php';
use Slack_Interface\Slack;
use Slack_Interface\Slack_API_Exception;
//
// HELPER FUNCTIONS
//
/**
* Initializes the Slack object.
*
* @return Slack The Slack interface object
*/
function initialize_slack_interface() {
return null;
}
/**
* Executes an application action (e.g. 'send_notification').
*
* @param Slack $slack The Slack interface object
* @param string $action The id of the action to execute
*
* @return string A result message to show to the user
*/
function do_action( $slack, $action ) {
$result_message = '';
switch ( $action ) {
default:
break;
}
return $result_message;
}
//
// MAIN FUNCTIONALITY
//
// Setup the Slack interface
$slack = initialize_slack_interface();
// If an action was passed, execute it before rendering the page
$result_message = '';
if ( isset( $_REQUEST['action'] ) ) {
$action = $_REQUEST['action'];
$result_message = do_action( $slack, $action );
}
//
// PAGE LAYOUT
//
?>
<html>
<head>
<title>Slack Integration Example</title>
<style>
body {
font-family: Helvetica, sans-serif;
padding: 20px;
}
.notification {
padding: 20px;
background-color: #fafad2;
}
input {
padding: 10px;
font-size: 1.2em;
width: 100%;
}
</style>
</head>
<body>
<h1>Slack Integration Example</h1>
<?php if ( $result_message ) : ?>
<p class="notice">
<?php echo $result_message; ?>
</p>
<?php endif; ?>
<form action="" method="post">
<input type="hidden" name="action" value="send_notification"/>
<p>
<input type="text" name="text" placeholder="Type your notification here and press enter to send." />
</p>
</form>
</body>
</html>
让我们看一下脚本的内容以及此时的内容:
- 在第7-13行 ,我们首先包含库文件,然后通知PHP我们将使用
Slack_Interface
命名空间中的Slack
和Slack_API_Exception
类。 这些文件和该类尚不存在,但我们会尽快处理。 - 接下来,有两个用于辅助功能的占位符。 第一个帮助器函数
initialize_slack_interface
( 第19-26行 )将为当前会话设置Slack
类。 - 第二个辅助函数
do_action
( 第28-45行 )将用于处理除呈现页面外的其他动作,例如,将提交的消息发布到您的Slack通道,还接收来自Slack的传入斜线命令。 - 继帮助器功能之后,我们的小应用程序具有“主要”功能。 首先,应用程序初始化
Slack
对象( 第52行 )。 然后,在第 54-59 行上 ,它使用action
参数检查是否已请求执行action
。 如果是,则应用程序使用我们的do_action
helper函数执行该动作。 - 脚本的其余部分是基本HTML(以及一些CSS,我在同一文件中编写了CSS,以使事情保持简单),该HTML呈现了您在上图中看到的形式。
接下来,在构成我们的Slack接口的类文件中添加一些内容。
在class-slack.php
,添加以下代码:
<?php
namespace Slack_Interface;
/**
* A basic Slack interface you can use as a starting point
* for your own Slack projects.
*/
class Slack {
private static $api_root = 'https://slack.com/api/';
public function __construct() {
}
}
该类除占位符构造函数和Slack API的根URL定义外,不包含任何功能。 在第 2 行 ,您还将注意到该类位于命名空间Slack_Interface
。
同样,在class-slack-access.php
,添加以下代码:
<?php
namespace Slack_Interface;
/**
* A class for holding Slack authentication data.
*/
class Slack_Access {
public function __construct( $data ) {
}
}
最后,将以下内容添加到class-slack-api-exception.php
:
<?php
namespace Slack_Interface;
use Exception;
/**
* A simple exception class for throwing Slack API errors.
*/
class Slack_API_Exception extends Exception {
}
现在,我们为Slack应用程序创建了框架,并准备开始添加一些功能。
但是首先,我们需要使该应用程序在Web上可用,以便Slack可以与其进行对话。
步骤2:使服务器在Internet上可用
在可以使用Slack注册应用程序并使其接收来自Slack的来电之前,首先需要使它可以从Internet访问。
斜杠命令还要求应用程序使用HTTPS。 如果您不关心命令,而只是希望您的应用程序能够发送通知,则可以跳过此部分。 但是,对于本教程而言,由于传入的斜杠命令是我们要执行的工作的重要组成部分,因此我们需要一种能够为我们提供HTTPS支持的解决方案。
如果您的Web服务器已经设置了HTTPS,那是很自然的方法。
在开发阶段,另一种选择是使用隧道服务,例如localtunnel 。 Localtunnel在网络上为您的服务器提供安全的URL,该URL可以指向在本地计算机上运行的Web服务器。 尽管不是实时应用程序的解决方案,但在测试功能时,它既简化了工作流程(无需将文件上传到服务器),又为您提供了HTTPS支持。
首先,请根据工具网站上的说明安装localtunnel。
然后,启动Web服务器,注意服务器侦听的端口。
最后,一旦服务器启动,请使用以下命令在终端中启动localtunnel。 将your_subdomain
替换为您的首选子域,并将your_port
为Web服务器的端口:
lt -s your_subdomain -p your_port
如果您请求的子域可用,则localtunnel将启动,并且您可以通过URL https://your_subdomain.localtunnel.me来访问服务器。

步骤3:注册新的Slack应用程序
一旦可以从互联网访问您的服务器,就该注册一个新的Slack应用程序了。
要创建Slack应用程序,请登录您的Slack帐户,然后访问“ 新应用程序”页面。 登录后,您还可以通过单击Slack API仪表板右上角的我的应用程序来找到此页面的链接。
“ 新应用程序”页面如下所示:
在此页面上,输入有关您的应用程序的信息,然后单击“ 创建应用程序”进行保存:
- 应用名称 :一个名称,用于在应用列表中以及在您发回Slack的所有消息中标识您的应用。 我去了“ 松弛教程 ”。
- 团队 :可以为其提供应用程序的团队。 准备好应用程序后,可以将其提交到应用程序目录。 届时,Slack团队将对其进行审核,如果一切顺利,则将您的应用程序提供给所有人。
- 简短描述 :当用户将您的应用程序连接到他们的Slack频道时将显示给用户的描述。 如果只是测试,则可以暂时将其保留为空。 链接到安装说明和应用程序支持信息字段也是如此。
- 图标 :当用户将您的应用程序连接到他们的Slack频道以及您的应用程序发布的每条消息中时,该图标都会显示给用户。
- 重定向URI :Slack将在用户完成身份验证流程后将其重定向到的URL。 我们将在下面的第5步和第6步中对此进行更详细的研究,但是现在,只需将字段设置为指向应用程序中的
index.php?action=oauth
,例如https://your_subdomain.localtunnel.me/ slack-integration / index.php?action = oauth 。
创建Slack应用程序定义后,您会在“ 我的应用程序”页面上看到它的列出。 在这里,您可以根据需要编辑应用程序的信息,并将其API凭据(列在OAuth Information一节中列出)复制到您的集成中:
步骤4:将API凭证存储在您的应用程序中
接下来,由于将API凭据存储到PHP应用程序中,因此花一些时间来思考如何尽可能安全地进行操作是一件好事。
通常,将此类敏感信息提交给版本控制不是一个好习惯。 相反,您可能要使用以下选项之一:
- 将凭据存储在数据库中可能是一个好主意,例如,在WordPress插件中,每个用户将拥有自己的API凭据集,并且您希望他们能够直接从Admin Dashboard设置其凭据。
- 另一个选择(比第一个更安全)是直接在服务器上的配置文件中将凭据定义为常量(同样,如果使用WordPress,则
wp-config.php
是很自然的选择)。 只要确保配置文件没有暴露给外界(或致力于版本控制)即可。 - 最后,您可以在服务器上将客户端ID和密码设置为环境变量。 这样,信息就不会存储在可能会意外泄漏到应用程序外部的文件中。
在我们的实现中,我们将结合使用后两种方法。 要使Slack接口了解API凭据,请在Slack
类中添加两个新函数:
/**
* Returns the Slack client ID.
*
* @return string The client ID or empty string if not configured
*/
public function get_client_id() {
// First, check if client ID is defined in a constant
if ( defined( 'SLACK_CLIENT_ID' ) ) {
return SLACK_CLIENT_ID;
}
// If no constant found, look for environment variable
if ( getenv( 'SLACK_CLIENT_ID' ) ) {
return getenv( 'SLACK_CLIENT_ID' );
}
// Not configured, return empty string
return '';
}
/**
* Returns the Slack client secret.
*
* @return string The client secret or empty string if not configured
*/
private function get_client_secret() {
// First, check if client secret is defined in a constant
if ( defined( 'SLACK_CLIENT_SECRET' ) ) {
return SLACK_CLIENT_SECRET;
}
// If no constant found, look for environment variable
if ( getenv( 'SLACK_CLIENT_SECRET' ) ) {
return getenv( 'SLACK_CLIENT_SECRET' );
}
// Not configured, return empty string
return '';
}
这两个函数几乎是彼此完全相同的副本,因此让我们get_client_id
一下第一个get_client_id
,以了解它们的作用:
- 首先,在第7-10行 ,该函数检查客户端ID是否已存储在名为
SLACK_CLIENT_ID
的常量中。 如果定义了此常数,则函数将返回其值。 - 如果尚未定义常量,则该函数将继续检查具有相同名称的环境变量( 第12-15行 )。
- 最后,如果未找到客户端ID,该函数将返回一个空字符串。
要使用这种方法,请将访问凭据添加到index.php
的开头,甚至更好的是,将一个单独的PHP文件添加到index.php
但不要提交版本控制:
// Define Slack application identifiers
// Even better is to put these in environment variables so you don't risk exposing
// them to the outer world (e.g. by committing to version control)
define( 'SLACK_CLIENT_ID', 'Paste your client ID here' );
define( 'SLACK_CLIENT_SECRET', 'Paste your client secret here' );
步骤5:创建用于存储授权信息的数据结构
现在我们已经存储了应用程序凭据,现在是时候进入下一个身份验证级别了:允许您的用户将应用程序添加到其Slack帐户中。
认证流程包括三个步骤:
- 如果用户尚未将应用程序添加到Slack ,则应用程序中将显示“ 添加到Slack ”按钮。
- 单击按钮后,要求用户授权应用程序发布通知并响应Slack通道上的命令。
- 当用户授权应用程序时,您的应用程序会收到一个临时代码,然后使用Slack API交换为一组永久身份验证信息。
我们将很快开始实施该流程,但是首先,一旦我们从Slack接收到身份验证信息,就需要一种用于存储和使用身份验证信息的方法。
为此,我们将使用本教程前面创建的Slack_Access
类。
在类的顶部,首先定义用于保存授权数据的变量:
// Slack OAuth data
private $access_token;
private $scope;
private $team_name;
private $team_id;
private $incoming_webhook;
然后,实现构造函数以从作为参数传入的数组中读取这些变量的值:
/**
* Sets up the Slack_Access object with authentication data.
*
* @param array $data The Slack OAuth authentication data. If the user
* hasn't been authenticated, pass an empty array.
*/
public function __construct( $data ) {
$this->access_token = isset( $data['access_token'] ) ? $data['access_token'] : '';
$this->scope = isset( $data['scope'] ) ? $data['scope'] : array();
$this->team_name = isset( $data['team_name'] ) ? $data['team_name'] : '';
$this->team_id = isset( $data['team_id'] ) ? $data['team_id'] : '';
$this->incoming_webhook = isset( $data['incoming_webhook'] ) ? $data['incoming_webhook'] : array();
}
构造函数将变量初始化为$data
数组中传递的值,如果属性数组中不存在该信息,则初始化为空值。
在构造函数之后,添加一个用于检查对象是否已使用有效数据初始化的函数:
/**
* Checks if the object has been initialized with access data.
*
* @return bool True if authentication data has been stored in the object. Otherwise false.
*/
public function is_configured() {
return $this->access_token != '';
}
然后,为了存储认证数据,添加以下功能:
/**
* Returns the authorization data as a JSON formatted string.
*
* @return string The data in JSON format
*/
public function to_json() {
$data = array(
'access_token' => $this->access_token,
'scope' => $this->scope,
'team_name' => $this->team_name,
'team_id' => $this->team_id,
'incoming_webhook' => $this->incoming_webhook
);
return json_encode( $data );
}
该函数返回包含授权数据的JSON格式的字符串。
在实际的应用程序中,您很可能希望将授权信息绑定到用户帐户,并将JSON数据与用户信息一起保存。 但是,在我们的示例应用程序中(再一次),我们将采用一种简单的方法:我们假设只有一个用户(您)曾经使用过该应用程序,因此我们只需要存储一组OAuth凭据。
但是首先,让我们转到Slack
类,使其使用我们刚刚添加到Slack_Access
的功能。
实现构造函数以设置当前Slack
实例的访问对象:
/**
* @var Slack_Access Slack authorization data
*/
private $access;
/**
* Sets up the Slack interface object.
*
* @param array $access_data An associative array containing OAuth
* authentication information. If the user
* is not yet authenticated, pass an empty array.
*/
public function __construct( $access_data ) {
if ( $access_data ) {
$this->access = new Slack_Access( $access_data );
}
}
在构造函数之后,添加一个用于检查Slack
对象中的授权数据是否已设置的函数:
/**
* Checks if the Slack interface was initialized with authorization data.
*
* @return bool True if authentication data is present. Otherwise false.
*/
public function is_authenticated() {
return isset( $this->access ) && $this->access->is_configured();
}
第6步:显示“添加到松弛”按钮
有了适当的数据结构,我们可以开始在主应用程序中使用授权检查,并显示“添加到松弛”按钮。
请注意,尽管Slack_Access
类本身几乎可以在大多数应用程序中使用,但index.php
使用的解决方案仅用于演示目的:由于我们没有用户管理或数据库,因此我们只需保存JSON-文本文件中来自to_json
格式化访问凭证。
此时,该文件尚不存在,这意味着该应用程序尚未添加到Slack帐户,并且应显示“添加到Slack”按钮而不是文本字段。
为了实现简单的存储系统,首先将index.php
的函数initialize_slack_interface
替换为以下内容:
/**
* Initializes the Slack handler object, loading the authentication
* information from a text file. If the text file is not present,
* the Slack handler is initialized in a non-authenticated state.
*
* @return Slack The Slack interface object
*/
function initialize_slack_interface() {
// Read the access data from a text file
if ( file_exists( 'access.txt' ) ) {
$access_string = file_get_contents( 'access.txt' );
} else {
$access_string = '{}';
}
// Decode the access data into a parameter array
$access_data = json_decode( $access_string, true );
$slack = new Slack( $access_data );
return $slack;
}
在第9-14行中 ,该函数从称为access.txt
的文本文件中以字符串形式读取授权数据(如果存在)。 如果文件不存在,则将JSON字符串初始化为空哈希。
然后,在第17行 ,将数据解析为一个数组以传递到Slack接口(在第19行 )。
现在,我们准备将所有内容放在一起,如果未找到授权数据,则使我们的小应用程序显示“添加到松弛”按钮。
在index.php
的末尾,用以下代码片段替换表单:
<?php if ( $slack->is_authenticated() ) : ?>
<form action="" method="post">
<input type="hidden" name="action" value="send_notification"/>
<p>
<input type="text" name="text" placeholder="Type your notification here and press enter to send." />
</p>
</form>
<?php else : ?>
<p>
<a href="https://slack.com/oauth/authorize?scope=incoming-webhook,commands&client_id=<?php echo $slack->get_client_id(); ?>"><img alt="Add to Slack" height="40" width="139" src="https://platform.slack-edge.com/img/add_to_slack.png" srcset="https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack@2x.png 2x"></a>
</p>
<?php endif; ?>
在第1行的代码段中,您会注意到该表单现在被is_authenticated
检查所包围,以便用户在授权应用程序之前看不到它。
然后,在else
分支的第8-12行中 ,该代码现在呈现“ Add to Slack”按钮。
让我们来看看里面有什么按钮的a
标签:
- 首先,该按钮将用户指向Slack的OAuth授权流程(
oauth/authorize
)。 - 使用
scope
参数,应用程序可以定义它需要用户允许的权限:在我们的例子中,我们需要传入的Webhooks(incoming-webhook
)来发布通知以及添加新的斜杠命令(commands
)的能力。 有关可用权限的完整列表, 请参阅API文档 。 - 最后,链接需要包含应用程序的公共密钥(
client_id
),我们已在本教程的前面将其存储到应用程序中。
其余的只是用于显示按钮图像的基本HTML。
现在,当您在Web浏览器中打开应用程序时,应该看到以下内容:
步骤7:完成OAuth验证
现在,“添加到松弛”按钮就位。 但是,当用户单击它时会发生什么?
首先,用户将看到Slack的应用程序身份验证页面,如下所示:
然后,如果对用户而言一切正常,则他或她将单击“ 授权”按钮,此时执行将返回到您的应用程序。
您会记得,在Slack中定义应用程序时,我们设置了一个回调URL( YOUR_URL/index.php?action=oauth
)。
为了处理此回调,我们将使用在本教程前面创建的动作系统。 在您的实际应用程序中,您必须以一种适合所使用平台的方式来实现回调URL。 例如,在WordPress中,您可以很好地使用重写引擎创建自定义的永久链接。
但是,尽管接收回调的方式因应用程序而异,但是处理从Slack接收的数据的方法仍然相同。
将仍然空的do_action
函数替换为以下内容:
/**
* Executes an application action (e.g. 'send_notification').
*
* @param Slack $slack The Slack interface object
* @param string $action The id of the action to execute
*
* @return string A result message to show to the user
*/
function do_action( $slack, $action ) {
$result_message = '';
switch ( $action ) {
// Handles the OAuth callback by exchanging the access code to
// a valid token and saving it in a file
case 'oauth':
$code = $_GET['code'];
// Exchange code to valid access token
try {
$access = $slack->do_oauth( $code );
if ( $access ) {
file_put_contents( 'access.txt', $access->to_json() );
$result_message = 'The application was successfully added to your Slack channel';
}
} catch ( Slack_API_Exception $e ) {
$result_message = $e->getMessage();
}
break;
default:
break;
}
return $result_message;
}
当用户从授权流程返回时,将在$action
设置为'oauth'
调用此函数。 与请求一起,应用程序接收一个一次性令牌,该令牌在第17行读取。
然后,在第21行上 ,为了完成授权,该函数在Slack
类do_oauth
调用一个函数。
您可能还记得,在初始化Slack接口时,我们尝试从文本文件access.txt
加载身份验证数据。 当找不到文件时,应用程序确定用户尚未对应用程序进行身份验证,并显示“添加到松弛”按钮。
现在,在OAuth身份验证成功完成之后,在第23行 ,该函数将数据保存到该文件。
但是在到达那里之前,要完成身份验证流程,我们仍然需要在Slack
类中实现do_oauth
函数。
该函数将调用Slack API来交换传递给OAuth回调函数的代码与身份验证数据,身份验证数据可以永久存储并用于与Slack进行通信,直到用户撤销授权为止。
为此,我们需要一种向Slack服务器发出HTTP请求的方法。 用PHP发出HTTP请求的方法有很多,这里介绍的并不是唯一的方法。 例如,如果您正在开发WordPress,则可能需要使用wp_remote_get
和wp_remote_post
。
但是,这一次,为了使所有内容独立于任何特定的应用程序开发框架,我决定使用一个具有优美简洁语法的免费库Requests 。
按照其网站上的说明安装磁带库。 在Tuts + GitHub存储库中的源代码中,您将找到现成的Composer配置,以将该库包含到我们的应用程序中。
安装请求(或选择HTTP库)后,将do_oauth
函数添加到Slack
类中:
/**
* Completes the OAuth authentication flow by exchanging the received
* authentication code to actual authentication data.
*
* @param string $code Authentication code sent to the OAuth callback function
*
* @return bool|Slack_Access An access object with the authentication data in place
* if the authentication flow was completed successfully.
* Otherwise false.
*
* @throws Slack_API_Exception
*/
public function do_oauth( $code ) {
// Set up the request headers
$headers = array( 'Accept' => 'application/json' );
// Add the application id and secret to authenticate the request
$options = array( 'auth' => array( $this->get_client_id(), $this->get_client_secret() ) );
// Add the one-time token to request parameters
$data = array( 'code' => $code );
$response = Requests::post( self::$api_root . 'oauth.access', $headers, $data, $options );
// Handle the JSON response
$json_response = json_decode( $response->body );
if ( ! $json_response->ok ) {
// There was an error in the request
throw new Slack_API_Exception( $json_response->error );
}
// The action was completed successfully, store and return access data
$this->access = new Slack_Access(
array(
'access_token' => $json_response->access_token,
'scope' => explode( ',', $json_response->scope ),
'team_name' => $json_response->team_name,
'team_id' => $json_response->team_id,
'incoming_webhook' => $json_response->incoming_webhook
)
);
return $this->access;
}
让我们逐行浏览功能:
在第14-18行上 ,该函数初始化HTTP请求的参数。 值得注意的是,客户端ID和密码是作为请求选项传递的,以使用HTTP的基本身份验证机制。
在第 21 行 ,您会注意到我们将在回调函数中收到的一次性令牌发送回Slack API以识别请求。
POST
请求在第23行发送。 然后,该函数通过解析响应并进行设置,如果一切顺利,则设置并返回授权数据( 第33-44行 ),或者如果请求出错,则引发异常( 第28-31行 )。
现在,“添加到松弛”流程已准备就绪。 尝试一下时,应该看到以下内容:
另外,如果查看项目目录,则应该找到一个名为access.txt
的文本文件,其中存储了身份验证数据。
现在,我们已经准备好了有趣的部分:将应用程序发布到您的Slack频道。
2.发送通知到备用频道
将通知发布到Slack频道是使团队保持对他们重要的事件的最新信息的有效方法。 网络商店可能会发送有关新购买商品的通知,错误跟踪软件可以自动通知开发人员,并且清单继续存在。
在我们的示例中,正如您之前在UI中看到的那样,我们将发送用户使用文本字段提交的所有通知。
但是发送任何其他类型的通知的功能是相同的,因此一旦准备就绪,您就可以使用相同的代码发送自己的更复杂的通知。
步骤1:创建用于发送通知的功能
在Slack
类中,添加以下函数:
/**
* Sends a notification to the Slack channel defined in the
* authorization (Add to Slack) flow.
*
* @param string $text The message to post to Slack
* @param array $attachments Optional list of attachments to send
* with the notification
*
* @throws Slack_API_Exception
*/
public function send_notification( $text, $attachments = array() ) {
if ( ! $this->is_authenticated() ) {
throw new Slack_API_Exception( 'Access token not specified' );
}
// Post to webhook stored in access object
$headers = array( 'Accept' => 'application/json' );
$url = $this->access->get_incoming_webhook();
$data = json_encode(
array(
'text' => $text,
'attachments' => $attachments,
'channel' => $this->access->get_incoming_webhook_channel(),
)
);
$response = Requests::post( $url, $headers, $data );
if ( $response->body != 'ok' ) {
throw new Slack_API_Exception( 'There was an error when posting to Slack' );
}
}
使用webhook将通知发布到Slack频道是完成的, webhook是Slack公开给应用程序以发布到频道的特定于授权的URL。
我们没有太注意它早些时候在“添加到懈怠”流动,但如果你在数据看Slack_Access
一遍,你会发现,松弛返回一个名为场incoming_webhook
。 此字段是一个数组,其中包含两个字段:我们应将通知发布到的URL,以及用户为应用程序的消息选择的通道。
要访问该数据,请将以下两个函数添加到Slack_Access
类中:
/**
* Returns the webhook URL for posting notifications.
*
* @return string The incoming webhook URL
*/
public function get_incoming_webhook() {
if ( is_array( $this->incoming_webhook ) && isset( $this->incoming_webhook['url'] ) ) {
return $this->incoming_webhook['url'];
}
return '';
}
/**
* Returns the channel to which the user has authorized the application
* to post notifications.
*
* @return string The selected Slack channel's ID
*/
public function get_incoming_webhook_channel() {
if ( is_array( $this->incoming_webhook ) && isset( $this->incoming_webhook['channel'] ) ) {
return $this->incoming_webhook['channel'];
}
return '';
}
现在,让我们回到上面的send_notification函数,看看如何使用这些函数发送通知。
在第 19 行 ,您会注意到HTTP请求被发送到存储在授权数据中的传入Webhook URL 。
然后,在第24行 ,将在通道中将通道以及文本和我们要发布的所有附件传递给请求参数。
步骤2:在示例应用程序中使用通知发送功能
现在,我们已经实现了发送通知的功能,让我们将该功能附加到我们的用户界面上并进行测试。
将以下新的case
分支添加到index.php
的do_action
函数:
// Sends a notification to a Slack channel
case 'send_notification':
$message = isset( $_REQUEST['text'] ) ? $_REQUEST['text'] : 'Hello!';
try {
$slack->send_notification( $message );
$result_message = 'Notification sent to Slack channel.';
} catch ( Slack_API_Exception $e ) {
$result_message = $e->getMessage();
}
break;
此代码段从请求参数( 第3行 )读取消息,并使用我们刚刚创建的send_notification
函数将其发布到Slack( 第6行 )。
由于表单已在本教程开始时创建,因此您现在可以将第一条消息发送到Slack频道。 在文本字段中输入内容 ,然后按Enter提交表单。
然后,查看您的Slack频道以查看消息:
步骤3:使用附件使您的通知更具信息性
在send_notification
函数中,您可能注意到了一个名为attachments
的参数。 我没有提到它,因为它与示例应用程序不太匹配。 但是,附件是一种将有关应用程序事件的更多有趣信息传递到Slack通道的有效方法,您可能希望在应用程序中使用它们。
因此,让我们通过修改步骤2中的send_notification
调用来对附件进行一些实验。 将$slack->send_notification()
调用替换为以下代码:
$attachments = array(
array(
'fallback' => 'Jarkko just posted a new bread recipe.',
'title' => 'Sprouted Wheat Bread',
'title_link' => 'https://bread-magazine.com/sprouted-wheat-flour/',
'text' => 'Jarkko just posted a new bread recipe. Check it out.',
'color' => '#7CD197',
'fields' => array(
array(
'title' => 'Preparation time',
'value' => ':hourglass: 24 hours',
'short' => true
),
array(
'title' => 'Difficulty',
'value' => 'Medium',
'short' => true
),
),
'image_url' => 'https://s3.amazonaws.com/interested/wordpress/wp-content/uploads/2015/02/12093547/sprouted-bread.jpg'
)
);
$slack->send_notification( $message, $attachments );
上面的代码中指定的附件是有关在配方数据库中添加新面包配方的假想通知。 它只是一个示例,因此继续进行修改,以查看对它所做的更改如何影响Slack通道上的输出。
-
fallback
: 必需的纯文本消息,如果无法显示附件,则显示该消息。 -
title
:附件的标题,使用更大的字体设置样式。 -
title_link
:用户单击链接时将打开的URL。 在我们的示例中,这将显示配方。 -
text
:将显示在附件内的文本。 -
color
:附件左侧线条的颜色。 -
fields
:要显示在附件中的数据字段的列表。 在示例中,它们用于显示有关配方的一些信息。 -
image_url
:要显示在附件中的图像的URL。
这是您发布带有上面指定的附件的通知时会看到的内容:
玩弄参数,看看更改它们如何影响发布在Slack频道上的消息:修改属性,发送新的通知,并查看更改的内容。
有关附件的更多信息,请参阅Slack文档 。
3.使您的应用程序响应斜杠命令
您的应用程序现在可以与Slack通信了。 接下来,我们将以另一种方式使通信工作:通过添加斜杠命令,我们可以使Slack成为应用程序的接口。
在实际的应用程序中,这有很多用例。 将错误标记为已修复,将订单标记为已发货或开个玩笑只是一些想到的事情。
让我们继续执行笑话请求,以便在有人在Slack频道上键入/joke
时发布笑话。
步骤1:定义斜杠命令
首先,访问您的Slack Application的设置页面以定义新的斜杠命令。
向下滚动到标题为Slash Commands的部分 ,然后单击Create new command 。
在下一个屏幕中,输入用于指定新命令的必需信息,然后单击保存 。
以下是此页面上字段的简要说明:
- Command :斜杠命令,包括斜杠字符。 例如,
/joke
。 - 请求URL :当有人在Slack通道上键入此斜杠命令时,应在服务器上调用的URL。 这是localtunnel派上用场的地方:URL必须是HTTPS,并且可以从Internet连接。 使用以下URL格式使请求URL与我们将在下面的步骤2中构建的功能兼容:
YOUR_SERVER/index.php?action=command
。 - 简短描述 :当有人键入命令时,在自动完成弹出窗口中显示的描述。
- 用法提示 :如果命令使用参数,则可以在此处进行描述。 此文本在自动完成对话框中也可见。
保存命令后,您会在“ 斜线命令”部分中找到新命令。 您可以使用按钮进行编辑或删除。

在命令列表下方,您将找到一个标签为Verification Token的字符串。
您可以在执行命令之前使用此令牌来验证命令确实来自Slack。 以与本教程前面的客户端ID和密钥相同的方式将令牌存储在应用程序中,例如,通过在index.php
的开头添加一个常量:
define( 'SLACK_COMMAND_TOKEN', 'Paste your command verification token here' );
步骤2:创建一个系统来跟踪应用程序中的斜杠命令
现在,当有人在Slack聊天窗口中键入命令时,Slack将识别该命令(您可以立即尝试查看自动完成弹出窗口)。
当用户提交命令时,Slack将通过上一步中指定的请求URL调用我们的服务器。 现在,我们需要实现功能,以使我们的应用程序正确响应。
由于您可以在Slack应用程序中添加多个斜杠命令,因此最好支持可变数量的斜杠命令。 这就是为什么我们将从创建一个用于跟踪应用程序中斜杠命令的系统开始。
首先,在Slack
类中,添加以下变量来保存命令:
/**
* @var array $slash_commands An associative array of slash commands
* attached to this Slack interface
*/
private $slash_commands;
在类的构造函数中,添加一行以初始化数组:
$this->slash_commands = array();
然后,创建一个用于向阵列添加新的斜杠命令的函数:
/**
* Registers a new slash command to be available through this
* Slack interface.
*
* @param string $command The slash command
* @param callback $callback The function to call to execute the command
*/
public function register_slash_command( $command, $callback ) {
$this->slash_commands[$command] = $callback;
}
现在您有了斜杠命令列表,添加一个用于执行命令的函数:
/**
* Runs a slash command passed in the $_POST data if the
* command is valid and has been registered using register_slash_command.
*
* The response written by the function will be read by Slack.
*/
public function do_slash_command() {
// Collect request parameters
$token = isset( $_POST['token'] ) ? $_POST['token'] : '';
$command = isset( $_POST['command'] ) ? $_POST['command'] : '';
$text = isset( $_POST['text'] ) ? $_POST['text'] : '';
$user_name = isset( $_POST['user_name'] ) ? $_POST['user_name'] : '';
// Use the command verification token to verify the request
if ( ! empty( $token ) && $this->get_command_token() == $_POST['token'] ) {
header( 'Content-Type: application/json' );
if ( isset( $this->slash_commands[$command] ) ) {
// This slash command exists, call the callback function to handle the command
$response = call_user_func( $this->slash_commands[$command], $text, $user_name );
echo json_encode( $response );
} else {
// Unknown slash command
echo json_encode( array(
'text' => "Sorry, I don't know how to respond to the command."
) );
}
} else {
echo json_encode( array(
'text' => 'Oops... Something went wrong.'
) );
}
// Don't print anything after the response
exit;
}
让我们浏览一下该函数以了解它的作用:
首先,在第8-12行上 ,该函数从请求参数中收集数据:
-
token
用于验证请求是否为有效的Slack命令请求。 -
command
包含应执行的斜杠命令。 -
text
是在命令后键入的文本字符串。 它可以用来将参数传递给您的斜杠命令。 -
user_name
是发送斜杠命令的用户的用户名。
在第15行 ,该函数通过将在请求参数中传递的令牌与我们在上一步中存储的令牌进行比较来进行验证。
如果令牌有效,则在Slack
类中注册了具有给定命令名称的命令后,该函数将继续执行该命令。 命令的执行在第20行完成,该函数调用为该命令指定的回调函数。
然后,在第21行 ,将响应编码为JSON字符串并打印出来。 请注意,该函数以exit
调用结束,以确保在响应后不再打印任何内容。
要完成此功能,请添加功能get_command_token
以检索应用程序的命令验证令牌:
/**
* Returns the command verification token.
*
* @return string The command verification token or empty string if not configured
*/
private function get_command_token() {
// First, check if command token is defined in a constant
if ( defined( 'SLACK_COMMAND_TOKEN' ) ) {
return SLACK_COMMAND_TOKEN;
}
// If no constant found, look for environment variable
if ( getenv( 'SLACK_COMMAND_TOKEN' ) ) {
return getenv( 'SLACK_COMMAND_TOKEN' );
}
// Not configured, return empty string
return '';
}
Slack类中的斜杠命令功能现已完成,在实现第一个命令之前要做的就是将回调URL连接到此代码。
为此,在index.php
的do_action
函数中添加一个新的case
分支:
// Responds to a Slack slash command. Notice that commands are
// registered at Slack initialization.
case 'command':
$slack->do_slash_command();
break;
步骤3:注册并测试斜杠命令
现在,我们已经创建了一个用于处理应用程序中斜杠命令的系统,让我们使用它来实现/joke
命令的功能。
首先,在函数initialize_slack_interface
的末尾,添加以下代码行以注册命令并传入将处理该命令的函数的名称:
// Register slash commands
$slack->register_slash_command( '/joke', 'slack_command_joke' );
然后,创建函数:
/**
* A simple slash command that returns a random joke to the Slack channel.
*
* @return array A data array to return to Slack
*/
function slack_command_joke() {
$jokes = array(
"The box said 'Requires Windows Vista or better.' So I installed LINUX.",
"Bugs come in through open Windows.",
"Unix is user friendly. It’s just selective about who its friends are.",
"Computers are like air conditioners: they stop working when you open Windows.",
"I would love to change the world, but they won’t give me the source code.",
"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning."
);
$joke_number = rand( 0, count( $jokes ) - 1 );
return array(
'response_type' => 'in_channel',
'text' => $jokes[$joke_number],
);
}
由于此函数是作为演示创建的,因此它并不会做很多事情:它会随机选择一个(相当糟糕的)笑话之一,并以Slack期望的格式返回它。
请注意,尽管此命令功能不带任何参数,但对于一个更复杂的示例,您可以添加两个参数: $text
以访问用户在命令后键入的任何数据,以及$user_name
以获取用户的名称。提交了命令。
要测试该命令,请继续并在Slack通道上键入/joke
。
结论和对未来的想法
您现在已经完成了本教程,并且知道如何将PHP应用程序与Slack集成。 在本教程中,您还构建了用于将通知发送到Slack频道以及响应用户直接在Slack中键入命令的工具。
下一步就是将这些想法付诸实践。
考虑一下您的应用程序,并寻找与Slack交谈和收听来自Slack的命令的地方,这些地方可以使用户感到更有用和更愉快,并实现它们。
该平台正在Swift发展,API也正在Swift发展。 密切关注进展情况,并打造出惊人的东西!