Slack Pusher:将 Slack 消息推送到 WordPress





5.00/5 (12投票s)
接收来自 slack 的消息并创建 WordPress帖子的示例 WordPress 插件。
引言
本文通过一个 WordPress 插件驱动 Slack API,该插件接收来自 Slack 的消息并将其发布为文章。这是一个非常有趣的演示,展示了如何轻松实现与 Slack 交互的实际应用程序。此外,我们还将学习如何在本地 Dockerized WordPress 环境中进行开发,并将其暴露在互联网上。
剧透:看它如何工作
不想等到最后?好的,让我们来看看它的实际效果!代码可以在这里找到。
这个插件非常简单。你可以在 Slack 中创建一个应用,然后你可以与它进行对话。
你发送给它的所有消息都将被发布为 WordPress 文章,并将 Slack 格式语法转换为 HTML。
所有这些,都使用 ngrok
和 docker
完成,可以在你的 PC 上运行并与 Slack 交互。
Slack API 概览
当我开始研究 Slack API 以进入上下文时,我对它所做的工作质量印象深刻。引人注目之处在于它涵盖了所有可能的开发用例。你想到的任何事情都可以实现。这还不够?嗯,API 是为开发人员设计的。我测试了许多其他 API 系统——我当然指的是大公司——在这种情况下,我发现创建应用并部署给用户非常容易,我感到惊讶。为一个自己的空间创建一个应用,然后将其推广为公开应用,隐藏敏感信息如 clientid
和 client secret,使其在安装时可配置,这非常有意思,我对自己说,“我一切俱备,可以开始了。”
多种选项,涵盖所有情况
如前所述,所有开发场景都通过不同的功能来覆盖。为了让你对我们能做什么有一个概念
- 向界面添加按钮,在对话框中显示自定义表单(Web、桌面、移动端)
- 当使用事件发生时(类似于其他称之为“
webhook
”的东西)得到通知 - 代表用户操作数据(CRUD)(常规 API,在发起 HTTP 请求时,事情就会发生)
太棒了!那么让我们探索所有可能性
-
Web API:这是我们想象中的 API。将其视为经典的一组 REST 操作,可以调用以获取/设置信息。
-
WebHook:Incoming Webhooks 是一种简单的方式,可以让应用程序将消息发布到 Slack。这由 REST 调用进行管理。创建 Incoming Webhook 会给你一个唯一的 URL,你可以调用它来执行诸如发布消息之类的操作。
-
Commands:让用户直接从 Slack 中的消息框触发与你的应用的交互。当调用斜杠命令时,Slack 会向你在命令配置中输入的请求 URL 发送一个 HTTP POST 请求。该请求包含一个标准的负载,其中包含用户数据和上下文信息。
-
UI:可以创建一个扩展来定制 UI。在示例中,当用户点击一个按钮时,你可以打开一个对话框。在对话框中,你可以收集信息或显示信息。
-
Event API:这与 WebHook 类似,但方向相反。当你的 Slack 中发生事件时,你的 URL 会被触发,你可以管理数据。这就是本项目使用的,并在后面进行解释。
如何结合 Slack 扩展功能以赢得比赛
在我们的简单应用中,我们需要非常基本的东西:只需将消息发送到我们的 WordPress 实例。因此,API 应用将托管在 WordPress 本身中,这是一个非常简单实用的解决方案。如果你们好奇,我们稍后会讨论 WordPress 应用,我只想透露它不过是一个插件。当然,出于隐私和安全方面的考虑,API 不能读取所有用户的消息。只能代表用户操作或管理配置设置,绝不能侵犯他人的隐私。所以一个好的解决方案是使用 BOT。当你在一个对话中添加一个 bot 时,bot 可以听到你所说的话是明确的。
这对每个人来说都是透明的。所以我的解决方案是实现一个简单的 bot,它
- 会被用户添加到某个对话或频道
- bot 会读取该频道的所有消息,它永远不会休眠(所有机器人都有此特点 😉)。
- bot 不过是一个 http 端点,所以只需运行代码并传入消息即可。
基本上,我们可以将这项工作分为两个阶段
- 有趣的 Slack 配置,一切都闪耀
- 使用 PHP 进行相同的标准 HTTP API 开发
我不太喜欢用 PHP。我想这是因为我之前总是使用结构良好的、真正的面向对象的语言,然后才开始玩它。我无意冒犯 PHP,这只是我个人的感受,而且也许现在加入该平台的人会因其巨大的改进而产生更好的影响。但是,感受就是感受,我不想在缺失有趣或令人兴奋的东西的地方进行实验……所以我决定通过决定使用本地 Docker 环境进行开发并将其暴露在互联网上,来给它增添一些趣味。这不算什么革命性的,但足以让我相信我会享受这项工作。
第一部分:Slack 配置
Slack 配置非常简单。我不想,也不是本文的目的,展示一个从零开始创建 Slack 的向导。如果你需要,可以查看这篇精彩的文章。既然我们已经有了应用,我们必须启用事件。这非常简单,只需导航到事件部分并将其打开。事件的设置页面非常非常简单。我们只需要设置两个部分:调用的 URL 和权限。对于这个应用,我们只需要通知消息的可能性,所以配置与以下内容非常相似
然后是有趣的部分,URL。这可以被认为是简单的,只需输入 URL 然后停止,但还有更多。这有趣的部分在于 Slack 和你之间的信任机制。这是因为你必须证明你的身份,而 Slack 在发送数据时必须证明它的身份。否则,我们可能会陷入糟糕的境地,Slack 可能会将数据发送给错误的(或恶意的)应用程序,或者某些黑客会将人工负载发送到你的应用程序并代表 Slack 进行操作。
为了避免这种情况,不用担心,Slack API 实现了一个非常简单且完整的信任机制。一个更简单的解决方案是将所有数据发送到一个端点,这使得通信更容易,尽管它可能会给被调用的端点带来一些小小的额外负担。如果你想保持事物的零散化(也许像每个信息类型一个端点),你可以拥有多个端点,配置会更复杂。
当你将 URL 输入文本框时,会向该端点发出一个挑战调用。挑战将发送令牌和一个随机的 string
,称为挑战。端点将返回挑战,以证明能够管理 Slack 调用。在我的实现中,端点只接受一次挑战,并将令牌存储在数据库中。正如我们将看到的,这允许插件检查请求并避免出现某人冒充 Slack 连接到自己的情况。
请求执行
请求与挑战不匹配
请求已正确验证
身份验证令牌与你在应用程序凭据中找到的相同
第二部分:WordPress 插件
还记得我们想尝试 Docker 暴露本地环境吗?好吧,我们就是这样开始的,然后真正的工作就是剩下的令人讨厌的部分。只需从 StackOverflow 复制粘贴一些代码来在 WordPress 中插入一个帖子,仅此而已……或者更好的是,在我开始之前我是这么想的。
公开你的本地端口
第一件有趣的事情是公开本地端口到互联网。我确信使用一些反向代理工具是可以做到的,但我以前从未尝试过。在快速搜索互联网后,我找到了一个很棒的服务,名为 ngrock
,它可以将本地端口公开到 Web。免费层有一些限制(例如,每次运行时 URL 都会改变),但基本上可以使用 http 和 https 而无摩擦地使用。
Ngrock 支持保存一些配置文件以避免每次都记住设置,只需运行类似“ngrock start projectname
”的命令。问题是,我可能感兴趣的 99% 的设置都不在免费层中,所以我使用原始格式“ngrock http localport
”,其中 localport
自然绑定到从 Docker 暴露的端口号。
Docker 化 WordPress 环境
Docker 部分也非常简单。我已经将 WordPress 应用部署到 Docker 或 Kubernetes,所以我已经掌握了镜像本身。因为我喜欢可共享到团队的可写配置(是的,我当时是这个团队的唯一成员,但我受过训练要像团队一样思考,而不是个人),所以我设置了一个 Docker Compose 文件。它只有两个节点(mysql+wordpress
)。Mysql 数据文件夹映射到一个外部文件夹,这很好,可以避免在容器被删除时数据丢失,并且如果你想从头开始,只需删除文件夹并重新启动所有内容。对于 WordPress,我只映射了插件文件夹,而不是所有插件所属的“plugins”文件夹,而是特定的 slack-pusher 插件。(我之前是否已经说过我给这个项目起的名字?)这样,我们就拥有了一个简单的文件系统结构,其中
- Volumes 包含 mysql 的卷数据,这会被 git 忽略
- Docker-compose.yaml 容器和服务定义
- Slack-pusher 包含插件的文件夹
容易吗?相当容易。要运行所有内容,只需运行 docker-compose up,然后运行 ngrock http 8055
将你的开发 WordPress 暴露给互联网。
下一步?好吧,连接到 Slack,然后开始开发。
version: '3.3'
services:
db:
#db settings is omitted
wordpress:
depends_on:
- db
image: wordpress:latest
volumes:
- ./slack-pusher-plugin:/var/www/html/wp-content/plugins/slack-pusher-plugin:ro
ports:
- "8055:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress
WORDPRESS_CONFIG_EXTRA: "define('WP_HOME','https://'.$$_SERVER['HTTP_HOST']);
define('WP_SITEURL','https://'.$$_SERVER['HTTP_HOST']); error_reporting(E_ALL);
ini_set('display_errors', 1);"</span>
实现插件
这是非常简单的一部分。只需创建一个 bootstrap.php 文件,其中包含一些定义,然后某些内容就会在管理区域中移动。
实现设置表单
我是一个有远见的人,所以即使一开始不是必需的,到某个时候我们仍然需要一个设置表单来输入一些参数,比如 apikey
、clientid
、client secret,或者连接到 Slack 部分所需的任何其他内容。在我们的例子中,我们只需要事件,所以它非常简单。
我们需要配置来存储受信任的令牌,以及一个指示是否可以将应用程序与 Slack 链接的标志。该标志称为 wait_challenge
,初始值为 false。这迫使用户在准备好链接 Slack 和 WordPress 时显式启用它。在此阶段(希望只有几秒钟),WordPress 接受 Slack 挑战。当第一个挑战收到后,Slack 被链接,令牌被内部存储在 WordPress 中。设置表单的实现非常简单,因为参数很少,“原生” PHP 就足够了。
//... other module code
function spp_options_page()
{
?>
<div class="wrap">
<h1>Slack Pusher</h1>
<form method="post" action="options.php">
<?php settings_fields( 'spp-settings-group' ); ?>
<?php do_settings_sections( 'spp-settings-group' ); ?>
<table class="form-table">
<tr valign="top">
<th scope="row">Wating for challange</th>
<td><input type="checkbox" name="wait_challange" value="1"
<?php checked( '1', get_option( 'wait_challange' ) ); ?> /></td>
</tr>
<tr valign="top">
<th scope="row">Token</th>
<td><input type="text" name="token" value="<?php echo esc_attr
( get_option('token') ); ?>" disabled /></td>
</tr>
<!-- <tr valign="top">
<th scope="row">Challange</th>
<td><input type="text" name="challange" value="<?php echo esc_attr
( get_option('challange') ); ?>" disabled/></td>
</tr> -->
</table>
<?php submit_button(); ?>
</form>
</div>
<?php } //... other module code
好消息是,数据由默认的 WordPress 选项实现自动保存。
实现 BOT 端点
此端点以这种方式管理负载
- 这是一个挑战
- 如果启用了
wait_challenge
,则存储令牌,关闭wait_challenge
并回复挑战负载 - 否则,这是一个未经授权的尝试,返回未授权
- 如果启用了
- 这是一个常规的消息钩子
- 如果令牌有效,则处理消息
- 否则,返回未授权
代码非常简单。这部分代码添加了 REST 端点。
add_action( 'rest_api_init', function () {
register_rest_route( 'slack-pusher/v1', '/postmessage', array(
'methods' => 'POST',
'callback' => 'spp_post_message',
) );
} );
此函数实现算法
function spp_post_message( $data ) {
$enabled=get_option('wait_challange');
if(isset($data['challenge']))
{
if($enabled==TRUE)
{
//avoid unwanted registration
update_option('wait_challange',FALSE);
update_option('token',$data["token"]);
return sendChallangeResponse($data);
}
else
{
return sendUnauthorized();
}
}
else
{
if(get_option("token") != $data['token'])
{
return sendUnauthorized();
}
$newpost=im2post($data);
wp_insert_post($newpost);
}
return;
}
添加帖子到 WordPress
向 WordPress 添加帖子非常非常简单。WordPress API 接受一个数组,其中我们真正需要设置作者、标题和文本,仅此而已。标题根据约定假定为消息的第一行。其余部分假定为内容。Slack 允许使用特殊字符进行格式化,例如 *text*
用于粗体或 _text_
用于斜体。这通过将 Slack 语法转换为 HTML 来管理。第一个版本有一些限制(仅管理基本格式),但有一个相同的转换库可供使用,并且在未来可以轻松改进。
此片段将 Slack 消息转换为 HTML
function renderHtml($text)
{
$rendermap=array(
'/((?<!\\*)\\*(?!\\*))(.*)((?<!\\*)\*(?!\\*))/i'=> '<b>$2</b>',
'/((?<!_)_(?!_))(.*)((?<!_)_(?!_))/i'=>'<i>$2</i>',
'/((?<!\\~)\\~(?!\\~))(.*)((?<!\\~)\\~(?!\\~))/i'=> '<strike>$2</strike>',
);
foreach($rendermap as $wrapper=>$html_tag)
{
$text=preg_replace($wrapper,$html_tag,$text);
//error_log("w=>$wrapper t=>$html_tag result=> $text");
}
return $text;
}
最后,此另一个片段将帖子添加到 WordPress
$newpost=im2post($data);
wp_insert_post($newpost);
关注点
使用 Slack API 非常有趣,它向我展示了我们在集成该产品时所拥有的所有可能性。此外,我亲身体验到实现一套好的扩展功能如今可以推动产品走向成功。我试图总结这篇文章中最重要的主题。
Slack API
通过使用 Event API,我们能够将即时消息发送到外部应用程序并进行处理。这是通过信任端点与 Slack 来实现的,方式非常安全。配置部分非常简单,但由于端点是参数化的(我们的 WordPress URL 根据具体情况而变化),我们无法直接交付应用程序,而是需要要求最终用户手动设置。如果我们开发了一个付费的 Saas 解决方案,当我们接收所有调用并处理事物时,这也不是问题。
WordPress 模块
创建 WordPress 插件很容易。WordPress 是功能性的,被广泛使用,所以学习曲线非常短。我使用了“原生” WordPress,因为我们不需要比仅以简单方式实现它所拥有的更多功能。要将此演示转换为实际插件,一些重构可能会有所帮助,以分离逻辑部分(设置、API、引导程序)。即使在实际应用中,有一个充当中介到 CMS 末端的应用程序也可能很方便。这样做,我们可以有一个 Slack 应用(付费 Saas 产品?)将消息发布到我的目标,如 Facebook、Medium、LinkedIn、WordPress、Drupal……这也有助于减少用户首次安装时的摩擦,并集中业务逻辑。
未来工作
现有插件可以从多个方面进行扩展
- 将插件添加到 WordPress 市场
- 添加根据 Slack 用户选择正确用户的可能性
- 改进 Slack 格式以支持链接、图像、列表以及所有其他内容
- 添加命令或语法来配置多个选项(帖子所属的标签、状态等)
这个想法可以被重复用于
- 与其他 CMS 或 wiki 执行相同的操作
- 创建一个调度器应用程序,可以配置为发布到多个目的地
- 创建一个可以转售的 Saas 应用程序(也许是个梦想)
历史
- 2019-01-24:文章发布
- 2019-01-09:仓库和项目创建