Dify
简体中文
简体中文
  • 入门
    • 欢迎使用 Dify
      • 特性与技术规格
      • 模型供应商列表
    • 云服务
    • 社区版
      • Docker Compose 部署
      • 本地源码启动
      • 宝塔面板部署
      • 单独启动前端 Docker 容器
      • 环境变量说明
      • 常见问题
    • Dify Premium
    • Dify 教育版
  • 手册
    • 接入大模型
      • 增加新供应商
      • 预定义模型接入
      • 自定义模型接入
      • 接口方法
      • 配置规则
      • 负载均衡
    • 构建应用
      • 创建应用
      • 聊天助手
        • 多模型调试
      • Agent
      • 应用工具箱
        • 敏感内容审查
    • 工作流
      • 关键概念
      • 变量
      • 节点说明
        • 开始
        • LLM
        • 知识检索
        • 问题分类
        • 条件分支
        • 代码执行
        • 模板转换
        • 文档提取器
        • 列表操作
        • 变量聚合
        • 变量赋值
        • 迭代
        • 参数提取
        • HTTP 请求
        • Agent
        • 工具
        • 结束
        • 直接回复
        • 循环
      • 快捷键
      • 编排节点
      • 文件上传
      • 异常处理
        • 预定义异常处理逻辑
        • 错误类型
      • 附加功能
      • 预览与调试
        • 预览与运行
        • 单步调试
        • 对话/运行日志
        • 检查清单
        • 运行历史
      • 应用发布
      • 结构化输出
      • 变更公告:图片上传被替换为文件上传
    • 知识库
      • 创建知识库
        • 1. 导入文本数据
          • 1.1 从 Notion 导入数据
          • 1.2 从网页导入数据
        • 2. 指定分段模式
        • 3. 设定索引方法与检索设置
      • 管理知识库
        • 维护知识库内文档
        • 通过 API 维护知识库
      • 元数据
      • 在应用内集成知识库
      • 召回测试/引用归属
      • 知识库请求频率限制
      • 连接外部知识库
      • 外部知识库 API
    • 工具
      • 快速接入工具
      • 高级接入工具
      • 工具配置
        • Google
        • Bing
        • SearchApi
        • StableDiffusion
        • Dall-e
        • Perplexity Search
        • AlphaVantage 股票分析
        • Youtube
        • SearXNG
        • Serper
        • SiliconFlow (支持 Flux 绘图)
        • ComfyUI
    • 发布
      • 发布为公开 Web 站点
        • Web 应用的设置
        • 文本生成型应用
        • 对话型应用
      • 嵌入网站
      • 基于 APIs 开发
      • 基于前端组件再开发
    • 标注
      • 日志与标注
      • 标注回复
    • 监测
      • 集成外部 Ops 工具
        • 集成 LangSmith
        • 集成 Langfuse
        • 集成 Opik
      • 数据分析
    • 扩展
      • API 扩展
        • 使用 Cloudflare Workers 部署 API Tools
        • 敏感内容审查
      • 代码扩展
        • 外部数据工具
        • 敏感内容审查
    • 协同
      • 发现
      • 邀请与管理成员
    • 管理
      • 应用管理
      • 团队成员管理
      • 个人账号管理
      • 订阅管理
      • 版本管理
  • 动手实验室
    • 初级
      • 如何搭建 AI 图片生成应用
      • AI Agent 实战:搭建个人在线旅游助手
    • 中级
      • 使用文件上传搭建文章理解助手
      • 使用知识库搭建智能客服机器人
      • ChatFlow 实战:搭建 Twitter 账号分析助手
  • 社区
    • 寻求支持
    • 成为贡献者
    • 为 Dify 文档做出贡献
  • 插件
    • 功能简介
    • 快速开始
      • 安装与使用插件
      • 插件开发
        • 初始化开发工具
        • Tool 插件
        • Model 插件
          • 创建模型供应商
          • 接入预定义模型
          • 接入自定义模型
        • Agent 策略插件
        • Extension 插件
        • Bundle 插件包
      • 插件调试
    • 插件管理
    • 接口定义
      • Manifest
      • Endpoint
      • Tool
      • Agent
      • Model
        • 模型设计规则
        • 模型接口
      • 通用规范定义
      • 持久化存储
      • 反向调用 Dify 服务
        • App
        • Model
        • Tool
        • Node
    • 最佳实践
      • 开发 Slack Bot 插件
      • Dify MCP 插件指南:一键连接 Zapier 并自动发送邮件
    • 发布插件
      • 自动发布插件
      • 发布至 Dify Marketplace
        • 插件开发者准则
        • 插件隐私政策准则
      • 发布至个人 GitHub 仓库
      • 本地发布与分享
      • 第三方签名验证
    • 常见问题
  • 研发
    • 后端
      • DifySandbox
        • 贡献指南
    • 模型接入
      • 接入 Hugging Face 上的开源模型
      • 接入 Replicate 上的开源模型
      • 接入 Xinference 部署的本地模型
      • 接入 OpenLLM 部署的本地模型
      • 接入 LocalAI 部署的本地模型
      • 接入 Ollama 部署的本地模型
      • 接入 LiteLLM 代理的模型
      • 接入 GPUStack 进行本地模型部署
      • 接入 AWS Bedrock 上的模型(DeepSeek)
    • 迁移
      • 将社区版迁移至 v1.0.0
  • 阅读更多
    • 应用案例
      • DeepSeek 与 Dify 集成指南:打造具备多轮思考的 AI 应用
      • 本地私有化部署 DeepSeek + Dify,构建你的专属私人 AI 助手
      • 如何训练出专属于“你”的问答机器人?
      • 教你十几分钟不用代码创建 Midjourney 提示词机器人
      • 构建一个 Notion AI 助手
      • 如何在几分钟内创建一个带有业务数据的官网 AI 智能客服
      • 使用全套开源工具构建 LLM 应用实战:在 Dify 调用 Baichuan 开源模型能力
      • 手把手教你把 Dify 接入微信生态
      • 使用 Dify 和 Twilio 构建 WhatsApp 机器人
      • 将 Dify 应用与钉钉机器人集成
      • 使用 Dify 和 Azure Bot Framework 构建 Microsoft Teams 机器人
      • 如何让 LLM 应用提供循序渐进的聊天体验?
      • 如何将 Dify Chatbot 集成至 Wix 网站?
      • 如何连接 AWS Bedrock 知识库?
      • 构建 Dify 应用定时任务助手
      • 如何在 Dify 内体验大模型“竞技场”?以 DeepSeek R1 VS o1 为例
      • 在 Dify 云端构建 AI Thesis Slack Bot
      • 将 Dify 快速接入 QQ、微信、飞书、钉钉、Telegram、Discord 等平台
    • 扩展阅读
      • 什么是 LLMOps?
      • 什么是数组变量?
      • 检索增强生成(RAG)
        • 混合检索
        • 重排序
        • 召回模式
      • 提示词编排
      • 如何使用 JSON Schema 让 LLM 输出遵循结构化格式的内容?
    • 常见问题
      • 本地部署
      • LLM 配置与使用
      • 插件
  • 政策
    • 开源许可证
    • 用户协议
      • 服务条款
      • 隐私政策
      • 获取合规报告
Powered by GitBook
On this page
  • 项目背景
  • 前置准备
  • 1. 开发插件
  • 2. 调试插件
  • 3. 验证插件效果
  • 4. 打包插件(可选)
  • 5. 发布插件(可选)
  • 参考阅读
  1. 插件
  2. 最佳实践

开发 Slack Bot 插件

Previous最佳实践NextDify MCP 插件指南:一键连接 Zapier 并自动发送邮件

Last updated 3 months ago

本文将帮助你:

深入掌握 Slack Bot 的搭建方法,创建由 AI 驱动的 Slack 聊天机器人,在 Slack 平台上智能回答用户的问题。

项目背景

Dify 插件生态致力于支持更简单、更易用的接入方式。本文将以 Slack 为例,详细介绍如何开发一个 Slack Bot 插件,便于团队中的成员直接在 Slack 平台内与 LLM 对话,提升 AI 服务的使用效率。

Dify 插件生态旨在提供更简单、更便捷的接入方式。本文将以 Slack 为例,详细讲解如何开发一个 Slack Bot 插件,帮助团队成员直接在 Slack 平台使用 AI 应用,提升办公效率。

Slack 是一个自由开放的实时办公通信平台,拥有丰富的 API。其中,基于事件机制的 Webhook 功能易于上手开发。我们将利用该机制创建 Slack Bot 插件,其原理如下图所示:

Slack Bot 原理图

为了避免混乱,现对以下概念作出解释:

  • Slack Bot 是在 Slack 平台上的一个聊天机器人,可以被视为虚拟角色,你可以与它进行聊天互动

  • Slack Bot 插件指的是 Dify Marketplace上的一款插件,用于连接 Dify 应用与 Slack 平台。本文将主要围绕该插件开发展开。

原理简介:

  1. 向 Slack Bot 发送消息

    当用户在 Slack 中向 Bot 机器人发出一条消息的时候,Slack Bot 会发出一个 Webhook 请求到 Dify 平台。

  2. 消息转发至 Slack Bot 插件

    用户在与 Slack bot 对话时,需要将消息转发至 Dify 应用。好比邮件系统需要一位收件人的邮箱,此时可以通过 Slack 的 API 配置一个 Slack Webhook 的地址,并将其填入至 Slack Bot 插件并建立连接。

  3. 插件在接受到消息后,返回至某个 Dify 应用

    Slack Bot 插件将处理 Slack 请求,发送至 Dify 中的应用。由 LLM 分析用户输入的内容并给出回应。

  4. Dify 应用回应后,将消息返回至 Slack Bot 并回答用户

    Slack Bot 获取 Dify 应用的回复后,通过插件将消息原路返回至 Slack Bot,使得用户能够在使用 Slack 时直接与 Dify 应用互动

前置准备

  • 创建 Slack App 并获取 OAuth Token

开启 Webhooks 功能。

将 App 安装至 Slack 工作区内。

获取 OAuth Token,用于后续的插件开发。

1. 开发插件

初始化项目

运行以下命令初始化插件开发项目:

dify plugin init

按照提示填写项目的基础信息,选择 extension 模板,并且授予 Apps 和 Endpoints 两个权限。

1. 编辑配置表单

在这个插件中,需要指定使用哪个 Dify 的 App 进行回复,并且在回复的时候需要使用到 Slack 的 App token,因此需要在插件表单中加上这两个字段。

修改 group 路径下的 yaml 文件,例如 group/slack.yaml。表单配置文件的名称由创建插件时填写的基础信息决定,你可以修改对应的 yaml 文件。

示例代码:

slack.yaml

settings:
  - name: bot_token
    type: secret-input
    required: true
    label:
      en_US: Bot Token
      zh_Hans: Bot Token
      pt_BR: Token do Bot
      ja_JP: Bot Token
    placeholder:
      en_US: Please input your Bot Token
      zh_Hans: 请输入你的 Bot Token
      pt_BR: Por favor, insira seu Token do Bot
      ja_JP: ボットトークンを入力してください
  - name: allow_retry
    type: boolean
    required: false
    label:
      en_US: Allow Retry
      zh_Hans: 允许重试
      pt_BR: Permitir Retentativas
      ja_JP: 再試行を許可
    default: false
  - name: app
    type: app-selector
    required: true
    label:
      en_US: App
      zh_Hans: 应用
      pt_BR: App
      ja_JP: アプリ
    placeholder:
      en_US: the app you want to use to answer Slack messages
      zh_Hans: 你想要用来回答 Slack 消息的应用
      pt_BR: o app que você deseja usar para responder mensagens do Slack
      ja_JP: あなたが Slack メッセージに回答するために使用するアプリ
endpoints:
  - endpoints/slack.yaml

代码数据结构说明:

  - name: app
    type: app-selector
    scope: chat
  • type 字段指定为 app-selector 字段

    用户在使用插件时可以访问某个 Dify 应用并进行消息转发。

  • scope 字段指定为 chat 字段

    只能使用 agent 、chatbot 、chatflow 等类型的 app。

最后修改 endpoints/slack.yaml 文件中的请求路径和请求方式,需要将 method 修改为 POST 方式。

示例代码:

endpoints/slack.yaml

path: "/"
method: "POST"
extra:
  python:
    source: "endpoints/slack.py"

2. 编辑功能代码

修改 endpoints/slack.py文件,并在其中添加下面的代码:

import json
import traceback
from typing import Mapping
from werkzeug import Request, Response
from dify_plugin import Endpoint
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError


class SlackEndpoint(Endpoint):
    def _invoke(self, r: Request, values: Mapping, settings: Mapping) -> Response:
        """
        Invokes the endpoint with the given request.
        """
        retry_num = r.headers.get("X-Slack-Retry-Num")
        if (not settings.get("allow_retry") and (r.headers.get("X-Slack-Retry-Reason") == "http_timeout" or ((retry_num is not None and int(retry_num) > 0)))):
            return Response(status=200, response="ok")
        data = r.get_json()

        # Handle Slack URL verification challenge
        if data.get("type") == "url_verification":
            return Response(
                response=json.dumps({"challenge": data.get("challenge")}),
                status=200,
                content_type="application/json"
            )
        
        if (data.get("type") == "event_callback"):
            event = data.get("event")
            if (event.get("type") == "app_mention"):
                message = event.get("text", "")
                if message.startswith("<@"):
                    message = message.split("> ", 1)[1] if "> " in message else message
                    channel = event.get("channel", "")
                    blocks = event.get("blocks", [])
                    blocks[0]["elements"][0]["elements"] = blocks[0].get("elements")[0].get("elements")[1:]
                    token = settings.get("bot_token")
                    client = WebClient(token=token)
                    try: 
                        response = self.session.app.chat.invoke(
                            app_id=settings["app"]["app_id"],
                            query=message,
                            inputs={},
                            response_mode="blocking",
                        )
                        try:
                            blocks[0]["elements"][0]["elements"][0]["text"] = response.get("answer")
                            result = client.chat_postMessage(
                                channel=channel,
                                text=response.get("answer"),
                                blocks=blocks
                            )
                            return Response(
                                status=200,
                                response=json.dumps(result),
                                content_type="application/json"
                            )
                        except SlackApiError as e:
                            raise e
                    except Exception as e:
                        err = traceback.format_exc()
                        return Response(
                            status=200,
                            response="Sorry, I'm having trouble processing your request. Please try again later." + str(err),
                            content_type="text/plain",
                        )
                else:
                    return Response(status=200, response="ok")
            else:
                return Response(status=200, response="ok")
        else:
            return Response(status=200, response="ok")

```

为了便于测试,插件功能目前仅能重复用户输入的内容,暂不调用 Dify app。

2. 调试插件

前往 Dify 平台,获取 Dify 插件远程调试的连接地址和密钥。

回到插件项目,复制 .env.example 文件并重命名为 .env。

INSTALL_METHOD=remote
REMOTE_INSTALL_HOST=remote
REMOTE_INSTALL_PORT=5003
REMOTE_INSTALL_KEY=****-****-****-****-****

运行 python -m main 命令启动插件。在插件页即可看到该插件已被安装至 Workspace 内。其他团队成员也可以访问该插件。

python -m main

设置插件 Endpoint

在 Dify 的插件管理页中找到自动安装的测试插件,新建一个 Endpoint,填写名称、Bot token、选择需要连接的 app。

保存后将生成一个 POST 请求地址。

接下来还需要完成 Slack App 的设置。

  1. 启用 Event 订阅

在其中粘贴上文中生成的插件 POST 请求地址。

勾选 Slack App 所需具备的权限。

3. 验证插件效果

代码使用了 self.session.app.chat.invoke 调用 Dify 平台内的 App,并传递了 app_id 和 query 等信息,最后将 response 的内容返回至 Slack Bot。运行 python -m main 命令重启插件进行调试,确认 Slack Bot 是否能够正确输出 Dify App 的答复消息。

4. 打包插件(可选)

确认插件能够正常运行后,可以通过以下命令行工具打包并命名插件。运行以后你可以在当前文件夹发现 slack_bot.difypkg 文件,该文件为最终的插件包。

# Replace ./slack_bot with your actual plugin project path.

dify plugin package ./slack_bot

恭喜,你已完成一个插件的完整开发、测试打包过程!

5. 发布插件(可选)

参考阅读

如果想要了解更多插件,请参考以下内容。

快速开始:

插件接口文档:

Dify 插件脚手架工具,详细说明请参考。

Python 环境,版本号 ≥ 3.12,详细说明请参考 ,或询问 LLM 获取完整的安装教程。

前往 平台, 选择以 scratch 方式创建 Slack APP,并选择需部署应用的 Slack 空间。

Slack api token
开启 Webhooks 功能
安装至工作区内
获取 OAuth Token

现在开始实际的插件编码工作。在开始之前,请确保你已经阅读过,或已动手开发过一次 Dify 插件。

如需了解更多关于插件反向调用 Dify 平台能力,请参考。

Plugins permission

现在可以将它上传至 来发布你的插件了!不过在发布前,请确保你的插件遵循了。

如果你想要查看完整 Dify 插件的项目代码,请前往 。除此之外,你可以看到其它插件的完整代码与具体细节。

结构

详细定义

初始化开发工具
Python 安装教程
Slack API
快速开始:开发 Extension 插件
反向调用:App
Dify Marketplace 仓库
插件发布规范
Github 代码仓库
开发 Extension 插件
开发 Model 插件
Bundle 类型插件:将多个插件打包
Manifest
Endpoint
反向调用 Dify 能力
工具
模型