slack-php/slack-block-kit

Slack Block Kit 消息和模态的 OOP 接口


README

PHP 的 Slack Block Kit

👉 通过 OOP 接口使用 Slack Block Kit 语法格式化消息和模态 👈

由 Jeremy Lindblom (@jeremeamia) 提供

Slack logo placed on top of blocks

Coded in PHP 8.1 Packagist Version Build Status

简介

来自 Slack 的 Block Kit 文档

Block Kit 是 Slack 应用程序的 UI 框架,在构建消息和其他 表面 的体验时提供了控制与灵活性的平衡。

通过组合、更新、排序和堆叠 (几乎在 Slack 的任何地方都可用),自定义信息和引导用户了解您应用程序的功能,以定制信息的顺序和外观。

此库为使用 Slack Block Kit 编写消息/模态提供了 PHP 的 OOP 接口。它还可以反向操作,这意味着您可以将消息/模态 JSON 填充到对象层次结构中。

Block Kit 概念

此库帮助您在代码中以编程和动态方式构建 Slack 消息和模态,但您首先需要了解它们的一般工作原理。库试图防止您在 Block Kit 中执行不被允许的操作,但可能不会针对每个单独的条件进行验证。

您可能需要查看 Slack 文档中的以下概念

  • 表面 - 有 3 种主要类型:消息、模态和应用首页
  • - 包括 部分上下文操作
  • 块元素 - 包括按钮、菜单、文本输入和其他交互式组件。我们在这个库中将所有这些称为“元素”。
  • 组合对象 - 我们在库中称之为“部分”

通常,我们将 Block Kit 中的所有这些不同事物统称为“组件”。

安装

通过 Composer 轻松安装

composer require slack-php/slack-block-kit

然后在项目初始化代码中包含 Composer 生成的自动加载器。

注意:此库是为 PHP 8.1+ 构建的。

此库的 1.0 版本支持版本 7.3/7.4。

基本用法

此库支持使用 PHP 8 的命名参数功能进行直观的语法来组合 Slack 表面(例如,消息、模态)。

<?php

use SlackPhp\BlockKit\Surfaces\Message;
use SlackPhp\BlockKit\Blocks\Section;
use SlackPhp\BlockKit\Blocks\Divider;
use SlackPhp\BlockKit\Blocks\BlockImage;

// ...

// CONSTRUCTION
$msg = new Message(
    ephemeral: true,
    blocks: [
        new Section('Don\'t you just love XKCD?'),
        new Divider(),
        new BlockImage(
            title: 'Team Chat',
            imageUrl: 'https://imgs.xkcd.com/comics/team_chat.png',
            altText: 'Comic about the stubbornness of some people switching chat clients',
        ),
    ]
);

// VALIDATION
// Throws a ValidationException if any of the components are invalid or missing required properties.
$msg->validate();

// OUTPUT
// To convert to JSON (e.g., to send to Slack API, webhook, or response_url), use PHP's `json_encode()` function.
echo json_encode($msg);
// OR you can use the surfaces's `toJson()` method, which also includes a convenience parameter for pretty printing.
echo $msg->toJson(true);
// OR you can just convert to an array and do something else with the data.
print_r($msg->toArray());

Kit 门面

Kit 类充当整个库组件集的门面,并为每个组件提供工厂方法。它允许您减少在构建消息(或其他表面)时需要导入的类数量。

每个工厂方法具有与原始组件构造函数相同的参数。

<?php

use SlackPhp\BlockKit\Kit;

// ...

$msg = Kit::message(
    ephemeral: true,
    blocks: [
        Kit::section('Don\'t you just love XKCD?'),
        Kit::divider(),
        Kit::blockImage(
            title: 'Team Chat',
            imageUrl: 'https://imgs.xkcd.com/comics/team_chat.png',
            altText: 'Comic about the stubbornness of some people switching chat clients',
        ),
    ]
);

流畅接口

如果命名参数不适合您,还有另一种方法可以设置组件的属性,即通过设置器方法。每个组件都有可链式设置的属性设置器方法,这允许实现流畅风格的接口。

$msg = Kit::message()
    ->ephemeral()
    ->blocks(
        Kit::section('Don\'t you just love XKCD?'),
        Kit::divider(),
        Kit::blockImage()
            ->title('Team Chat')
            ->imageUrl('https://imgs.xkcd.com/comics/team_chat.png')
            ->altText('Comic about the stubbornness of some people switching chat clients')
        ),
    );

流式语法不依赖于 Kit 外观。组件类有一个静态的 new() 方法,也可以用于链式调用。

$msg = Message::new()
    ->ephemeral()
    ->blocks(
        Section::new('Don\'t you just love XKCD?'),
        Divider::new(),
        BlockImage::new()
            ->title('Team Chat')
            ->imageUrl('https://imgs.xkcd.com/comics/team_chat.png')
            ->altText('Comic about the stubbornness of some people switching chat clients')
        ),
    );

空值

所有属性在设置之前都视为空/空值。

您还可以显式地将属性设置为空,以移除其值(例如,从您从现有数据创建的组件中)。

$section->accessory(null);

最后,列表中的块、元素、选项等允许空值,因此可以使用条件项目。

$msg = Kit::message(
    blocks: [
        Kit::section('Don\'t you just love XKCD?'),
        ($includeDivider) ? Kit::divider() : null,
        Kit::blockImage(
            title: 'Team Chat',
            imageUrl: 'https://imgs.xkcd.com/comics/team_chat.png',
            altText: 'Comic about the stubbornness of some people switching chat clients',
        ),
    ]
);

在块套件构建器中预览

Slack 提供了一个 交互式块套件构建器,用于编写/测试消息和其他界面。这是探索和了解块套件格式的绝佳方式。

Kit::preview 方法允许您将消息/界面作为块套件构建器 URL 渲染,这样您就可以通过它们的交互式工具在浏览器中链接到预览或消息/界面。这将帮助您了解它在 Slack 客户端中的渲染效果。

$msg = Kit::message(
    ephemeral: true,
    blocks: [
        Kit::section('Don\'t you just love XKCD?'),
        Kit::divider(),
        Kit::blockImage(
            title: 'Team Chat',
            imageUrl: 'https://imgs.xkcd.com/comics/team_chat.png',
            altText: 'Comic about the stubbornness of some people switching chat clients',
        ),
    ]
);

echo Kit::preview($msg);

输出

https://app.slack.com/block-kit-builder#%7B"blocks":%5B%7B"type":"section"%2C"text":%7B"type":"mrkdwn"%2C"text":"Don%27t%20you%20just%20love%20XKCD%3F"%7D%7D%2C%7B"type":"divider"%7D%2C%7B"type":"image"%2C"title":%7B"type":"plain_text"%2C"text":"Team%20Chat"%7D%2C"image_url":"https:%5C%2F%5C%2Fimgs.xkcd.com%5C%2Fcomics%5C%2Fteam_chat.png"%2C"alt_text":"Comic%20about%20the%20stubbornness%20of%20some%20people%20switching%20chat%20clients"%7D%5D%7D

这里是实际的块套件构建器链接

它在块套件构建器中看起来可能像这样

Screenshot of rendered message in Block Kit Builder

组件活化

某些 Slack 应用程序集成(如与模态集成)需要接收现有界面的 JSON,然后修改或替换该界面。您可以使用其 fromArray 方法(或 fromJson)将界面的 JSON(或元素)"活化"为其对象表示。

$messageJson = <<<JSON
{
    "blocks": [
        {
            "type": "section",
            "block_id": "block1",
            "text": {
                "type": "mrkdwn",
                "text": "*foo bar*"
            }
        }
    }
}
JSON;

// Use fromArray to hydrate the message from parsed JSON data.
$decodedMessageJson = json_decode($messageJson, true);
$message = Message::fromArray($decodedMessageJson);

// OR... use fromJson to hydrate from a JSON string.
$message = Message::fromJson($messageJson);

消息格式化

存在 Md 类,用于提供格式化 "mrkdwn" 文本的辅助工具。这些辅助工具可以用于避免记住 Slack mrkdwn 语法。此外,如果需要,这些函数将自动正确转义 <>& 字符。

示例

// Note: $event is meant to represent some kind of DTO from your own application.
$md = Kit::md();
$msg = Kit::message(
    blocks: [
        Kit::section(
            text: $md->sub(
                'Hello, {audience}! On {date}, {host} will be hosting an AMA in the {channel} channel at {time}.',
                [
                    'audience' => $md->atHere(),
                    'date'     => $md->date($event->timestamp),
                    'host'     => $md->user($event->hostId),
                    'channel'  => $md->channel($event->channelId),
                    'time'     => $md->time($event->timestamp),
                ]
            )
        )
    ]
);

示例结果

{
  "blocks": [
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "Hello, <!here>! On <!date^1608322949^{date}|2020-12-18T20:22:29+00:00>, <@U12345678> will be hosting an AMA in the <#C12345678> channel at <!date^1608322949^{time}|2020-12-18T20:22:29+00:00>."
      }
    }
  ]
}

虚拟块

除了标准块之外,以下是一些由一个或多个其他块组成的虚拟/自定义块

  • TwoColumnTable - 使用带有字段的分区来创建具有可选标题的两列表格。
  • CodeBlock - 使用分区来创建具有可选标题的代码块。

类结构

  • SurfaceBlockElementPart 都是块套件 Component 的类型。
  • 可以使用 Kit 外观作为工厂创建任何 Component
  • Component 包含定义其外观和行为的属性和子 Component
  • Part 是构成其他 Component 属性的重复模式。
  • Surface 包含一个或多个 Block
  • Block 包含一个或多个 Element
  • 大多数 Element 以某种方式是交互式的。
  • 许多 Element 也是 Input,接收用户输入。

UML diagram for slack-block-kit

请参阅 YUML
[Kit]-creates>[Component]
[Surface]^[Message]
[Surface]^[Modal]
[Surface]^[AppHome]
[Surface]^[Attachment]
[Component]^[Surface]
[Component]^[Block]
[Component]^[Element]
[Component]^[Part]
[Component]<>->[Part]
[Surface]<>->[Block]
[Message]<>->[Attachment]
[Block]<>->[Element]
[Element]^[Input]
[Element]-[note:Examples: Button, OverflowMenu {bg:cornsilk}]
[Input]-[note:Examples: Select Menu, DatePicker {bg:cornsilk}]
[Part]-[note: Examples: Text, Fields {bg:cornsilk}]
[Block]-[note: Examples: Section, Actions {bg:cornsilk}]

贡献

欢迎贡献以支持新元素、添加测试、改进代码等。