Dify
English
English
  • Getting Started
    • Welcome to Dify
      • Features and Specifications
      • List of Model Providers
    • Dify Community
      • Deploy with Docker Compose
      • Start with Local Source Code
      • Deploy with aaPanel
      • Start Frontend Docker Container Separately
      • Environment Variables Explanation
      • FAQs
    • Dify Cloud
    • Dify Premium on AWS
    • Dify for Education
  • Guides
    • Model
      • Add New Provider
      • Predefined Model Integration
      • Custom Model Integration
      • Interfaces
      • Schema
      • Load Balancing
    • Application Orchestration
      • Create Application
      • Chatbot Application
        • Multiple Model Debugging
      • Agent
      • Application Toolkits
        • Moderation Tool
    • Workflow
      • Key Concepts
      • Variables
      • Node Description
        • Start
        • End
        • Answer
        • LLM
        • Knowledge Retrieval
        • Question Classifier
        • Conditional Branch IF/ELSE
        • Code Execution
        • Template
        • Doc Extractor
        • List Operator
        • Variable Aggregator
        • Variable Assigner
        • Iteration
        • Parameter Extraction
        • HTTP Request
        • Agent
        • Tools
        • Loop
      • Shortcut Key
      • Orchestrate Node
      • File Upload
      • Error Handling
        • Predefined Error Handling Logic
        • Error Type
      • Additional Features
      • Debug and Preview
        • Preview and Run
        • Step Run
        • Conversation/Run Logs
        • Checklist
        • Run History
      • Application Publishing
      • Structured Outputs
      • Bulletin: Image Upload Replaced by File Upload
    • Knowledge
      • Create Knowledge
        • 1. Import Text Data
          • 1.1 Import Data from Notion
          • 1.2 Import Data from Website
        • 2. Choose a Chunk Mode
        • 3. Select the Indexing Method and Retrieval Setting
      • Manage Knowledge
        • Maintain Documents
        • Maintain Knowledge via API
      • Metadata
      • Integrate Knowledge Base within Application
      • Retrieval Test / Citation and Attributions
      • Knowledge Request Rate Limit
      • Connect to an External Knowledge Base
      • External Knowledge API
    • Tools
      • Quick Tool Integration
      • Advanced Tool Integration
      • Tool Configuration
        • Google
        • Bing
        • SearchApi
        • StableDiffusion
        • Dall-e
        • Perplexity Search
        • AlphaVantage
        • Youtube
        • SearXNG
        • Serper
        • SiliconFlow (Flux AI Supported)
        • ComfyUI
    • Publishing
      • Publish as a Single-page Web App
        • Web App Settings
        • Text Generator Application
        • Conversation Application
      • Embedding In Websites
      • Developing with APIs
      • Re-develop Based on Frontend Templates
    • Annotation
      • Logs and Annotation
      • Annotation Reply
    • Monitoring
      • Data Analysis
      • Integrate External Ops Tools
        • Integrate LangSmith
        • Integrate Langfuse
        • Integrate Opik
    • Extension
      • API-Based Extension
        • External Data Tool
        • Deploy API Tools with Cloudflare Workers
        • Moderation
      • Code-Based Extension
        • External Data Tool
        • Moderation
    • Collaboration
      • Discover
      • Invite and Manage Members
    • Management
      • App Management
      • Team Members Management
      • Personal Account Management
      • Subscription Management
      • Version Control
  • Workshop
    • Basic
      • How to Build an AI Image Generation App
    • Intermediate
      • Build An Article Reader Using File Upload
      • Building a Smart Customer Service Bot Using a Knowledge Base
      • Generating analysis of Twitter account using Chatflow Agent
  • Community
    • Seek Support
    • Become a Contributor
    • Contributing to Dify Documentation
  • Plugins
    • Introduction
    • Quick Start
      • Install and Use Plugins
      • Develop Plugins
        • Initialize Development Tools
        • Tool Plugin
        • Model Plugin
          • Create Model Providers
          • Integrate the Predefined Model
          • Integrate the Customizable Model
        • Agent Strategy Plugin
        • Extension Plugin
        • Bundle
      • Debug Plugin
    • Manage Plugins
    • Schema Specification
      • Manifest
      • Endpoint
      • Tool
      • Agent
      • Model
        • Model Designing Rules
        • Model Schema
      • General Specifications
      • Persistent Storage
      • Reverse Invocation of the Dify Service
        • App
        • Model
        • Tool
        • Node
    • Best Practice
      • Develop a Slack Bot Plugin
      • Dify MCP Plugin Guide: Connect Zapier and Automate Email Delivery with Ease
    • Publish Plugins
      • Publish Plugins Automatically
      • Publish to Dify Marketplace
        • Plugin Developer Guidelines
        • Plugin Privacy Protection Guidelines
      • Publish to Your Personal GitHub Repository
      • Package the Plugin File and Publish it
      • Signing Plugins for Third-Party Signature Verification
    • FAQ
  • Development
    • Backend
      • DifySandbox
        • Contribution Guide
    • Models Integration
      • Integrate Open Source Models from Hugging Face
      • Integrate Open Source Models from Replicate
      • Integrate Local Models Deployed by Xinference
      • Integrate Local Models Deployed by OpenLLM
      • Integrate Local Models Deployed by LocalAI
      • Integrate Local Models Deployed by Ollama
      • Integrate Models on LiteLLM Proxy
      • Integrating with GPUStack for Local Model Deployment
      • Integrating AWS Bedrock Models (DeepSeek)
    • Migration
      • Migrating Community Edition to v1.0.0
  • Learn More
    • Use Cases
      • DeepSeek & Dify Integration Guide: Building AI Applications with Multi-Turn Reasoning
      • Private Deployment of Ollama + DeepSeek + Dify: Build Your Own AI Assistant
      • Build a Notion AI Assistant
      • Create a MidJourney Prompt Bot with Dify
      • Create an AI Chatbot with Business Data in Minutes
      • Integrating Dify Chatbot into Your Wix Website
      • How to connect with AWS Bedrock Knowledge Base?
      • Building the Dify Scheduler
      • Building an AI Thesis Slack Bot on Dify
    • Extended Reading
      • What is LLMOps?
      • Retrieval-Augmented Generation (RAG)
        • Hybrid Search
        • Re-ranking
        • Retrieval Modes
      • How to Use JSON Schema Output in Dify?
    • FAQ
      • Self-Host
      • LLM Configuration and Usage
      • Plugins
  • Policies
    • Open Source License
    • User Agreement
      • Terms of Service
      • Privacy Policy
      • Get Compliance Report
  • Features
    • Workflow
Powered by GitBook
On this page
  • Project Background
  • Prerequisites
  • 1. Developing the Plugin
  • 2. Debugging Plugins
  • 3. Verify the Plugin
  • 4. Package the Plugin (Optional)
  • 5. Publish the Plugin (Optional)
  • Further Reading
  1. Plugins
  2. Best Practice

Develop a Slack Bot Plugin

PreviousBest PracticeNextDify MCP Plugin Guide: Connect Zapier and Automate Email Delivery with Ease

Last updated 3 months ago

What You’ll Learn:

Gain a solid understanding of how to build a Slack Bot that’s powered by AI—one that can respond to user questions right inside Slack.

Project Background

The Dify plugin ecosystem focuses on making integrations simpler and more accessible. In this guide, we’ll use Slack as an example, walking you through the process of developing a Slack Bot plugin. This allows your team to chat directly with an LLM within Slack, significantly improving how efficiently they can use AI.

Slack is an open, real-time communication platform with a robust API. Among its features is a webhook-based event system, which is quite straightforward to develop on. We’ll leverage this system to create a Slack Bot plugin, illustrated in the diagram below:

Slack Bot diagram

To avoid confusion, the following concepts are explained:

  • Slack Bot A chatbot on the Slack platform, acting as a virtual user you can interact with in real-time.

  • Slack Bot Plugin A plugin in the Dify Marketplace that connects a Dify application with Slack. This guide focuses on how to develop that plugin.

How It Works (A Simple Overview):

  1. Send a Message to the Slack Bot

    When a user in Slack sends a message to the Bot, the Slack Bot immediately issues a webhook request to the Dify platform.

  2. Forward the Message to the Slack Bot Plugin

    The Dify platform triggers the Slack Bot plugin, which relays the details to the Dify application—similar to entering a recipient’s address in an email system. By setting up a Slack webhook address through Slack’s API and entering it in the Slack Bot plugin, you establish this connection. The plugin then processes the Slack request and sends it on to the Dify application, where the LLM analyzes the user’s input and generates a response.

  3. Return the Response to Slack

Once the Slack Bot plugin receives the reply from the Dify application, it sends the LLM’s answer back through the same route to the Slack Bot. Users in Slack then see a more intelligent, interactive experience right where they’re chatting.

Prerequisites

  • Create a Slack App and Get an OAuth Token

  1. Enable Webhooks:

  1. Install the App in Your Slack Workspace:

  1. Obtain an OAuth Token for future plugin development:

1. Developing the Plugin

1.1 Initialize the Project

Run the following command to set up your plugin development environment:

dify plugin init

Follow the prompts to provide basic project info. Select the extension template, and grant both Apps and Endpoints permissions.

1.2 Edit the Configuration Form

This plugin needs to know which Dify app should handle the replies, as well as the Slack App token to authenticate the bot’s responses. Therefore, you’ll add these two fields to the plugin’s form.

Modify the YAML file in the group directory—for example, group/slack.yaml. The form’s filename is determined by the info you provided when creating the plugin, so adjust it accordingly.

Sample Code:

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

Explanation of the Configuration Fields:

  - name: app
    type: app-selector
    scope: chat
  • type: Set to app-selector, which allows users to forward messages to a specific Dify app when using this plugin.

  • scope: Set to chat, meaning the plugin can only interact with app types such as agent, chatbot, or chatflow.

Finally, in the endpoints/slack.yaml file, change the request method to POST to handle incoming Slack messages properly.

Sample Code:

endpoints/slack.yaml

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

2. Edit the function code

Modify the endpoints/slack.py file and add the following code:

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")

2. Debugging Plugins

### 2. Debug the Plugin

Go to the Dify platform and obtain the remote debugging address and key for your plugin.

<figure><img src="https://assets-docs.dify.ai/2025/01/8d24006f0cabf5bf61640a9023c45db8.png" alt=""><figcaption></figcaption></figure>

Back in your plugin project, copy the `.env.example` file and rename it to `.env`.

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

Run python -m main to start the plugin. You should now see your plugin installed in the Workspace on Dify’s plugin management page. Other team members will also be able to access it.

python -m main

Configure the Plugin Endpoint

From the plugin management page in Dify, locate the newly installed test plugin and create a new endpoint. Provide a name, a Bot token, and select the app you want to connect.

After saving, a POST request URL is generated:

Next, complete the Slack App setup:


3. Verify the Plugin

In your code, self.session.app.chat.invoke is used to call the Dify application, passing in parameters such as app_id and query. The response is then returned to the Slack Bot. Run python -m main again to restart your plugin for debugging, and check whether Slack correctly displays the Dify App’s reply:


4. Package the Plugin (Optional)

Once you confirm that the plugin works correctly, you can package and name it via the following command. After it runs, you’ll find a slack_bot.difypkg file in the current directory—your final plugin package.

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

dify plugin package ./slack_bot

Congratulations! You’ve successfully developed, tested, and packaged a plugin!


5. Publish the Plugin (Optional)


Further Reading

If you want to explore more about plugin development, check the following:

Quick Starts:

Plugin Interface Docs:

Dify plugin developing tool: For more information, see .

Python environment (version ≥ 3.12): Refer to this or ask an LLM for a complete setup guide.

Go to the , create a Slack app from scratch, and pick the workspace where it will be deployed.

Now we’ll dive into the actual coding. Before starting, make sure you’ve read or have already built a Dify plugin before.

For additional details on reverse-invoking Dify services within a plugin, see .

Plugins permission

Enable Event Subscriptions

Paste the POST request URL you generated above.

Grant Required Permissions

You can now upload it to the for public release. Before publishing, ensure your plugin meets the . Once approved, your code is merged into the main branch, and the plugin goes live on the .

For a complete Dify plugin project example, visit the . You’ll also find additional plugins with full source code and implementation details.

structure

definitions

Initializing the Development Tool
Python Installation Tutorial
Slack API platform
Quick Start: Developing an Extension Plugin
Reverse Invocation: App
Dify Marketplace repository
Plugin Publishing Guidelines
Dify Marketplace
GitHub repository
Develop an Extension Plugin
Develop a Model Plugin
Bundle Plugins: Packaging Multiple Plugins
Manifest
Endpoint
Reverse-Calling Dify Services
Tools
Models