1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【n8n×ChatGPT】地球の裏側(ペルー)で働くために。寝ている間にSlackとメールを要約・下書きしてくれる「影のAI秘書」を構築した

1
Last updated at Posted at 2026-02-18

unnamed-2.jpg

はじめに:時差14時間の壁に挑む

来年、仕事とVR撮影を兼ねて ペルー(マチュピチュなど) へ渡航します。
非常に楽しみな反面、経営者兼エンジニアとして最大の懸念があります。

「時差14時間の壁」 です。

日本のビジネスタイム(9:00〜18:00)は、ペルーの深夜(19:00〜翌4:00)。
私がぐっすり寝ている間に、クライアントからの緊急連絡やSlackのメンションが飛び交うことになります。

「海外にいるので返信遅れます」と言うのは簡単ですが、それでは信頼残高が減る一方です。
そこで私は考えました。

「私が寝ている間、私の代わりに一次対応をしてくれる『影のAI秘書』を作ればいいじゃないか」

今回は、n8n と OpenAI API、そして Slack Block Kit を駆使して構築した、完全非同期型のコミュニケーションシステムを紹介します。


アーキテクチャ:「Shadow AI Secretary」の全貌

ただの自動応答bot(Auto-reply)ではありません。
**「読んで、判断して、下書きを作って、私の承認を待つ」**というフローを組みました。


実装のポイント①:AIによる「重要度判定」と「要約」

すべての通知を受け取っていては、せっかくの海外滞在が台無しです。
n8nのワークフロー内で、GPT-4oに以下のようなプロンプトを投げてフィルタリングします。

// Code Node内のプロンプト構築
const prompt = `
あなたは山本(私)の秘書です。以下のメッセージを分析してください。

【メッセージ内容】
${incomingMessage}

【出力フォーマット】
- urgency: "High" | "Medium" | "Low"
- category: "ClientWork" | "DevTeam" | "Misc"
- summary: 30文字以内で要約
- draft_reply: 山本の口調(丁寧だが簡潔)で返信案を作成

【判定基準】
- サーバーダウン、納期遅延に関わるものは "High"
- 雑談や参考共有は "Low"
`;

// OpenAI APIへ送信
const response = await $httpRequest({
  method: 'POST',
  url: 'https://api.openai.com/v1/chat/completions',
  headers: {
    'Authorization': `Bearer ${OPENAI_API_KEY}`,
    'Content-Type': 'application/json'
  },
  body: {
    model: 'gpt-4o',
    messages: [{ role: 'user', content: prompt }],
    response_format: { type: 'json_object' }
  }
});

これにより、「サーバー落ちてます!」は即座にLINE通知(叩き起こす)、「デザイン確認お願いします」は翌朝のダイジェスト行き、という振り分けが可能になります。

重要度 判定基準 処理
High サーバーダウン、セキュリティ事故、納期遅延 即座にLINE通知(2重通知)
Medium 仕様相談、承認依頼、MTG調整 翌朝のダイジェストSlackに含める
Low 雑談、情報共有 (スルーまたは日報に記載)

実装のポイント②:「私の口調」を憑依させる(Few-shot)

AIが作った返信文が「ロボットっぽい」と、クライアントに失礼になります。
そこで、Few-shot Learning(少数の例示) を使います。

const systemPrompt = `
あなたは山本勇志です。以下の過去の返信例を参考に、口調を模倣してください。

【例1: クライアント対応】
入力: "進捗状況を教えてください"
出力: "承知いたしました。本日夕方までに現状と次のステップをご共有いたします。"

【例2: チーム内連絡】
入力: "明日のMTG空いてますか?"
出力: "ありがとうございます!午前中でしたら参加可能です。議題シェアお願いします。"

【例3: 緊急時の謝意】
入力: "サーバー落ちました"
出力: "申し訳ありません、現在移動中のため、15分後に対応します。恐れ入りますが少々お待ちください。"

【指示】
上記の口調(丁寧だが簡潔、絵文字は控えめ、ビジネスライク)を守りつつ、以下のメッセージに対する返信案を作成してください。
`;

const userPrompt = `
相手: ${senderName}
内容: ${messageContent}
文脈: ${contextSummary}
`;

これを噛ませるだけで、驚くほど「自分っぽい」返信ドラフトが出来上がります。
ポイント: 実際の過去のSlackログを10件ほど抽出し、JSONL形式で few-shots として持たせることで、より精度が上がります。


実装のポイント③:Slack Block Kit で「承認ボタン」を作る

ここがUXの肝です。
朝起きてSlackを見ると、AI秘書から以下のようなリッチなカードが届いています。

このインターフェースは Slack Block Kit でJSONを組み、n8nから chat.postMessage または webhook 経由でPOSTしています。

{
  "blocks": [
    {
      "type": "header",
      "text": {
        "type": "plain_text",
        "text": "📬 昨夜の未読まとめ(3件)",
        "emoji": true
      }
    },
    {
      "type": "section",
      "fields": [
        {
          "type": "mrkdwn",
          "text": "*件名:* 〇〇案件のAPI仕様について\n*差出人:* A社 佐藤様\n*緊急度:* Medium"
        }
      ]
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*要約:* 仕様変更の相談。来週までに回答が欲しいとのこと。"
      }
    },
    {
      "type": "section",
      "text": {
        "type": "mrkdwn",
        "text": "*🤖 AI作成の返信案:*\n> 佐藤様、ご連絡ありがとうございます。仕様変更の件、確認いたしました。ペルー滞在中のため、恐れ入りますが日本時間の明日午前中に詳細を回答させていただきます。"
      }
    },
    {
      "type": "actions",
      "elements": [
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "✅ そのまますぐ送信",
            "emoji": true
          },
          "style": "primary",
          "value": "send_as_is_${messageId}",
          "action_id": "action_send"
        },
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "✏️ 修正して送信",
            "emoji": true
          },
          "value": "edit_${messageId}",
          "action_id": "action_edit"
        },
        {
          "type": "button",
          "text": {
            "type": "plain_text",
            "text": "🗑️ 破棄",
            "emoji": true
          },
          "style": "danger",
          "value": "discard_${messageId}",
          "action_id": "action_discard"
        }
      ]
    },
    {
      "type": "divider"
    }
  ]
}

ボタンアクションの処理

ボタンを押すと、n8nの Webhook が叩かれ、GmailやSlack API経由で実際にメッセージが送信されます。

// n8n Webhook 受信後の処理(簡略)
const action = $input.first().json.body.actions[0];
const messageId = action.value.split('_')[2]; // messageIdを抽出
const actionType = action.action_id; // action_send, action_edit, action_discard

// Notionから保存済みの下書きを取得
const draft = await notion.pages.retrieve({ page_id: messageId });

if (actionType === 'action_send') {
  // Gmailで送信
  await gmail.users.messages.send({
    userId: 'me',
    requestBody: {
      raw: createEmailRaw(draft.properties)
    }
  });
  
  // Slackに通知
  await slack.chat.postMessage({
    channel: '#general',
    text: `✅ 自動送信完了: ${draft.properties.title}`
  });
  
} else if (actionType === 'action_edit') {
  // 編集用のモーダルを開く(Slack Modal API)
  await slack.views.open({
    trigger_id: triggerId,
    view: createEditModal(draft)
  });
}

私は寝起きにコーヒーを飲みながら、「送信ボタン」をポチポチ押すだけで、昨夜のタスク処理が完了します。


まとめ:距離は技術で超えられる

「海外に行くと仕事が止まる」というのは、同期コミュニケーション(電話・会議)に頼っているからです。
非同期コミュニケーションの質を技術で高めれば、地球の裏側にいても、まるで隣の席にいるかのように仕事を回すことができます。

構築にかかった時間とコスト

項目 時間 備考
設計 2時間 フローチャート作成
n8n構築 4時間 プロンプト調整込み
Slack UI調整 2時間 Block Kitの微調整
合計 8時間 初回構築のみ

運用コスト(月額):

  • n8n Cloud: ¥2,500
  • OpenAI API: ¥1,500程度(通知量による)
  • 合計: ¥4,000/月(時差対応人件費の1/100以下)

このシステムのおかげで、私は安心してマチュピチュの頂上で深呼吸ができそうです。

もし「自分も海外で働きたいけど、連絡が不安」という方がいれば、ぜひ n8n × LLM で自分だけの影武者を作ってみてください。


🔗 参考リンク

この記事を書いた人✏️

@YushiYamamoto

株式会社プロドウガ CEO / AIアーキテクト
Next.js / TypeScript / n8nを活用した自律型アーキテクチャ設計を専門としています。
日々の自動化の検証結果や、ビジネス側の視点(ROI等)に関するより深い考察は、以下の公式サイトおよびnoteで発信しています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?