شروع کار
راهنمای توسعهدهندگان آیفریم
موچت را داخل وبسایت یا WebView نمایش دهید؛ با JWT کاربران را شناسایی کنید، نشست مهمان را مدیریت کنید و اطلاعات صفحه را با فرمانهای پشتیبانیشدهٔ آیفریم بفرستید.
آیفریم، موچت را مستقیماً داخل صفحهٔ شما قرار میدهد. گفتگو بدون حباب شناور و در فضایی که برایش تعیین کردهاید باز میماند. بازدیدکنندگان میتوانند بدون ترک صفحه پاسخ بگیرند، فرمها را تکمیل کنند و از قابلیتهایی استفاده کنند که در داشبورد فعال کردهاید.
برای گفتگوی مهمان، همان تگ آیفریم کافی است. اگر میخواهید کاربر واردشده را شناسایی کنید، گفتگوی مهمان تازهای شروع کنید یا اطلاعات صفحهٔ جاری را به موچت بدهید، کد اتصال این صفحه را هم اضافه کنید. آیفریم قرارداد postMessage مستقل دارد؛ متدهای window.$muchat مربوط به نصب حباب گفتگو هستند.
چه زمانی از آیفریم استفاده کنید
در این موارد از آیفریم استفاده کنید:
- گفتگو در بخشی از مرکز راهنما، پنلی در داشبورد یا صفحهٔ اختصاصی پشتیبانی قرار میگیرد.
- میخواهید عرض، ارتفاع و چیدمان اطراف گفتگو را خودتان کنترل کنید.
- پلتفرم شما آیفریم را میپذیرد، اما برای اسکریپتهای نصب شخص ثالث محدودیت دارد.
- میخواهید صفحهٔ پشتیبانی وب را در WebView اپلیکیشن موبایل نمایش دهید.
برای دکمهٔ شناور، از حباب گفتگو استفاده کنید. اگر بهجای قراردادن گفتگو در سایت خود، میخواهید یک لینک جداگانه به اشتراک بگذارید، صفحهٔ مستقل را انتخاب کنید.
شروع سریع
کد آیفریم را کپی کنید
- وارد داشبورد موچت شوید و موچت موردنظرتان را انتخاب کنید.
- به انتشار موچت بروید و در کارت ویجت چت، روی مدیریت بزنید.
- بالای پیشنمایش، انتشار و سپس آیفریم وبسایت را انتخاب کنید.
- کد HTML را کپی کنید و در محلی از صفحه بگذارید که میخواهید گفتگو نمایش داده شود.

اندازه را تنظیم و یک شناسه اضافه کنید
کد داشبورد، آیفریم را با عرض کامل و ارتفاع ۶۴۰ پیکسل نمایش میدهد. اندازهها را متناسب با چیدمان سایت تغییر دهید. اگر صفحه باید به آیفریم فرمان بفرستد، یک id اضافه کنید؛ اگر پیام صوتی فعال است، allow="microphone" را نگه دارید.
<iframe
id="muchat-iframe"
src="https://widget.mu.chat/iframe?website_token=YOUR_WEBSITE_TOKEN"
title="MuChat support"
allow="microphone"
style="width: 100%; height: 640px; border: 0"
></iframe>YOUR_WEBSITE_TOKEN را با مقدار پس از website_token= در کد آیفریم داشبورد جایگزین کنید. این مقدار، شناسهٔ عمومی ویجت است؛ نه شناسهٔ موچت، کلید API گفتگو یا کلید محرمانهٔ امضای هویت کاربران.
در صورت نیاز، صفحه را متصل کنید
گفتگوی مهمان بدون JavaScript در صفحهٔ میزبان هم کار میکند. برای شناسایی کاربر، بازنشانی مهمان یا انتقال اطلاعات صفحه، ابتدا کد اتصال را بارگذاری کنید؛ سپس این کد را بلافاصله بعد از آیفریم اجرا کنید:
const chat = connectMuchat(document.getElementById("muchat-iframe"));
chat.on("iframeReady", ({ ok, status }) => {
if (!ok) {
console.error("MuChat could not load", status);
return;
}
chat.send({ event: "initConfig", willIdentify: false });
console.info("MuChat is ready");
});این نمونه، نشست مهمان را شروع میکند. اگر دسترسی گفتگو را به کاربران واردشده محدود کردهاید، بهجای ارسال willIdentify: false از نمونهٔ شناسایی کاربر استفاده کنید.
اتصال را آزمایش کنید
صفحه را باز کنید و از داخل آیفریم سؤالی بفرستید. دریافت پاسخ و اندازهٔ مناسب گفتگو را در دسکتاپ و موبایل بررسی کنید. اگر کد اتصال را اضافه کرده باشید، آمادهشدن آیفریم در کنسول مرورگر هم اعلام میشود.
اتصال به آیفریم
این تابع را با نام connect-muchat.js ذخیره کنید یا پیش از کد نصب آیفریم، در یک اسکریپت قرار دهید. این تابع را خودتان به سایت اضافه میکنید؛ فایلی با این نام از سرور موچت بارگذاری نمیشود.
function connectMuchat(iframe) {
const origin = new URL(iframe.src).origin;
const prefix = "muchat-iframe:";
const handlers = {};
let markReady;
const ready = new Promise((resolve) => { markReady = resolve; });
function onMessage(event) {
if (event.source !== iframe.contentWindow || event.origin !== origin) return;
if (typeof event.data !== "string" || !event.data.startsWith(prefix)) return;
let message;
try {
message = JSON.parse(event.data.slice(prefix.length));
} catch { return; }
if (!message || typeof message.event !== "string") return;
const { event: type, ...data } = message;
if (type === "iframeReady" && data.ok) markReady(data);
for (const handler of handlers[type] ?? []) handler(data, message);
}
window.addEventListener("message", onMessage);
return {
ready,
send: (message) => ready.then(() => {
iframe.contentWindow.postMessage(prefix + JSON.stringify(message), origin);
}),
on: (type, handler) => (handlers[type] ??= []).push(handler),
disconnect: () => window.removeEventListener("message", onMessage)
};
}این کد چهار کار انجام میدهد:
- فرمانها را فقط به مبدأیی میفرستد که از
srcآیفریم خوانده میشود و برای رویدادهای دریافتی، هم پنجرهٔ فرستنده و هم مبدأ را بررسی میکند. - پیشوند
muchat-iframe:و محتوای JSON پیامهای آیفریم را آماده یا باز میکند. - فرمانهای خروجی را تا اولین رویداد موفق
iframeReadyنگه میدارد. - تابعهای ثبتشده را با فیلدهای رویداد بهعنوان آرگومان اول و پیام کاملِ بازشده بهعنوان آرگومان دوم فراخوانی میکند.
| API کد اتصال | کاربرد |
|---|---|
chat.ready | یک Promise که با اولین iframeReady دارای ok: true تکمیل میشود. |
chat.send(message) | پس از آمادگی اولیه، فرمان را ارسال میکند. تکمیل Promise به معنی ارسال است، نه تأیید اجرای موفق فرمان. |
chat.on(event, handler) | تابع دریافت یک رویداد را ثبت میکند. برای یک رویداد میتوانید چند تابع ثبت کنید. |
chat.disconnect() | شنوندهٔ پیامهای کد اتصال را حذف میکند؛ خود آیفریم را حذف نمیکند یا نمیبندد. |
اگر از ابزار بستهبندی ماژولها استفاده میکنید، پیش از function connectMuchat کلمهٔ export را اضافه کنید و تابع را در کامپوننت خود وارد کنید.
قواعد زمانبندی
- کد اتصال را پیش از اعلام
iframeReadyفعال کنید. در HTML ساده، ابتدا فایل تابع را بارگذاری کنید و بلافاصله پس از آیفریم، اتصال را بسازید. نمونهٔ React، شنوندهها را پیش از اضافهکردن آیفریم به صفحه ثبت میکند. - از
iframeReadyاستفاده کنید، نه رویدادloadآیفریم. بارگذاری سند به معنی آمادهبودن شنوندهٔ فرمانها نیست. - موچت در آیفریم ۱ ثانیه برای اولین
initConfigصبر میکند. آن را در تابع دریافتiframeReadyبفرستید. باwillIdentify: true، گفتگو منتظر شناسایی موفق کاربر میماند. باfalseیا نرسیدن تنظیم اولیه در این بازه، دسترسی مهمان تابع تنظیمات کانال است. initConfigدیرهنگام یا تکراری، تصمیم اولیه را تغییر نمیدهد. تنظیم اولیه را در تابع دریافت رویداد آمادگی قرار دهید تا برای هر سند تازهٔ آیفریم اجرا شود.- بازنشانی مهمان، آیفریم را دوباره بارگذاری میکند و
iframeReadyدوباره میرسد. Promise مربوط بهreadyپس از اولین موفقیت، تکمیلشده باقی میماند؛ برای راهاندازی سند تازه، از رویداد جدید استفاده کنید.
نشانههای آمادهشدن
| رویداد | معنی | کاربرد |
|---|---|---|
iframeReady با ok: true | آیفریم آمادهٔ دریافت فرمان است؛ این رویداد پایان نمایش گفتگو را تأیید نمیکند. | ارسال initConfig، set-user و change-url. |
user-identified با verified: true | سرور، JWT کاربر را پذیرفته و آیفریم نشست برگشتی را اعمال کرده است. | تأیید ورود در صفحه یا نمایش آیفریمی که عمداً پنهان کردهاید. |
error | شناسایی کاربر ناموفق بوده است. code خطا را مشخص میکند و در صورت وجود، status هم فرستاده میشود. | نمایش امکان تلاش دوباره یا دریافت توکن تازه. |
بدون کد اتصال
استفاده از کد اتصال اختیاری است، اما کد شما باید همین قرارداد را رعایت کند:
- منتظر پیامی از
contentWindowو مبدأ همان آیفریم بمانید. - فقط رشتههایی را بپذیرید که با
muchat-iframe:شروع میشوند و JSON پس از این پیشوند را بخوانید. - نام رویداد را از
eventبخوانید، نهtype. فیلدهای رویداد در شیء بازشده، کنارeventقرار دارند. - برای ارسال فرمان، پیشوند
muchat-iframe:را به ابتدایJSON.stringify(message)اضافه کنید و مبدأ آیفریم را بهعنوانtargetOriginقرار دهید.
شیء JavaScript خام یا پیشوند پیامهای ویجت شناور را نفرستید. آیفریم مستقیم، این قالبها را نادیده میگیرد.
کارهای رایج
در نمونههای زیر فرض شده است که از const chat = connectMuchat(iframe) در بخش اتصال به آیفریم استفاده کردهاید. جریان راهاندازی مناسب صفحهٔ خود را انتخاب کنید؛ چند تابع دریافت آمادگی با تنظیمات متناقض را همزمان ثبت نکنید.
شناسایی کاربر واردشده به حساب
initConfig را بلافاصله بفرستید؛ سپس JWT را از مسیر احراز هویتشدهٔ سرور خود دریافت کنید و با set-user بفرستید. با این ترتیب، گفتگو تا دریافت توکن منتظر میماند.
chat.on("iframeReady", async ({ ok }) => {
if (!ok) return;
await chat.send({ event: "initConfig", willIdentify: true });
try {
const response = await fetch("/api/muchat/user-token", {
credentials: "same-origin",
cache: "no-store"
});
if (!response.ok) throw new Error("Could not get the user token");
const { token } = await response.json();
if (typeof token !== "string" || !token.trim()) {
throw new Error("Missing user token");
}
await chat.send({ event: "set-user", user_jwt: token });
} catch (error) {
console.error("MuChat sign-in could not start", error);
}
});
chat.on("user-identified", ({ verified }) => {
console.info("MuChat user verified:", verified);
});
chat.on("error", ({ code, status }) => {
console.error("MuChat identification failed", code, status);
});/api/muchat/user-token مسیری است که خودتان در برنامهٔ خود پیادهسازی میکنید و برای کاربر واردشده، پاسخ { "token": "SIGNED_USER_JWT" } برمیگرداند؛ این مسیر، API موچت نیست. توکن را روی سرور و با کلید هویت ویجت امضا کنید.
نتیجه از طریق user-identified یا error میرسد؛ منتظرماندن برای chat.send، رسید تأیید هویت نیست. JWT حساب دیگر را پس از پایان تلاش جاری برای شناسایی بفرستید.
بازنشانی گفتگو در هر بار بارگذاری
برای صفحههای مخصوص مهمان که عمداً با هر بار بارگذاری صفحه، گفتگوی تازهای شروع میکنند:
let hasReset = false;
chat.on("iframeReady", ({ ok, verified, require_verified_user }) => {
if (!ok || verified || require_verified_user || hasReset) return;
hasReset = true;
chat.send({ event: "reset" });
});این شرط محافظ مهم است: بازنشانی، آیفریم را دوباره بارگذاری میکند و iframeReady دوباره اجرا میشود. متغیر در صفحهٔ میزبان قرار دارد؛ بنابراین با بارگذاری مجدد آیفریم از نو تنظیم نمیشود. این نمونه را همزمان با شناسایی کاربر به کار نبرید.
بازنشانی گفتگو با یک دکمه
<button id="reset-chat" type="button">Start a new chat</button>
<script>
document.getElementById("reset-chat").addEventListener("click", () => {
chat.send({ event: "reset" });
});
</script>این دکمه، نشست تازهای برای مهمان شروع میکند. بازنشانی برای کاربر تأییدشده و هنگام شناسایی نادیده گرفته میشود؛ روشی برای خروج کاربر از حساب نیست.
نمایش گفتگو فقط پس از آمادهشدن
آیفریم، وضعیتهای بارگذاری و شناسایی خودش را مدیریت میکند. اگر در طراحی صفحه، قاب را تا تأیید ورود پنهان میکنید:
const chatFrame = document.getElementById("muchat-iframe");
chatFrame.style.visibility = "hidden";
chat.on("user-identified", ({ verified }) => {
if (verified) chatFrame.style.visibility = "visible";
});این نمونه را همراه شناسایی کاربر استفاده کنید. برای مهمان، در صورت نیاز میتوانید با iframeReady موفق، محفظهٔ گفتگو را نمایش دهید و اجازه دهید آیفریم وضعیت بارگذاری خودش را نشان دهد. رویداد جداگانهای به نام conversationReady وجود ندارد.
ساخت دکمهٔ اختصاصی باز و بستهکردن
برای نمایش یا پنهانکردن گفتگوی داخل صفحه، محفظهٔ آن را کنترل کنید:
<button id="toggle-support" type="button" aria-controls="support-panel" aria-expanded="false">
Chat with support
</button>
<section id="support-panel" hidden>
<iframe
src="https://widget.mu.chat/iframe?website_token=YOUR_WEBSITE_TOKEN"
title="MuChat support"
allow="microphone"
style="width: 100%; height: 640px; border: 0"
></iframe>
</section>
<script>
const button = document.getElementById("toggle-support");
const panel = document.getElementById("support-panel");
button.addEventListener("click", () => {
panel.hidden = !panel.hidden;
button.setAttribute("aria-expanded", String(!panel.hidden));
});
</script>این نمونه، بدون حذف آیفریم، نمایش آن را تغییر میدهد. پنهانکردن قاب، نشست را تمام نمیکند و ضبط فعال میکروفن را هم خودکار متوقف نمیکند. وقتی کاربر کاملاً از صفحهٔ پشتیبانی خارج میشود، آیفریم را حذف و کد اتصال آن را هم قطع کنید.
دادن اطلاعات زمینهای صفحه به موچت
نشانی و عنوان صفحهٔ جاری را پس از آمادهشدن آیفریم و دوباره پس از جابهجایی در سایت بفرستید:
function sendPageContext(referrer = document.referrer || null) {
return chat.send({
event: "change-url",
page_context: {
url: window.location.href,
title: document.title,
referrer
}
});
}
chat.on("iframeReady", ({ ok }) => {
if (ok) sendPageContext();
});
window.addEventListener("popstate", () => sendPageContext());رویداد popstate، حرکت عقب و جلوی مرورگر را پوشش میدهد. اگر مسیریاب شما از pushState یا replaceState استفاده میکند، پس از پایان جابهجایی و بهروزرسانی عنوان صفحه، sendPageContext را از هوک مربوط به مسیریاب فراخوانی کنید. میتوانید نشانی قبلی را بهعنوان referrer بدهید.
موچت ممکن است اطلاعات اولیه را از سند صفحهٔ میزبان یا ارجاعدهنده دریافت کند، اما آیفریم با مبدأ متفاوت، اغلب فقط مبدأ سایت را دریافت میکند. ارسال change-url، اطلاعات کامل صفحهٔ جاری را بهصورت صریح مشخص میکند.
در صورت فعالبودن استفاده از اطلاعات صفحه برای هوش مصنوعی در کانال، موچت از عنوان، مبدأ و مسیر صفحه استفاده میکند؛ پارامترهای جستوجو، بخش پس از # و ارجاعدهنده در این دادهٔ مدل قرار نمیگیرند. اطلاعات صفحه از مرورگر میآید و دادهٔ تأییدشدهٔ حساب کاربری نیست.
خروج کاربر از حساب
وقتی کاربر از حساب برنامهٔ شما خارج میشود، گفتگوی مربوط به حساب را از صفحه حذف کنید:
chat.disconnect();
document.getElementById("muchat-iframe").remove();در صفحههای حساب کاربری، اجازه دسترسی فقط برای کاربران احراز هویت شده را فعال کنید و گفتگو را پس از مشخصشدن کاربر واردشده نمایش دهید. در ورود بعدی، JWT همان کاربر را دوباره بفرستید. آیفریم فرمان خروج از حساب ندارد: set-user خالی نادیده گرفته میشود و بازنشانی مهمان، نشست تأییدشده را پاک نمیکند یا توکنهای دسترسی صادرشده را لغو نمیکند.
رهگیری آمادگی و ورود کاربر
با رویدادهای پشتیبانیشده، راهاندازی موفق یا خطاهای شناسایی را در ابزار پایش برنامهٔ خود ثبت کنید. آیفریم مستقیم، رویداد عمومی برای تکتک پیامهای کاربر، پاسخ جریانی یا فراخوانی ابزارها در اختیار صفحه نمیگذارد. رویدادهای muchat:opened و muchat:closed ویجت شناور را برای قاب داخل صفحه استفاده نکنید.
تنظیم زبان و ظاهر گفتگو
در داشبورد، انتشار موچت ← ویجت چت ← مدیریت را باز کنید. زبان، جهت متن، تم، رنگها، آواتار، پیامهای خوشآمدگویی و سؤالهای پیشنهادی را همانجا تنظیم و ذخیره کنید.
آیفریم از همین تنظیمات گفتگو استفاده میکند. عرض، ارتفاع و چیدمان اطراف آن متعلق به صفحهٔ شماست. آیفریم مستقیم، فرمان تغییر ظاهر در زمان اجرا، مانند setOptions، یا بازنویسی زبان از طریق URL را نمیپذیرد.
هماهنگکردن گفتگو با صفحهنمایش موبایل
تگ متای viewport را در صفحه بگذارید و اجازه دهید آیفریم با محفظهٔ خود هماهنگ شود. برای مثال:
#muchat-iframe {
width: 100%;
height: min(720px, 80dvh);
min-height: 420px;
border: 0;
}اگر این CSS را به کار میبرید، مقدار height در استایل داخل تگ را حذف یا اصلاح کنید. گفتگو را با صفحهکلید باز موبایل، پاسخهای بلند و فرمها آزمایش کنید. نیازی به ارسال عرض پنجرهٔ میزبان نیست؛ ابعاد خود آیفریم، فضای در دسترس را مشخص میکند.
پشتیبانی از قابلیتها
قابلیتهای قابل استفاده در آیفریم
| قابلیت | شیوهٔ کار |
|---|---|
| گفتگوی متنی و دریافت پاسخ | با فعالبودن کانال، داخل گفتگو در دسترس است. |
| هویت کاربر | JWT امضاشدهٔ کاربر از طریق set-user. |
| نشست تازه برای مهمان | reset؛ برای کاربر تأییدشده یا هنگام شناسایی نادیده گرفته میشود. |
| اطلاعات صفحهٔ جاری | change-url، مطابق تنظیم استفاده از اطلاعات صفحه برای هوش مصنوعی در کانال. |
| پیامهای خوشآمدگویی، سؤالهای پیشنهادی و ظاهر | در تنظیمات ویجت چت تعیین میشوند. |
| پیوست، پیام صوتی و لینک منابع | بر اساس قابلیتهای فعال و محدودیتهای کانال در دسترساند. میکروفن به اجازهٔ مرورگر هم نیاز دارد. |
| فرمها، دریافت اطلاعات مخاطب و عملیات هوش مصنوعی | از داشبورد تنظیم و در جریان گفتگو اجرا میشوند. |
| ادامهٔ گفتگو | آیفریم نشست را با کوکی مرورگر نگه میدارد؛ بخش تاریخچهٔ گفتگو را ببینید. |
اسکریپت نصب و کنترلهای صفحهٔ میزبان
| قابلیت | روش استفاده در گفتگوی داخل صفحه |
|---|---|
| حباب شناور، موقعیت آن و پیامهای خوشآمدگویی شناور | متعلق به پوستهٔ ویجت شناورند. آیفریم داخل صفحهٔ شما میماند. |
window.$muchat.open()، close() و toggle() | محفظهٔ میزبان را خودتان نمایش دهید یا پنهان کنید. |
| ارسال پیام از دکمهٔ سایت | آیفریم مستقیم فرمان sendMessage ندارد. اگر این اتصال را نیاز دارید، از SDK ویجت شناور استفاده کنید. |
| پیامهای آغازین، زبان و تغییر ظاهر | تنظیمات مشترک گفتگو را در داشبورد ذخیره کنید. ابعاد قاب را صفحهٔ میزبان تعیین میکند. |
| رویدادهای پاسخ و فراخوانی ابزار | در قرارداد عمومی آیفریم مستقیم نیستند. برای رابط گفتگوی اختصاصی، از REST API استفاده کنید. |
پیامهایی که میتوانید بفرستید
فرمانها از فیلد event استفاده میکنند. کد اتصال، پیشوند و تبدیل به رشته را انجام میدهد.
event | فیلدها | اثر |
|---|---|---|
initConfig | willIdentify | جریان اولیهٔ مهمان یا شناسایی را انتخاب میکند. |
set-user | user_jwt | توکن امضاشدهٔ هویت کاربر را میفرستد. |
reset | ندارد | با بارگذاری دوبارهٔ آیفریم، نشست مهمان تازهای شروع میکند. |
change-url | page_context | اطلاعات صفحهٔ میزبان را بهروز یا پاک میکند. |
initConfig
willIdentifybooleanاگر قرار است JWT کاربر را بفرستید، true بدهید. برای دسترسی مهمان، false بدهید. اولین تنظیم معتبر باید در فاصلهٔ ۱ ثانیه پس از iframeReady برسد؛ تنظیمهای بعدی نادیده گرفته میشوند.
chat.send({ event: "initConfig", willIdentify: true });اگر willIdentify برابر true باشد، اما دریافت توکن ناموفق شود، امکان تلاش دوباره یا ورود را در صفحهٔ خود نشان دهید. انتظار نداشته باشید initConfig دوم، دسترسی مهمان را باز کند.
set-user
user_jwtstringالزامیJWT غیرخالی که روی سرور شما و با کلید هویت همین کانال ویجت امضا شده است. فاصلههای ابتدا و انتها حذف میشوند. مقدار خالی، کاربر را از حساب خارج نمیکند.
chat.send({ event: "set-user", user_jwt: userJwt });پاسخ موفق سرور، نشست و مخاطب آیفریم را بهروز میکند و سپس user-identified فرستاده میشود. خطای شناسایی با error اعلام میشود و تلاش دوباره خودکار نیست. تا پایان تلاش جاری، JWT کاربر دیگری را نفرستید.
reset
chat.send({ event: "reset" });آیفریم، کوکی نشست مهمان خودش را حذف و سند را دوباره بارگذاری میکند. با این کار، وضعیت محلی گفتگو، پیشنویس و اتصال قاب کنار گذاشته میشوند؛ گفتگوهای ذخیرهشده روی سرور حذف نمیشوند. این فرمان پیش از راهاندازی موفق، برای مخاطب تأییدشده و هنگام شناسایی اثری ندارد.
change-url
page_contextobject | nullالزامییک شیء با url و فیلدهای اختیاری title و referrer بفرستید؛ یا با null، اطلاعات صفحهٔ مورد استفاده برای تعاملهای بعدی را پاک کنید.
نشانیها باید HTTP(S)، بدون اطلاعات ورود در URL و حداکثر ۲۰۴۸ نویسه باشند. عنوان میتواند حداکثر ۵۰۰ نویسه داشته باشد. فقط اطلاعات صفحهای را بفرستید که گفتگو به آن نیاز دارد.
برای پاککردن اطلاعات جاری:
chat.send({ event: "change-url", page_context: null });این کار، اطلاعات ذخیرهشده همراه پیامهای قبلی را پاک نمیکند. شیوهٔ بهروزرسانی در نمونهٔ کامل اطلاعات صفحه آمده است.
رویدادهایی که دریافت میکنید
با کد اتصال، chat.on(event, (data, message) => ...) فیلدهای رویداد را مستقیماً در data و پیام کاملِ بازشده را در message دریافت میکند.
event | فیلدها | معنی |
|---|---|---|
iframeReady | websiteToken، ok، status، verified، require_verified_user | آیفریم آمادگی را اعلام میکند. فقط ok: true صف کد اتصال را آزاد میکند. |
user-identified | verified | پاسخ موفق شناسایی اعمال شده است؛ مقدار verified: true را بررسی کنید. |
error | action، code و در صورت وجود status | شناسایی ناموفق بوده است. مقدار action برابر set-user است. |
chat.on("iframeReady", ({ ok, status, verified, require_verified_user }) => {
console.info("MuChat readiness", { ok, status, verified, require_verified_user });
});
chat.on("user-identified", ({ verified }) => {
console.info("MuChat identity confirmed", { verified });
});
chat.on("error", ({ action, code, status }) => {
console.error("MuChat action failed", { action, code, status });
});کد اتصال، پیشوند و JSON را از قبل باز کرده است. data.verified را بخوانید یا verified را مستقیماً دریافت کنید؛ دنبال data.data نگردید. خطا در بارگذاری صفحه میتواند مانع رسیدن هر رویدادی شود؛ بنابراین خود قاب و بخش Network مرورگر را هم بررسی کنید.
هویت و دادههای کاربر
شناسایی، کاربر واردشده به سایت را به مخاطب و گفتگوی ویجت متصل میکند. JWT روی سرور موچت و با کلید هویت همان کانال ویجت بررسی میشود. website_token عمومی، ویجت را انتخاب میکند؛ هویت بازدیدکننده را ثابت نمیکند.
انتخاب زمان شناسایی کاربر
جریان متناسب با برنامهٔ خود را انتخاب کنید:
- توکن امضاشده را در صفحهٔ احراز هویتشده قرار دهید. سرور، ورود کاربر را بررسی میکند، JWT را امضا میکند و در HTML قرار میدهد. در تابع دریافت آمادگی،
initConfigوset-userرا بفرستید. مثال PHP را ببینید. - توکن را در مرورگر دریافت کنید. بلافاصله
initConfigرا باwillIdentify: trueبفرستید؛ سپس توکن را از مسیر احراز هویتشدهٔ خود بگیرید. بخش شناسایی کاربر واردشده را ببینید. - پس از مشخصشدن وضعیت کاربر، آیفریم را بسازید. در React صبر کنید تا JWT کاربر واردشده آماده شود یا دسترسی مهمان مشخص باشد. نمونه، شنونده را پیش از اضافهشدن قاب ثبت میکند.
JWT
در ویجت وبسایت، بخش احراز هویت کاربران را باز کنید و کلید امضای هویت را دریافت کنید. این کلید فقط روی سرور شما نگهداری میشود. آیفریم از همان کلید کانال ویجت شناور استفاده میکند و به کلید جداگانهای نیاز ندارد.
محتوای توکن، رشتهٔ اجباری user_id و فیلدهای پشتیبانیشدهٔ مخاطب را دارد؛ برای مثال:
{
"user_id": "customer-42",
"name": "Example User",
"email": "user@example.com",
"phone_number": "+989120000000"
}برای حساب واردشده، شناسهای ثابت و غیرخالی انتخاب کنید. سرور از فیلدهایی مانند locale، country_code و custom_attributes تعریفشدهٔ مخاطب هم پشتیبانی میکند. فیلد سفارشی باید برای همان موچت تعریف شده باشد و نوع مقدار با تنظیم آن مطابقت داشته باشد. فیلد غایب یا دارای null، مقدار قبلی مخاطب را پاک نمیکند.
با HS256 امضا کنید و زمان انقضای کوتاه بگذارید. نمونههای زیر، توکن یکساعته میسازند. برای نمونهٔ Node.js، بستهٔ jsonwebtoken را در پروژهٔ سرور خود نصب کنید؛ تابع PHP از امکانات داخلی زبان استفاده میکند. هر دو تابع را فقط پس از تأیید ورود کاربر در برنامهٔ خود فراخوانی کنید.
import jwt from "jsonwebtoken";
export function createMuchatToken(user) {
const secret = process.env.MUCHAT_IDENTITY_SECRET;
if (!secret) throw new Error("Missing MuChat identity secret");
return jwt.sign(
{ user_id: String(user.id), name: user.name, email: user.email },
secret,
{ algorithm: "HS256", expiresIn: "1h" }
);
}<?php
function createMuchatToken(array $user): string {
$secret = getenv('MUCHAT_IDENTITY_SECRET');
if (!$secret) throw new RuntimeException('Missing MuChat identity secret');
$encode = fn(string $value): string => rtrim(strtr(base64_encode($value), '+/', '-_'), '=');
$header = $encode(json_encode(['alg' => 'HS256', 'typ' => 'JWT'], JSON_THROW_ON_ERROR));
$payload = $encode(json_encode([
'user_id' => (string) $user['id'],
'name' => $user['name'] ?? null,
'email' => $user['email'] ?? null,
'iat' => time(),
'exp' => time() + 3600,
], JSON_THROW_ON_ERROR));
$signature = $encode(hash_hmac('sha256', "$header.$payload", $secret, true));
return "$header.$payload.$signature";
}اگر از مثال کامل PHP پایین استفاده میکنید، تابع PHP را در create-muchat-token.php ذخیره کنید. در هر دو نمونه، MUCHAT_IDENTITY_SECRET متغیر محیطی سرور و حاوی کلید محرمانهٔ همان کانال ویجت است. اگر هدر اختیاری kid را در JWT میگذارید، مقدار آن را برابر شناسهٔ همان کلید قرار دهید.
خروج از حساب
وقتی کاربر دیگر وارد حساب نیست، گفتگوی مربوط به حساب را مطابق نمونهٔ خروج از صفحه حذف کنید. هنگام تغییر حساب، JWT کاربر تازه را بفرستید و پیش از کاملدانستن جابهجایی، منتظر user-identified بمانید. تا زمانی که برنامه در حال مشخصکردن حساب فعال است، گفتگوی کاربر قبلی را نشان ندهید.
تاریخچهٔ گفتگو
آیفریم، نشست را در کوکی مبدأ ویجت نگه میدارد. روی HTTPS و در مرورگرهای پشتیبان، کوکیهای تفکیکشده بر اساس سایت میزبان، نشست را به همان سایتِ دربرگیرنده محدود میکنند.
| بازدیدکننده | چه چیزی ادامه پیدا میکند |
|---|---|
| مهمان | گفتگوی مرتبط با نشست فعلی آیفریم در همان مرورگر و سایت میزبان. پاککردن یا مسدودکردن کوکیها میتواند نشست تازهای ایجاد کند. |
| کاربر شناساییشده | پس از شناسایی موفق، موچت میتواند گفتگوی همان مخاطب در همان کانال ویجت را دوباره متصل کند. تداوم نشست محلی و سیاست ذخیرهسازی مرورگر همچنان مؤثرند. |
بازنشانی مهمان، نشست محلی تازهای شروع میکند و سوابق سرور را پاک نمیکند. گفتگوی یک کانال دیگر یا صفحهٔ مستقل، از کوکی نشست آیفریم استفاده نمیکند.
پرکردن اولیهٔ فرمها
| فرم یا اطلاعات | رفتار |
|---|---|
| اطلاعات مخاطب در JWT معتبر | فیلدهای پشتیبانیشدهٔ هویت، مخاطب را بهروز میکنند. |
| فرم دریافت اطلاعات مخاطب | اگر همهٔ فیلدهای درخواستی از قبل با مقدار معتبر مخاطب موجود باشند، ممکن است نمایش داده نشود یا کنار گذاشته شود. پرشدن بخشی از اطلاعات کافی نیست. |
| فرمهای دیگرِ شروع گفتگو | از شرطهای تنظیمشده برای همان فرم پیروی میکنند. فرم تکمیلشده، تکمیلشده باقی میماند. |
| اطلاعات صفحه از مرورگر | زمینهٔ صفحهٔ جاری را فراهم میکند؛ راهی برای پرکردن فیلدهای تأییدشدهٔ مخاطب نیست. |
عملیات هوش مصنوعی در آیفریم
عملیات هوش مصنوعی را در داشبورد تنظیم و در آزمایشگاه بررسی کنید. همان گفتگو در آیفریم هم میتواند از این عملیات استفاده کند؛ از جمله اتصال HTTP به سرویسهای کسبوکار شما.
اجرای عملیات در جریان تنظیمشدهٔ موچت انجام میشود. آیفریم مستقیم، CHATBOT_TOOL_CALL را به صفحهٔ شما نمیفرستد و پاسخ CHATBOT_TOOL_RESULT را از آن نمیپذیرد. اطلاعات ورود سرویسها را در تنظیمات سمت سرور عملیات نگه دارید.
فرمهای داخل گفتگو
فرمها را در داشبورد بسازید و تنظیم کنید. فرم داخل گفتگو نمایش داده میشود، پاسخهای بازدیدکننده را دریافت میکند و از شرطها و رفتار ادامهٔ گفتگویی پیروی میکند که تعیین کردهاید. شناسایی کاربر میتواند بر ضروریبودن فرمهای شروع اثر بگذارد.
صفحهٔ میزبان، ساختار فرم را از طریق GET_FORM_SCHEMA نمیفرستد و ارسال فرم را با callback آیفریم دریافت نمیکند. برای تغییر فیلدها، مقدارهای پیشفرض یا شرطها، خود فرم را ویرایش کنید؛ پیام تعریفنشده به آیفریم نفرستید.
تنظیمات گفتگو و چیدمان میزبان
ظاهر، زبان، پیام خوشآمدگویی و سؤالهای پیشنهادی از تنظیمات ویجت چت میآیند. چیدمان اطراف گفتگو، ابعاد قاب و هر محفظهٔ اختصاصی باز و بستهشونده را صفحهٔ میزبان تعیین میکند.
پیامهای داخلی تنظیم پیشنمایش داشبورد را در وبسایت کپی نکنید. اتصال عمومی از چهار فرمان مستندشده استفاده میکند؛ پیشنمایش، رابط جداگانهای برای ویرایش تنظیمات است.
پارامترهای URL
| پارامتر | مثال | کاربرد |
|---|---|---|
website_token | ?website_token=YOUR_WEBSITE_TOKEN | کانال ویجت را با مقدار موجود در کد نصب داشبورد انتخاب میکند. |
https://widget.mu.chat/iframe?website_token=YOUR_WEBSITE_TOKENuser_jwt، کلید محرمانهٔ امضا، ایمیل کاربر یا کلید API گفتگو را در URL نگذارید. پس از آمادگی، هویت را با set-user بفرستید. آیفریم از بازنویسی زبان با hostLang در URL پشتیبانی نمیکند؛ زبان گفتگو را در داشبورد انتخاب کنید.
مثالهای کامل
یک صفحهٔ کامل برای گفتگوی مهمان که اطلاعات صفحهٔ جاری را هم منتقل میکند. کد اتصال بالا را در مسیر /connect-muchat.js سایت خود ذخیره کنید و مقدار توکن ویجت را تغییر دهید.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MuChat support</title>
<script src="/connect-muchat.js"></script>
</head>
<body>
<iframe
id="muchat-iframe"
src="https://widget.mu.chat/iframe?website_token=YOUR_WEBSITE_TOKEN"
title="MuChat support"
allow="microphone"
style="width: 100%; height: 640px; border: 0"
></iframe>
<script>
const chat = connectMuchat(document.getElementById("muchat-iframe"));
chat.on("iframeReady", ({ ok, status }) => {
if (!ok) {
console.error("MuChat could not load", status);
return;
}
chat.send({ event: "initConfig", willIdentify: false });
chat.send({
event: "change-url",
page_context: {
url: location.href,
title: document.title,
referrer: document.referrer || null
}
});
});
</script>
</body>
</html>به تابع اتصال، export اضافه و آن را از پروژهٔ خود وارد کنید. این کامپوننت، اتصال و شنوندهها را پیش از اضافهکردن آیفریم ثبت میکند و هنگام تغییر توکن، حساب کاربر یا حذف کامپوننت، آنها را پاک میکند.
import { useEffect, useRef } from "react";
import { connectMuchat } from "./connect-muchat.js";
export default function MuChatIframe({ websiteToken, userJwt }) {
const container = useRef(null);
useEffect(() => {
const iframe = document.createElement("iframe");
iframe.src = "https://widget.mu.chat/iframe?website_token=" + encodeURIComponent(websiteToken);
iframe.title = "MuChat support";
iframe.allow = "microphone";
iframe.style.cssText = "width: 100%; height: 640px; border: 0";
const chat = connectMuchat(iframe);
chat.on("iframeReady", ({ ok }) => {
if (!ok) return;
chat.send({ event: "initConfig", willIdentify: Boolean(userJwt) });
if (userJwt) chat.send({ event: "set-user", user_jwt: userJwt });
chat.send({
event: "change-url",
page_context: { url: location.href, title: document.title, referrer: document.referrer || null }
});
});
chat.on("user-identified", ({ verified }) => console.info("MuChat verified:", verified));
chat.on("error", ({ code, status }) => console.error("MuChat identity error", code, status));
container.current.appendChild(iframe);
return () => {
chat.disconnect();
iframe.remove();
};
}, [websiteToken, userJwt]);
return <div ref={container} />;
}پس از مشخصشدن وضعیت کاربر در برنامه:
<MuChatIframe websiteToken="YOUR_WEBSITE_TOKEN" userJwt={userJwt} />JWT امضاشدهٔ کاربر را بدهید؛ یا برای صفحهای که عمداً مهمان میپذیرد، null بفرستید. تا وقتی JWT کاربر واردشده در حال دریافت است، گفتگوی مهمان نسازید. هنگام خروج از حساب، کامپوننت را از صفحه حذف کنید؛ تغییر توکن به null، نشست تأییدشدهٔ ذخیرهشده را خارج نمیکند. در Next.js، ابتدای این کامپوننت "use client" را اضافه کنید.
این صفحه از تابع PHP به نام createMuchatToken در بخش JWT استفاده میکند. $_SESSION['user'] را با نشست احراز هویتشدهٔ برنامهٔ خود تطبیق دهید. توکن امضاشده در صفحه قرار میگیرد و هیچوقت وارد URL آیفریم نمیشود.
<?php
require __DIR__ . '/create-muchat-token.php';
session_start();
$user = $_SESSION['user'] ?? null;
if (!$user) {
http_response_code(401);
exit('Sign in to use support');
}
$token = createMuchatToken($user);
header('Cache-Control: no-store');
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MuChat support</title>
<script src="/connect-muchat.js"></script>
</head>
<body>
<iframe
id="muchat-iframe"
src="https://widget.mu.chat/iframe?website_token=YOUR_WEBSITE_TOKEN"
title="MuChat support"
allow="microphone"
style="width: 100%; height: 640px; border: 0"
></iframe>
<script>
const userJwt = <?= json_encode($token, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT) ?>;
const chat = connectMuchat(document.getElementById("muchat-iframe"));
chat.on("iframeReady", ({ ok }) => {
if (!ok) return;
chat.send({ event: "initConfig", willIdentify: true });
chat.send({ event: "set-user", user_jwt: userJwt });
chat.send({
event: "change-url",
page_context: { url: location.href, title: document.title, referrer: document.referrer || null }
});
});
chat.on("user-identified", ({ verified }) => console.info("MuChat verified:", verified));
chat.on("error", ({ code, status }) => console.error("MuChat identity error", code, status));
</script>
</body>
</html>صفحه را روی HTTPS ارائه کنید و کلید امضا را در متغیر محیطی سرور بگذارید. کلید هویت هیچوقت وارد HTML نمیشود.
اپلیکیشنهای موبایل
WebView میتواند صفحهٔ پشتیبانی شما را بارگذاری کند و همان گفتگوی داخل صفحه، فرمها و قابلیتهای فعال را نمایش دهد. نمونههای زیر، https://example.com/support را باز میکنند؛ آن را با نشانی HTTPS صفحهای از سایت خود جایگزین کنید که اتصال HTML، React یا PHP بالا را دارد.
شیوهٔ کار
- دسترسی مهمان: WebView میتواند صفحهٔ پشتیبانی شما را باز کند. اگر دسترسی با لینک مستقیم فعال باشد و کانال مهمان را بپذیرد، بارگذاری مستقیم URL آیفریم هم ممکن است.
- دسترسی کاربر واردشده: صفحهٔ خودتان را با آیفریم و کد اتصال بارگذاری کنید. صفحه باید کاربر را احراز هویت کند یا توکن را از جریان ورود امن برنامه دریافت کند. توکن را در URL صفحه نگذارید.
- فرمانها و رویدادها: کد اتصال در صفحهٔ پشتیبانیِ میزبان اجرا میشود. بازکردن مستقیم URL ویجت، قاب والد ایجاد نمیکند؛ بنابراین شنوندهٔ پیامهای میزبان فعال نمیشود. ارسال
set-userبه پنجرهٔ اصلی، اتصال معادل این روش نیست.
اگر صفحهٔ پشتیبانی مخصوص کاربران واردشده است، پیش از نمایش آن، ورود وب اپلیکیشن را برقرار کنید. ورود کاربر در اپلیکیشن بومی، خودکار به WebView منتقل نمیشود.
مثالها
یک WKWebView که صفحهٔ پشتیبانی شما را باز میکند. delegate، لینکهایی را که پنجرهٔ تازه میخواهند، در مرورگر سیستم باز میکند. برای SwiftUI، کنترلکننده را در UIViewControllerRepresentable قرار دهید.
import UIKit
import WebKit
final class SupportViewController: UIViewController, WKUIDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView(frame: view.bounds)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
webView.uiDelegate = self
view.addSubview(webView)
webView.load(URLRequest(url: URL(string: "https://example.com/support")!))
}
func webView(_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures) -> WKWebView? {
if navigationAction.targetFrame == nil,
let url = navigationAction.request.url,
["https", "http"].contains(url.scheme ?? "") {
UIApplication.shared.open(url)
}
return nil
}
}برای پیام صوتی، NSMicrophoneUsageDescription را به Info.plist اضافه کنید، allow="microphone" را روی آیفریم نگه دارید و مجوز رسانهٔ WebKit را متناسب با برنامه مدیریت کنید. ضبط را روی دستگاه واقعی آزمایش کنید.
یک اکتیویتی WebView با JavaScript و ذخیرهسازی DOM فعال. android.permission.INTERNET را در مانیفست تعریف کنید.
import android.os.Bundle
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.activity.ComponentActivity
class SupportActivity : ComponentActivity() {
private lateinit var webView: WebView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
webView = WebView(this).apply {
settings.javaScriptEnabled = true
settings.domStorageEnabled = true
webViewClient = WebViewClient()
loadUrl("https://example.com/support")
}
setContentView(webView)
}
override fun onDestroy() {
webView.destroy()
super.onDestroy()
}
}این نمونهٔ پایه، صفحه را باز میکند و مجوز میکروفن نمیدهد. برای صدا، android.permission.RECORD_AUDIO را تعریف و درخواست کنید؛ پس از اجازهٔ کاربر، درخواست مجوز رسانهٔ WebView را برای مبدأ مورداعتماد گفتگو مدیریت کنید. لینکهایی را که باید بیرون برنامه باز شوند، در کد مسیریابی اپلیکیشن مدیریت کنید.
صفحهٔ پشتیبانی را با react-native-webview باز کنید. پیش از استفاده از کامپوننت، این بسته را در اپلیکیشن نصب کنید.
import { WebView } from "react-native-webview";
export default function SupportScreen() {
return (
<WebView
source={{ uri: "https://example.com/support" }}
javaScriptEnabled
domStorageEnabled
/>
);
}اگر صدا را فعال میکنید، مجوز میکروفن هر پلتفرم را تنظیم کنید. برای پل ارتباطی صفحه با کد بومی، از تابعهای مسیریابی و دریافت پیام WebView استفاده کنید؛ موچت، SDK بومی جداگانهای برای آیفریم ارائه نمیکند.
همان صفحهٔ پشتیبانی را با flutter_inappwebview بارگذاری کنید. ابتدا بسته را به وابستگیهای اپلیکیشن اضافه کنید.
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
class SupportScreen extends StatelessWidget {
const SupportScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Support')),
body: InAppWebView(
initialUrlRequest: URLRequest(url: WebUri('https://example.com/support')),
initialSettings: InAppWebViewSettings(javaScriptEnabled: true),
),
);
}
}شبکه، میکروفن و مدیریت مجوزهای WebView را برای قابلیتهایی که فعال میکنید تنظیم کنید. اگر لینکهای پاسخ باید در مرورگر سیستم باز شوند، تابعهای مدیریت مسیریابی را هم اضافه کنید.
نکتههایی که باید بدانید
- ورود صفحهٔ پشتیبانی را برقرار کنید. برای گفتگوی تأییدشده، صفحهٔ میزبان باید JWT مناسب بگیرد و برای هر سند تازهٔ آیفریم بفرستد. نمونههای مهمان WebView، هویت کاربر بومی را خودکار معرفی نمیکنند.
- فضای ذخیرهسازی متعلق به WebView است. فرض نکنید گفتگوی مرورگر یا کوکیهای برنامه از قبل در آن وجود دارند. پاککردن دادههای WebView میتواند تداوم نشست محلی را از بین ببرد.
- تنظیمات دسترسی را رعایت کنید. قراردادن صفحهٔ پشتیبانی در برنامه، همچنان نیاز دارد مبدأ آن در فهرست دامنههای مجاز باشد. بازکردن مستقیم URL ویجت هم تابع تنظیم لینک مستقیم و احراز هویت است.
- صفحهٔ اپلیکیشن را خودتان ببندید. آیفریم مستقیم، رویداد
closeبه کد بومی نمیفرستد. مسیریابی و چرخهٔ عمر WebView در اختیار اپلیکیشن است. - توکن را وارد لاگ یا URL نکنید. از صفحهٔ احراز هویتشده یا پل ارتباطی تحت کنترل خود استفاده کنید و تغییر حساب و خروج را روی دستگاه واقعی آزمایش کنید.
امنیت
مبدأها
- فرمانها را به مبدأ
srcآیفریم بفرستید و وقتی حاوی هویت هستند، هرگز"*"نگذارید. کد اتصال این کار را انجام میدهد. - پیش از پذیرش پیام،
event.source،event.originو پیشوندmuchat-iframe:را بررسی کنید. کد اتصال هر سه را بررسی میکند. - با دامنههای مجاز داشبورد، سایتهایی را که میتوانند گفتگو را در خود قرار دهند محدود کنید. توکن ویجت بهخودیخود عمومی است.
دامنههای مجاز
در پنجرهٔ نصب آیفریم وبسایت، هر مبدأ مجاز را همراه پروتکل در یک خط وارد کنید؛ مانند https://example.com یا https://*.example.com. برای آزمایش محلی، پورت واقعی را هم بگذارید؛ مثلاً http://localhost:3000. سپس ذخیره را بزنید.
آیفریم بر اساس این فهرست، سیاست امنیتی frame-ancestors میفرستد. مرورگر از نمایش آن در سایت خارج از مبدأهای مجاز جلوگیری میکند. اگر گفتگو داخل چند قاب تودرتو باشد، مبدأ قابهای بالاتر هم باید مجاز باشند.
گزینهٔ اجازه دسترسی با لینک مستقیم مشخص میکند که گفتگو در تب جداگانه باز شود یا نه. غیرفعالکردن آن، گفتگو را داخل آیفریم نگه میدارد و جای دامنههای مجاز یا تأیید هویت را نمیگیرد.
کلیدهای محرمانه و دادهها
از کلید هویت همان کانال ویجتی استفاده کنید که website_token به آن مربوط است. پس از تعویض کلید، مقدار محرمانه و kid اختیاری را روی سرور بهروز کنید. کلید قبلی فرصت انتقال محدودی دارد؛ برای همیشه به آن تکیه نکنید.
change-url یا اطلاعات صفحهٔ مرورگر را مجوز دسترسی به حساب و اجرای عملیات محافظتشده تلقی نکنید. این تصمیمها متعلق به برنامهٔ احراز هویتشده و تنظیمات سمت سرور عملیات هستند.
ویژگیهای عنصر آیفریم
| ویژگی | کاربرد |
|---|---|
title | یک نام دسترسپذیر برای گفتگوی داخل صفحه فراهم میکند. |
allow="microphone" | در صورت فعالبودن صدا، به قاب اجازهٔ درخواست میکروفن میدهد. مرورگر همچنان از بازدیدکننده اجازه میگیرد. |
style یا کلاس CSS | عرض، ارتفاع و حاشیه را در صفحه کنترل میکند. |
id | در صورت نیاز به فرمان، کد اتصال با آن قاب درست را پیدا میکند. |
referrerpolicy | میزان اطلاعاتی را که مرورگر میتواند از صفحهٔ میزبان بفرستد کنترل میکند. برای نشانی و عنوان صریح، بهجای اتکا به ارجاعدهنده از change-url استفاده کنید. |
اگر sandbox یا Permissions Policy محدودکننده میگذارید، بررسی کنید اسکریپتها، فضای ذخیرهسازی، فرمها، دانلود و میکروفن فعالِ گفتگو همچنان کار کنند. این محدودیتها در اختیار سایت میزبان هستند.
رفع مشکل
دیدن کنسول آیفریم
در ابزار توسعهدهندهٔ مرورگر، منوی انتخاب زمینهٔ اجرای کنسول را که معمولاً top نام دارد باز کنید و قاب widget.mu.chat را انتخاب کنید. درخواستهای ناموفق را در Network هم ببینید. برای WebView، در صورت فعالبودن اشکالزدایی وب، از ابزار بررسی دستگاه Safari روی iOS یا chrome://inspect روی Android استفاده کنید.
مشکلات رایج
website_tokenرا از کد همان ویجت در داشبورد کپی کنید و فعالبودن کانال ویجت چت را بررسی کنید.- مبدأ دقیق سایت، با پروتکل و پورت، را با دامنههای مجاز مقایسه کنید. خطای
frame-ancestorsرا در کنسول مرورگر ببینید. - برای قاب و محفظهٔ آن، عرض و ارتفاع قابل نمایش بگذارید. ارتفاع درصدی به ارتفاع مشخصِ عنصر والد نیاز دارد.
- اگر دسترسی فقط برای کاربران احراز هویتشده فعال است، JWT بفرستید و شناسایی موفق را بررسی کنید. بازکردن URL در تب جداگانه هم تابع تنظیم دسترسی با لینک مستقیم است.
- یکی از چهار مقدار پشتیبانیشدهٔ
eventرا با پیشوندmuchat-iframe:بفرستید. شیء خام یا پیام دارایtypeنادیده گرفته میشود. - منتظر
iframeReadyباok: trueبمانید. رویدادloadآیفریم، نشانهٔ آمادگی دریافت فرمان نیست. - پیام را به پنجرهٔ قاب درست و مبدأ
new URL(iframe.src).originبفرستید. - بازنشانی برای کاربر تأییدشده و هنگام شناسایی عمداً نادیده گرفته میشود؛ فرمان ارسال پیام و تغییر ظاهر در زمان اجرا، جزو این رابط نیستند.
- کد اتصال را پیش از اعلام آمادگی ثبت کنید. شنوندهای که بعد از راهاندازی قاب اضافه شود، رویداد ازدسترفته را بازیابی نمیکند.
- بررسی کنید شرط پنجرهٔ فرستنده یا مبدأ، قاب درست را رد نکند.
- خود قاب را برای خطای صفحه یا درخواست راهاندازی بررسی کنید. خطای بارگذاری میتواند مانع فعالشدن شنونده شود.
- بازکردن URL آیفریم بهعنوان سند اصلی، شنوندهٔ میزبان را فعال نمیکند.
- با
HS256، کلید هویت همین کانال ویجت وuser_idرشتهای و غیرخالی امضا کنید. - انقضای JWT و مقدارهای
iat،nbfیاkidاختیاری را بررسی کنید. initConfigرا بهموقع و باwillIdentify: trueبفرستید؛ سپسset-userرا باuser_jwtارسال کنید. برای سند تازهٔ آیفریم، شناسایی را تکرار کنید.- منتظر
user-identifiedباverified: trueبمانید. تکمیلchat.sendفقط به معنی ارسال پیام است. - در رویداد
error، کد گزارششده را بررسی کنید و پیش از تلاش دوباره، توکن معتبر بگیرید. توکن یا کلید را در لاگ چاپ نکنید.
کد اتصال، فیلدها را مستقیم میدهد؛ از ({ verified })، data.code یا data.ok استفاده کنید. پیام خام، یک رشتهٔ دارای پیشوند است، نه شیئی تودرتو در event.data.data. اگر کد اتصال را ندارید، پیشوند و JSON را خودتان باز کنید.
بازنشانی، قاب را دوباره بارگذاری میکند و iframeReady دوباره میرسد. یک متغیر محافظ در صفحهٔ میزبان نگه دارید و فقط یکبار بازنشانی کنید؛ یا فقط پس از کلیک صریح کاربر. در هر رویداد آمادگی، بدون شرط بازنشانی نکنید.
آن را در داشبورد تنظیم و در آزمایشگاه بررسی کنید. عملیات و فرمها در جریان موچت اجرا میشوند؛ آیفریم مستقیم، درخواست فراخوانی ابزار یا ساختار فرم به صفحهٔ میزبان نمیفرستد. بهجای انتظار برای callback مرورگر، تنظیمات عملیات یا فرم را بررسی کنید.
ممکن است مرورگر یا WebView، کوکیهای آیفریم را پاک یا مسدود کرده باشد. HTTPS و مجوز ذخیرهسازی را بررسی کنید. برای کاربر واردشده، شناسایی را با همان کانال ویجت و user_id ثابت تکرار کنید؛ فرض نکنید کوکی مهمان بین سایتهای میزبان یا دستگاهها منتقل میشود.
دکمهٔ اختصاصی باز و بستهکردن در اختیار صفحهٔ میزبان است. محفظهٔ خود را پنهان کنید یا هنگام خروج از صفحه، آیفریم را حذف کنید. فرمان یا رویداد close برای آیفریم وجود ندارد و بازنشانی مهمان هم آن را نمیبندد.
پنجرهٔ تازه و مسیریابی بیرونی را در اپلیکیشن مدیریت کنید. برای صدا، HTTPS، allow="microphone"، مجوز سیستمعامل و مدیریت مجوز رسانهٔ WebView را بررسی کنید. نمونههای پایهٔ WebView، دسترسی میکروفن را خودکار اعطا نمیکنند.
آیفریم با صفحهٔ پشتیبانیِ والد ارتباط دارد، نه مستقیماً با اپلیکیشن بومی. کد اتصال را در همان صفحه اجرا کنید و اگر کد بومی به رویدادی نیاز دارد، از پل ارتباطی WebView خود استفاده کنید. بازکردن مستقیم URL ویجت، قاب والد ایجاد نمیکند یا شنوندهٔ میزبان را فعال نمیکند.