
取引先とのメールのやり取りを、AIが自動で要約して自社アプリ「ビヨンドウェブ」のトークに投稿する仕組みを、ノーコードで作成しました。 受信箱を開かなくても、チーム全員が状況を把握できます。 今回はGmailですが、同じ仕組みでLINEやSlackの内容もトークに自動投稿できます。 プログラミングの知識がなくても、コピペと設定だけで動かせます。
取引先とのメールのやり取りを、AIが自動で要約して、社内チャットに投稿してくれる仕組みを作ります。プログラミングの知識がなくても、手順どおりにコピペ+設定するだけで動かせます。
たとえば、こんな投稿が自動で流れてきます。
【相手・受信】展示会の御礼
・◯日14時に本社訪問の依頼
・訪問者は2名予定
【自分のアクション】
・◯日14時に訪問する旨を返信
受信したメールも、自分が送ったメールも、会社ごとにまとまってチャットに残ります。受信箱を開かなくても、チーム全員が状況を把握できるようになります。
メールは「担当者の受信箱の中」に閉じてしまいがちです。その結果、
チームに状況が共有されない
担当者が休むと経緯がわからない
「あの件どうなった?」が口頭頼み
この仕組みは、そんな“メールの中に埋もれた情報”を、自動でチームの見える場所に出してくれます。
登場するのは2つの道具です。
GAS(ガス):Gmailを5分おきに見張る「見張り役」。新しいメールを見つけて次に渡します。(Googleの無料ツール)
Dify(ディファイ):渡されたメールを「要約して、どこに投稿するか決めて、実際に投稿する」までやる「判断役」。(AIを組み込めるノーコードツール)
「見張りはGAS、判断はDify」と覚えればOKです。下の2枚の図が全体像です。


作り始める前に、次を用意します。特に③のコンタクト登録が、この仕組みの“要”です。
Difyのアカウントと、AIを使うためのAPIキー(OpenAIなど)
Googleアカウント(GASを動かすため/Gmailを見張るため)
CRM(コンタクト)に取引先を登録しておく ← 最重要
この仕組みは、CRMにメールアドレスが登録されている取引先とのメールだけを自動投稿します。
逆に言うと、登録していない相手のメールは投稿されません(私的なメールや迷惑メールが自動で除外される、という安全装置にもなります)。
なので「チャットに流したい取引先は、先にCRMのコンタクトに登録しておく」必要があります。
管理者アカウント(チャットやCRMのデータを操作するため)
ポイント:コンタクト登録=この仕組みの“通行許可証”です。登録されている相手だけが通れます。
API:道具どうしが会話するための“窓口”。
トークン:その窓口に入るための“一時的な合言葉”。
ノード:Difyで並べる“処理のブロック”。線でつなぐと流れになります。
トリガー:GASを「5分おきに自動で動かす」ためのタイマー。
Difyは、ブロック(ノード)を並べて線でつなぐだけで作れます。コードが出てくる場所もありますが、中身は分からなくてOK。コピペして貼るだけです。
GASから渡される情報の“受け皿”を作ります。次の6つを登録します。
メールの向き(受信か送信か)
相手のメールアドレス
件名
本文
メールのまとまりを表すID
前回の投稿先 (任意)
上から下へ、この順で並べます。
ログイン:チャット側の合言葉(トークン)をもらう
トークン取り出し:もらった合言葉を取り出す(コピペのコード)
CRM照合:相手がCRMに登録されているか調べる
一致確認:登録されていれば“会社”を特定(コピペのコード)
判定A:登録されていなければ、ここで終了(投稿しない)
判定B:すでに投稿先が分かっている続きの会話なら、振り分けをスキップ
トピック一覧取得:その会社の“開いている”投稿先を取得
振り分け(AI):既存の場所に足すか、新しく作るかをAIが判断
判定パース:AIの答えを整える(コピペのコード)
判定C:新規なら「新しい投稿先を作る」へ
新規作成:新しい投稿先を作る
新規ID取り出し:作った投稿先の番号を取り出す(コピペのコード)
集約:投稿先を1つに決める
要約(AI):投稿用に短くまとめる(受信/送信で書き分け)
投稿:チャットに投稿する
終了:投稿した/しなかった
4か所に小さなコードを貼ります。意味を理解する必要はありません。 ただし1つだけ約束ごとがあります。
入力の名前と、コードの中の名前をそろえること。 たとえば入力を
bodyという名前にしたら、コードもbodyを使います。1文字でも違うと動きません。
トークン取り出し(入力名:body)
def main(body: str) -> dict:
import json
return { "token": json.loads(body)["access_token"] }一致確認(入力名:records_json / target)
def main(records_json: str, target: str) -> dict:
import json
try:
data = json.loads(records_json)
except Exception:
return { "matched": 0, "company_id": 0 }
t = (target or "").strip().lower()
for c in data.get("records", []):
if (c.get("email") or "").strip().lower() == t and c.get("company_id"):
return { "matched": 1, "company_id": c["company_id"] }
return { "matched": 0, "company_id": 0 }判定パース(入力名:llm_text)
def main(llm_text: str) -> dict:
import json, re
try:
m = re.search(r"\{.*\}", llm_text, re.S)
d = json.loads(m.group(0)) if m else { }
except Exception:
d = {}
return {
"action": d.get("action", "append"),
"topic_id": int(d.get("topic_id") or 0),
"new_title": d.get("new_title") or "",
}新規ID取り出し(入力名:body)
def main(body: str) -> dict:
import json
try:
return { "new_topic_id": int(json.loads(body).get("id", 0)) }
except Exception:
return { "new_topic_id": 0 }振り分け:「件名・本文と、候補の一覧を見て、既存に足すか・新しく作るかを答えて」と指示。似た話題なら既存へ、明らかに別件なら新規。
要約:受信なら「相手の要点・依頼・期限」、自分の送信なら「自分が何を返信・提案したか」を箇条書きで。
作り終えたら、必ず**「公開」ボタンを押す**こと。Difyは「公開した状態」で動くので、直しても公開しないと反映されません。「直したのに動かない」の9割はこれです。
Googleの「Apps Script(script.google.com)」で新規プロジェクトを作ります。
Difyで作ったワークフローを公開し、「APIアクセス」から APIキー(app-で始まる文字列)をコピーします。
最初から入っている文字を全部消して、下を貼り付けます。先頭の4行だけ自分の情報に書き換えればOKです。
const DIFY_URL = 'https://api.dify.ai/v1/workflows/run';
const DIFY_KEY = 'app-xxxxxxxx'; // DifyのAPIキー
const MY_EMAIL = 'you@yourcompany.co.jp'; // 自分のメール
const MY_DOMAIN = 'yourcompany.co.jp'; // 自社のドメイン(社内を除外)
function poll() {
const props = PropertiesService.getScriptProperties();
const lastRun = Number(props.getProperty('lastRun') || (Date.now() - 864e5));
const threads = GmailApp.search(in: inbox OR in: sent) after: ${ Math.floor(lastRun / 1000)
});
let newest = lastRun;
threads.forEach(thread => {
const known = props.getProperty('map_' + thread.getId());
thread.getMessages().forEach(msg => {
const t = msg.getDate().getTime();
if (t <= lastRun) return;
if (t > newest) newest = t;
const isSent = (msg.getFrom() || '').toLowerCase().includes(MY_EMAIL);
const external = pickExternal([msg.getFrom(), msg.getTo(), msg.getCc()].join(','));
if (!external) return;
const payload = {
inputs: {
direction: isSent ? 'sent' : 'received',
external_email: external,
subject: msg.getSubject() || '',
body: (msg.getPlainBody() || '').slice(0, 4000),
thread_id: thread.getId(),
known_topic_id: known ? Number(known) : 0
}, response_mode: 'blocking', user: 'gmail-poller'
};
const res = UrlFetchApp.fetch(DIFY_URL, {
method: 'post', contentType: 'application/json',
headers: { Authorization: 'Bearer ' + DIFY_KEY }, payload: JSON.stringify(payload), muteHttpExceptions: true
});
const out = JSON.parse(res.getContentText());
const topicId = out.data && out.data.outputs ? out.data.outputs.topic_id : 0;
if (topicId > 0) props.setProperty('map_' + thread.getId(), String(topicId));
});
});
props.setProperty('lastRun', String(newest));
}
// メールの宛先・差出人・CCから「社外の相手」を見つける(CCの取引先も拾える)
function pickExternal(s) {
const emails = ((s || '').match(/[\w.+-]+@[\w.-]+\.[\w.-]+/g) || []).map(e => e.toLowerCase());
return emails.find(e => (e.split('@')[1] || '') !== MY_DOMAIN) || '';
}
// 最初に1回だけ実行:過去のメールをまとめて処理しないようにする
function startFresh() {
PropertiesService.getScriptProperties().setProperty('lastRun', String(Date.now()));
}
4. 最初の1回を実行(権限の許可)
関数を poll にして「実行」を押します。初回は Gmailを読む許可などを求められるので、画面の案内に従って許可します。過去のメールを一気に処理したくない場合は、先に startFresh を1回実行しておきます。
ここが“自動化”の本体です。画面左の**時計マーク(トリガー)**を開き、「トリガーを追加」で次のように設定して保存します。
実行する関数:poll
イベントのソース:時間主導型
タイプ:分ベースのタイマー
間隔:5分おき
これで完成です。初回は約5分後から動き始めます(数分前後することがあります)。
自動実行の記録は、画面左の**「実行数」**で見られます。
新しいメールが無いときは一瞬で終わります(正常です)。実際の投稿を試したいときは、CRMに登録済みの取引先と本当にメールをやり取りしてみてください。
直したのに反映されない → Difyで「公開」を押し忘れている
403や401で止まる → 合言葉(トークン)や設定の打ち間違い。特に英単語のスペルに注意(Authorization など)
何も投稿されない → 相手がCRMに未登録(=対象外。正常な動作)/新着メールがまだ無い
コードのブロックでエラー → 入力の名前とコードの名前がズレている
流したい取引先は、先にCRMのコンタクトに登録しておく(これが対象の線引き)。
続きの会話は同じ場所にまとまるので、トピックが散らかりません。
CCの取引先や自分の送信メールも拾えます。
メールの中に閉じた情報を、チームの見える場所へ。これをプログラミングなしで実現できます。ポイントは2つだけ。
CRMに取引先を登録しておく(通行許可証)
見張り役(GAS)と判断役(Dify)を用意してつなぐ
あとは手順どおりにコピペと設定をすれば、メールが自動でチャットにまとまっていきます。
この商品について質問がありますか?コミュニティや専門家に質問してください。