Skip to main content
⚠️ このドキュメントはAIによって自動翻訳されています。不正確な部分がある場合は、英語版を参照してください。
学習内容: AIを活用したSlack Botの構築方法をしっかりと理解できます。このBotはSlack内でユーザーの質問に直接回答できます。プラグインを初めて開発する場合は、まずプラグイン開発クイックスタートガイドを読むことをお勧めします。

プロジェクトの背景

Difyプラグインエコシステムは、統合をよりシンプルでアクセスしやすくすることに焦点を当てています。このガイドでは、Slackを例として、Slack Botプラグインの開発プロセスを順を追って説明します。これにより、チームはSlack内でLLMと直接チャットでき、AIの活用効率が大幅に向上します。 Slackは、堅牢なAPIを備えたオープンなリアルタイムコミュニケーションプラットフォームです。その機能の中には、webhookベースのイベントシステムがあり、開発が非常に簡単です。このシステムを活用してSlack Botプラグインを作成します。以下の図に示されています: Slack Bot diagram
混乱を避けるため、以下の概念を説明します:
  • Slack Bot Slackプラットフォーム上のチャットボットで、リアルタイムでやり取りできる仮想ユーザーとして機能します。
  • Slack Botプラグイン DifyアプリケーションとSlackを接続するDify Marketplace内のプラグインです。このガイドでは、そのプラグインの開発方法に焦点を当てています。
動作の仕組み(簡単な概要):
  1. Slack Botにメッセージを送信する Slack内のユーザーがBotにメッセージを送信すると、Slack Botは即座にDifyプラットフォームにwebhookリクエストを発行します。
  2. メッセージをSlack Botプラグインに転送する Difyプラットフォームは、Slack Botプラグインをトリガーし、詳細をDifyアプリケーションに中継します。これは、メールシステムで受信者のアドレスを入力するのと似ています。SlackのAPIを通じてSlack webhookアドレスを設定し、Slack Botプラグインに入力することで、この接続が確立されます。プラグインはSlackリクエストを処理し、Difyアプリケーションに送信します。そこでLLMがユーザーの入力を分析し、応答を生成します。
  3. Slackに応答を返す Slack BotプラグインがDifyアプリケーションから応答を受け取ると、同じルートを通じてLLMの回答をSlack Botに送り返します。Slack内のユーザーは、チャットしている場所で、よりインテリジェントでインタラクティブな体験を得られます。

前提条件

  • Difyプラグイン開発ツール:詳細については、開発ツールの初期化を参照してください。
  • Python環境(バージョン ≥ 3.12):このPythonインストールチュートリアルを参照するか、LLMに完全なセットアップガイドを尋ねてください。
  • Slack Appを作成してOAuthトークンを取得する
Slack APIプラットフォームにアクセスし、Slack appをゼロから作成し、デプロイするワークスペースを選択します。
  1. Webhooksを有効にする:
  1. Slackワークスペースにアプリをインストールする:
  1. 将来のプラグイン開発のためにOAuthトークンを取得する

1. プラグインの開発

ここから実際のコーディングに入ります。開始する前に、クイックスタート:拡張プラグインの開発を読んでいるか、すでにDifyプラグインを構築した経験があることを確認してください。

1.1 プロジェクトの初期化

以下のコマンドを実行して、プラグイン開発環境をセットアップします:
dify plugin init
プロンプトに従って基本的なプロジェクト情報を入力します。extensionテンプレートを選択し、AppsEndpointsの両方の権限を付与します。 プラグイン内でDifyサービスを逆呼び出しする方法の詳細については、逆呼び出し:Appを参照してください。 Plugins permission

1.2 設定フォームの編集

このプラグインは、どのDifyアプリが応答を処理するか、およびBotの応答を認証するためのSlack Appトークンを知る必要があります。そのため、プラグインのフォームにこれら2つのフィールドを追加します。 groupディレクトリ内のYAMLファイルを修正します。例えば、group/slack.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に設定すると、プラグインはエージェント、チャットボット、またはchatflowなどのアプリタイプとのみやり取りできます。
最後に、endpoints/slack.yamlファイルで、受信するSlackメッセージを適切に処理するためにリクエストメソッドを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")

2. プラグインのデバッグ

Difyプラットフォームに移動し、プラグインのリモートデバッグアドレスとキーを取得します。 プラグインプロジェクトに戻り、.env.exampleファイルをコピーして.envにリネームします。
INSTALL_METHOD=remote
REMOTE_INSTALL_URL=debug.dify.ai:5003
REMOTE_INSTALL_KEY=********-****-****-****-************
python -m mainを実行してプラグインを起動します。Difyのプラグイン管理ページで、ワークスペースにプラグインがインストールされているのが確認できるはずです。他のチームメンバーもアクセスできるようになります。
python -m main

プラグインエンドポイントの設定

Difyのプラグイン管理ページから、新しくインストールされたテストプラグインを見つけ、新しいエンドポイントを作成します。名前、Botトークンを入力し、接続するアプリを選択します。 Test Plugins 保存後、POSTリクエストURLが生成されます: Generated POST Request URL 次に、Slack Appのセットアップを完了します:
  1. Event Subscriptionsを有効にする 上記で生成したPOSTリクエストURLを貼り付けます。
  2. 必要な権限を付与する

3. プラグインの検証

コード内で、self.session.app.chat.invokeがDifyアプリケーションを呼び出すために使用され、app_idqueryなどのパラメータを渡します。応答はSlack Botに返されます。python -m mainを再度実行してプラグインをデバッグ用に再起動し、SlackがDify Appの応答を正しく表示するかどうかを確認します:

4. プラグインのパッケージ化(オプション)

プラグインが正しく動作することを確認したら、以下のコマンドでパッケージ化して名前を付けることができます。実行後、現在のディレクトリにslack_bot.difypkgファイルが作成されます。これが最終的なプラグインパッケージです。詳細なパッケージ化手順については、ローカルファイルとしてパッケージ化して共有を参照してください。
# ./slack_botを実際のプラグインプロジェクトパスに置き換えてください。

dify plugin package ./slack_bot
おめでとうございます!プラグインの開発、テスト、パッケージ化が正常に完了しました!

5. プラグインの公開(オプション)

Dify Marketplaceリポジトリにアップロードして公開できます。公開前に、プラグインがDify Marketplace公開ガイドラインに準拠していることを確認してください。承認されると、コードはメインブランチにマージされ、プラグインはDify Marketplaceで公開されます。

関連リソース

さらに読む

完全なDifyプラグインプロジェクトの例については、GitHubリポジトリをご覧ください。完全なソースコードと実装の詳細を含む追加のプラグインも見つかります。 プラグイン開発についてさらに探求したい場合は、以下を確認してください: クイックスタート: プラグインインターフェースドキュメント:
Edit this page | Report an issue