【保存版】DifyとSlackを連携させてAIチャットボットを作ろう!

今回は「Slack」と「Dify」を連携させて、Slack内で使えるチャットボットを作成してみましょう。DMまたは招待されたチャンネルのメンションに反応する仕組みで、あくまでも簡易的なチャットボットの認識でお願いします。

20分程度で簡単に作れるので、AIサービスを使って何かしらの業務改善がしたい…という場合に役立ててみてください。

>>ホワイトペーパー「AIを組み込んだシステム開発の事例」をダウンロードする

\ ホワイトペーパー /
貴社のPowerApps導入をぐっと前に進めるための
資料3点セット

【下記の3点の資料が無料でダウンロードできます】

  • Powe Apps 活用事例集
  • 【MS365で使える範囲も分かる】PowerAppsのライセンス早見表
  • 【担当者のスキルレベルや導入の進め方から判断!】PowerPlatformで内製化をすすめるためのロードマップ
目次

Dify(ディファイ)って?

Difyとは、大規模言語モデルを用いて、AI機能を持ったアプリをプログラミング不要で開発できるツールです。 特定のタスクや目的を達成するために動作するAIエージェントや、複雑な処理を行うAIモデルなどをノーコードで作れます。

だれでもAIツール、AIエージェントを作れるというのが大きな魅力。専門的な知識を持つAIエンジニアがいなくても、用途に応じたさまざまな生成AIアプリを作れてしまうんです。

Slack×Dify連携において必要なモノ

  • Google アカウント
  • Slack ワークスペースの管理者権限
  • Difyアカウント

DifyとSlackを連携させる手順

Google Apps Scriptのプロジェクト作成

Google Apps Script(GAS)にアクセスしましょう。「新しいプロジェクト」をクリックして作成。

エディタが表示されるので、もとからあるコードを削除して以下のコードを貼り付けてください。

クリックしてコードを表示
//----------
// 定数
//----------
const DIFY_API_ENDPOINT = 'https://api.dify.ai/v1/chat-messages';
const SLACK_API_BASE = 'https://slack.com/api';

//----------
// イベントの重複の対処
//----------
function isEventProcessed(eventId, eventTime) {
  const cache = CacheService.getScriptCache();
  const key = `processed_event_${eventId}`;

  // イベントが既に処理済みか確認
  if (cache.get(key)) {
    console.log(`重複イベント検出: ${eventId}`);
    return true;
  }

  // 古すぎるイベントはスキップ(3分以上前のイベント)
  const currentTime = Math.floor(Date.now() / 1000);
  if (currentTime - eventTime > 180) {
    console.log(`古いイベントをスキップ: ${eventId}`);
    return true;
  }

  // イベントを処理済みとしてマーク(10分間保持)
  cache.put(key, 'true', 600);
  return false;
}

//----------
// Difyの統合
//----------
function callDifyAPI(userMessage, slackUserId) {
  const apiKey = PropertiesService.getScriptProperties().getProperty('DIFY_API_KEY');
  if (!apiKey) {
    throw new Error('Dify APIキーがスクリプトプロパティに設定されていません');
  }

  const options = {
    method: 'post',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify({
      inputs: {},
      query: userMessage,
      user: slackUserId,
      response_mode: 'blocking',
      conversation_id: null
    }),
    muteHttpExceptions: true
  };

  try {
    const response = UrlFetchApp.fetch(DIFY_API_ENDPOINT, options);
    const responseData = JSON.parse(response.getContentText());

    if (response.getResponseCode() !== 200) {
      console.error('Dify APIエラー:', responseData);
      throw new Error(`Dify APIからエラーが返されました: ${response.getResponseCode()}`);
    }

    return responseData.answer;
  } catch (error) {
    console.error('Dify API呼び出しエラー:', error);
    throw error;
  }
}

//----------
// イベントハンドラー
//----------
function doPost(e) {
  try {
    console.log('受信したイベント:', e.postData.contents);
    const data = JSON.parse(e.postData.contents);

    // URL検証リクエストへの対応
    if (data.type === 'url_verification') {
      return ContentService.createTextOutput(data.challenge);
    }

    // イベントの処理
    if (data.event && data.event_id) {
      if (isEventProcessed(data.event_id, data.event_time)) {
        return ContentService.createTextOutput('duplicate');
      }

      console.log('イベントタイプ:', data.event.type);

      switch (data.event.type) {
        case 'app_mention':
          handleMention(data.event);
          break;
        case 'message':
          if (data.event.channel_type === 'im') {
            handleDirectMessage(data.event);
          }
          break;
      }
    }

    return ContentService.createTextOutput('ok');
  } catch (error) {
    console.error('doPostでエラーが発生:', error);
    return ContentService.createTextOutput('error');
  }
}

function handleMention(event) {
  try {
    if (event.bot_id || event.subtype === 'bot_message') {
      return;
    }

    const userMessage = event.text.replace(/<@[A-Z0-9]+>/g, '').trim();
    const difyResponse = callDifyAPI(userMessage, event.user);

    const message = {
      channel: event.channel,
      text: difyResponse,
      thread_ts: event.thread_ts || event.ts
    };

    sendSlackMessage(message);
    console.log('メンションに応答しました (Dify統合)');
  } catch (error) {
    console.error('メンション処理でエラーが発生:', error);
    const errorMessage = {
      channel: event.channel,
      text: "申し訳ありません。現在応答に問題が発生しています。しばらく経ってから再度お試しください。",
      thread_ts: event.thread_ts || event.ts
    };
    sendSlackMessage(errorMessage);
  }
}

function handleDirectMessage(event) {
  try {
    if (event.bot_id || event.subtype === 'bot_message') {
      return;
    }

    const difyResponse = callDifyAPI(event.text, event.user);

    const message = {
      channel: event.channel,
      text: difyResponse,
      thread_ts: event.thread_ts || event.ts
    };

    sendSlackMessage(message);
    console.log('ダイレクトメッセージに応答しました (Dify統合)');
  } catch (error) {
    console.error('DM処理でエラーが発生:', error);
    const errorMessage = {
      channel: event.channel,
      text: "申し訳ありません。現在応答に問題が発生しています。しばらく経ってから再度お試しください。",
      thread_ts: event.thread_ts || event.ts
    };
    sendSlackMessage(errorMessage);
  }
}

function sendSlackMessage(message) {
  const token = PropertiesService.getScriptProperties().getProperty('SLACK_BOT_TOKEN');
  const options = {
    method: 'post',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    payload: JSON.stringify(message),
    muteHttpExceptions: true
  };

  try {
    const response = UrlFetchApp.fetch(`${SLACK_API_BASE}/chat.postMessage`, options);
    const responseData = JSON.parse(response.getContentText());
    console.log('メッセージ送信結果:', JSON.stringify(responseData));

    if (!responseData.ok) {
      throw new Error(`Slack APIエラー: ${responseData.error}`);
    }
  } catch (error) {
    console.error('メッセージ送信でエラーが発生:', error);
    throw error;
  }
}

特に編集とかしなくてよいので、デプロイ 新しいデプロイ ウェブアプリの順にクリック。

また、以下の感じで設定してください。

  • 説明: 任意のものを記入してください(空欄でもOK)
  • 次のユーザーとして実行: 「自分
  • アクセスできるユーザー: 「全員

あとはアクセス承認の確認が来るので「承認」を押しましょう。ウェブアプリのURLをどこかにコピーしておいてください。

Slackの連携

slack apiにアクセス。Create an appからFrom a manifestを選んでください。

どのワークスペースにアプリをインストールするか聞かれるので、任意のワークスペースで。

その次はJSONタイプを選び、以下のコードをペーストします。、

クリックしてコードを表示

{
“display_information”: {
“name”: “Slack App上で表示される名前”,
“description”: “Slack App上で表示される説明”,
“background_color”: “#000000”
},
“features”: {
“bot_user”: {
“display_name”: “Slackで表示されるアプリ名”,
“always_online”: true
},
“app_home”: {
“home_tab_enabled”: true,
“messages_tab_enabled”: true,
“messages_tab_read_only_enabled”: false
}
},
“oauth_config”: {
“scopes”: {
“bot”: [
“app_mentions:read”,
“channels:history”,
“channels:read”,
“chat:write”,
“im:history”,
“im:read”,
“im:write”,
“reactions:read”,
“reactions:write”,
“team:read”,
“users:read”,
“users:read.email”,
“channels:join”
]
}
},
“settings”: {
“event_subscriptions”: {
“request_url”: “YOUR_GAS_WEBAPP_URL”,
“bot_events”: [
“app_mention”,
“message.channels”,
“message.im”,
“reaction_added”,
“reaction_removed”
]
},
“interactivity”: {
“is_enabled”: true,
“request_url”: “YOUR_GAS_WEBAPP_URL”
},
“org_deploy_enabled”: false,
“socket_mode_enabled”: false,
“token_rotation_enabled”: false
}
}

「Slack App上で表示される名前」「Slack App上で表示される説明」は任意のものを入力してください。

「Slackで表示されるアプリ名」も任意で構いませんが、英語で入力しましょう。「YOUR_GAS_WEBAPP_URL」には、先ほど取得したウェブアプリのURLを入力。

ダブルクォーテーション(””)の間に入力することを忘れずに。

エラーが出たら

URLを確認してください~見たいなエラーが出る場合がありますが、その場合「URLを確認する」みたいな箇所をクリックすると治るかと思います。

それでも治らない場合は、GASのデプロイの設定でアクセスできるユーザーの設定が「全員」になっていることを確認してください。筆者はこの辺りで詰まりました。

次はOAuth & Permissionsを選択し、「Install to ワークスペース名」をクリック。

許可するか?と聞かれるので許可してください。

Bot User OAuth Tokensの値をコピーして控えておきましょう。

Dify側の設定

Difyのダッシュボードにログインし、アプリケーションを新規作成します。作成する際は、DSLからインポートを選択。以下のファイルをドラッグしてください。

>>Dify用チャットフロー

APIアクセス → 右上にある「APIキー」に行き、新しいシークレットキーを作成を押します。すると、以下のようにAPIキーが発行されるのでこれも控えておきましょう。

GASの設定

GASに戻り、プロジェクトの設定から「スクリプトプロパティの設定」に行きます。

  • プロパティ名: SLACK_BOT_TOKEN
    • 値: xoxb-… (控えたBot User OAuth Token)
  • プロパティ名: DIFY_API_KEY
    • 値: (控えたDifyのAPIキー)

こんな感じで設定してください。

最後にデプロイを新バージョンに更新して終わりです。

適当にslack内でスレッドを作り「/Invite @dify_slack」で呼び出してみましょう。エラーがなければこんな感じで返してくれます。

まとめ

今回はSlack×Difyでの簡易的なチャットボットを作成してみました。

ここからの発展としては、Difyで議事録を学習したチャットボットを作成して、Slackのチャンネル内に入れる…なんてことも可能です。どんどんAI技術が発展する昨今、AI活用の波に乗り遅れないようにしたいですね。

弊社ではAI関連のシステム・アプリ開発を支援しており、過去に開発したサービスだとChatGPTを活用したAI英会話アプリがあります。AI活用セミナーも積極的に登壇しているので、AIを使って何かしらのサービスが作りたい!という方はぜひご相談ください。

>>ChatGPTを活用した英会話アプリ「AI英会話さん」

>>お問い合わせはこちらから

\ システム開発にお悩みの方へ /
貴社のシステム開発・アプリ開発を爆速で進めるための
超高速開発が分かる資料3点セット

【下記の3点の資料が無料でダウンロードできます】

  • 【料金表付き】新規事業を爆速で立ち上げられる高速開発支援サービスの紹介資料
  • 【最短24時間で納品?】高速開発のプロジェクト支援事例集
  • 導入に向けて開発プラットフォームのランニングコスト比較表
  • URLをコピーしました!

お役立ち資料



資料請求はこちら

資料請求

無料デモアプリはこちら

無料で作成依頼
目次