شروع کار

راهنمای توسعه‌دهندگان آی‌فریم

موچت را داخل وب‌سایت یا WebView نمایش دهید؛ با JWT کاربران را شناسایی کنید، نشست مهمان را مدیریت کنید و اطلاعات صفحه را با فرمان‌های پشتیبانی‌شدهٔ آی‌فریم بفرستید.

آی‌فریم، موچت را مستقیماً داخل صفحهٔ شما قرار می‌دهد. گفتگو بدون حباب شناور و در فضایی که برایش تعیین کرده‌اید باز می‌ماند. بازدیدکنندگان می‌توانند بدون ترک صفحه پاسخ بگیرند، فرم‌ها را تکمیل کنند و از قابلیت‌هایی استفاده کنند که در داشبورد فعال کرده‌اید.

برای گفتگوی مهمان، همان تگ آی‌فریم کافی است. اگر می‌خواهید کاربر واردشده را شناسایی کنید، گفتگوی مهمان تازه‌ای شروع کنید یا اطلاعات صفحهٔ جاری را به موچت بدهید، کد اتصال این صفحه را هم اضافه کنید. آی‌فریم قرارداد postMessage مستقل دارد؛ متدهای window.$muchat مربوط به نصب حباب گفتگو هستند.

چه زمانی از آی‌فریم استفاده کنید

در این موارد از آی‌فریم استفاده کنید:

  • گفتگو در بخشی از مرکز راهنما، پنلی در داشبورد یا صفحهٔ اختصاصی پشتیبانی قرار می‌گیرد.
  • می‌خواهید عرض، ارتفاع و چیدمان اطراف گفتگو را خودتان کنترل کنید.
  • پلتفرم شما آی‌فریم را می‌پذیرد، اما برای اسکریپت‌های نصب شخص ثالث محدودیت دارد.
  • می‌خواهید صفحهٔ پشتیبانی وب را در WebView اپلیکیشن موبایل نمایش دهید.

برای دکمهٔ شناور، از حباب گفتگو استفاده کنید. اگر به‌جای قراردادن گفتگو در سایت خود، می‌خواهید یک لینک جداگانه به اشتراک بگذارید، صفحهٔ مستقل را انتخاب کنید.

شروع سریع

کد آی‌فریم را کپی کنید

  1. وارد داشبورد موچت شوید و موچت موردنظرتان را انتخاب کنید.
  2. به انتشار موچت بروید و در کارت ویجت چت، روی مدیریت بزنید.
  3. بالای پیش‌نمایش، انتشار و سپس آی‌فریم وب‌سایت را انتخاب کنید.
  4. کد HTML را کپی کنید و در محلی از صفحه بگذارید که می‌خواهید گفتگو نمایش داده شود.
پنجرهٔ نصب آی‌فریم وب‌سایت در داشبورد موچت، همراه با کد 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 از نمونهٔ شناسایی کاربر استفاده کنید.

اتصال را آزمایش کنید

صفحه را باز کنید و از داخل آی‌فریم سؤالی بفرستید. دریافت پاسخ و اندازهٔ مناسب گفتگو را در دسکتاپ و موبایل بررسی کنید. اگر کد اتصال را اضافه کرده باشید، آماده‌شدن آی‌فریم در کنسول مرورگر هم اعلام می‌شود.

اگر اجازه دسترسی فقط برای کاربران احراز هویت شده فعال باشد، گفتگو تا ارسال JWT معتبر و دریافت رویداد user-identified با verified: true پنهان می‌ماند.

اتصال به آی‌فریم

این تابع را با نام connect-muchat.js ذخیره کنید یا پیش از کد نصب آی‌فریم، در یک اسکریپت قرار دهید. این تابع را خودتان به سایت اضافه می‌کنید؛ فایلی با این نام از سرور موچت بارگذاری نمی‌شود.

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 هم فرستاده می‌شود.نمایش امکان تلاش دوباره یا دریافت توکن تازه.

بدون کد اتصال

استفاده از کد اتصال اختیاری است، اما کد شما باید همین قرارداد را رعایت کند:

  1. منتظر پیامی از contentWindow و مبدأ همان آی‌فریم بمانید.
  2. فقط رشته‌هایی را بپذیرید که با muchat-iframe: شروع می‌شوند و JSON پس از این پیشوند را بخوانید.
  3. نام رویداد را از event بخوانید، نه type. فیلدهای رویداد در شیء بازشده، کنار event قرار دارند.
  4. برای ارسال فرمان، پیشوند 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فیلدهااثر
initConfigwillIdentifyجریان اولیهٔ مهمان یا شناسایی را انتخاب می‌کند.
set-useruser_jwtتوکن امضاشدهٔ هویت کاربر را می‌فرستد.
resetنداردبا بارگذاری دوبارهٔ آی‌فریم، نشست مهمان تازه‌ای شروع می‌کند.
change-urlpage_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فیلدهامعنی
iframeReadywebsiteToken، ok، status، verified، require_verified_userآی‌فریم آمادگی را اعلام می‌کند. فقط ok: true صف کد اتصال را آزاد می‌کند.
user-identifiedverifiedپاسخ موفق شناسایی اعمال شده است؛ مقدار verified: true را بررسی کنید.
erroraction، 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 عمومی، ویجت را انتخاب می‌کند؛ هویت بازدیدکننده را ثابت نمی‌کند.

انتخاب زمان شناسایی کاربر

جریان متناسب با برنامهٔ خود را انتخاب کنید:

  1. توکن امضاشده را در صفحهٔ احراز هویت‌شده قرار دهید. سرور، ورود کاربر را بررسی می‌کند، JWT را امضا می‌کند و در HTML قرار می‌دهد. در تابع دریافت آمادگی، initConfig و set-user را بفرستید. مثال PHP را ببینید.
  2. توکن را در مرورگر دریافت کنید. بلافاصله initConfig را با willIdentify: true بفرستید؛ سپس توکن را از مسیر احراز هویت‌شدهٔ خود بگیرید. بخش شناسایی کاربر واردشده را ببینید.
  3. پس از مشخص‌شدن وضعیت کاربر، آی‌فریم را بسازید. در React صبر کنید تا JWT کاربر واردشده آماده شود یا دسترسی مهمان مشخص باشد. نمونه، شنونده را پیش از اضافه‌شدن قاب ثبت می‌کند.

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 پایین استفاده می‌کنید، تابع PHP را در create-muchat-token.php ذخیره کنید. در هر دو نمونه، MUCHAT_IDENTITY_SECRET متغیر محیطی سرور و حاوی کلید محرمانهٔ همان کانال ویجت است. اگر هدر اختیاری kid را در JWT می‌گذارید، مقدار آن را برابر شناسهٔ همان کلید قرار دهید.

آی‌فریم، هویت را با JWT امضاشده می‌پذیرد. ایمیل ساده، شناسهٔ کاربر، هش کاربر یا فرادادهٔ مرورگر، جایگزین تأیید هویت نیستند. اطلاعات صفحه را جداگانه و از طریق change-url بفرستید.

خروج از حساب

وقتی کاربر دیگر وارد حساب نیست، گفتگوی مربوط به حساب را مطابق نمونهٔ خروج از صفحه حذف کنید. هنگام تغییر حساب، 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_TOKEN

user_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>

فایل تابع پیش از آی‌فریم بارگذاری می‌شود تا کد اتصال، بلافاصله پس از اضافه‌شدن قاب اجرا شود. برای گفتگوی مخصوص کاربران احراز هویت‌شده، به‌جای راه‌اندازی مهمان از جریان شناسایی یا مثال PHP استفاده کنید.

اپلیکیشن‌های موبایل

WebView می‌تواند صفحهٔ پشتیبانی شما را بارگذاری کند و همان گفتگوی داخل صفحه، فرم‌ها و قابلیت‌های فعال را نمایش دهد. نمونه‌های زیر، https://example.com/support را باز می‌کنند؛ آن را با نشانی HTTPS صفحه‌ای از سایت خود جایگزین کنید که اتصال HTML، React یا PHP بالا را دارد.

شیوهٔ کار

  • دسترسی مهمان: WebView می‌تواند صفحهٔ پشتیبانی شما را باز کند. اگر دسترسی با لینک مستقیم فعال باشد و کانال مهمان را بپذیرد، بارگذاری مستقیم URL آی‌فریم هم ممکن است.
  • دسترسی کاربر واردشده: صفحهٔ خودتان را با آی‌فریم و کد اتصال بارگذاری کنید. صفحه باید کاربر را احراز هویت کند یا توکن را از جریان ورود امن برنامه دریافت کند. توکن را در URL صفحه نگذارید.
  • فرمان‌ها و رویدادها: کد اتصال در صفحهٔ پشتیبانیِ میزبان اجرا می‌شود. بازکردن مستقیم URL ویجت، قاب والد ایجاد نمی‌کند؛ بنابراین شنوندهٔ پیام‌های میزبان فعال نمی‌شود. ارسال set-user به پنجرهٔ اصلی، اتصال معادل این روش نیست.

اگر صفحهٔ پشتیبانی مخصوص کاربران واردشده است، پیش از نمایش آن، ورود وب اپلیکیشن را برقرار کنید. ورود کاربر در اپلیکیشن بومی، خودکار به WebView منتقل نمی‌شود.

مثال‌ها

یک WKWebView که صفحهٔ پشتیبانی شما را باز می‌کند. delegate، لینک‌هایی را که پنجرهٔ تازه می‌خواهند، در مرورگر سیستم باز می‌کند. برای SwiftUI، کنترل‌کننده را در UIViewControllerRepresentable قرار دهید.

SupportViewController.swift
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 را متناسب با برنامه مدیریت کنید. ضبط را روی دستگاه واقعی آزمایش کنید.

نکته‌هایی که باید بدانید

  • ورود صفحهٔ پشتیبانی را برقرار کنید. برای گفتگوی تأییدشده، صفحهٔ میزبان باید 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 می‌فرستد. مرورگر از نمایش آن در سایت خارج از مبدأهای مجاز جلوگیری می‌کند. اگر گفتگو داخل چند قاب تو‌در‌تو باشد، مبدأ قاب‌های بالاتر هم باید مجاز باشند.

گزینهٔ اجازه دسترسی با لینک مستقیم مشخص می‌کند که گفتگو در تب جداگانه باز شود یا نه. غیرفعال‌کردن آن، گفتگو را داخل آی‌فریم نگه می‌دارد و جای دامنه‌های مجاز یا تأیید هویت را نمی‌گیرد.

کلیدهای محرمانه و داده‌ها

MUCHAT_IDENTITY_SECRET را روی سرور نگه دارید. فقط توکن امضاشدهٔ کاربر احراز هویت‌شده را برگردانید، انقضای کوتاه بگذارید و پاسخ حاوی JWT را وارد کش مشترک نکنید. کلید محرمانه را در کد مرورگر، بستهٔ اپلیکیشن بومی یا URL آی‌فریم قرار ندهید.

از کلید هویت همان کانال ویجتی استفاده کنید که 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 استفاده کنید.

مشکلات رایج

گام‌های بعدی

مستندات موچت

در این صفحه

چه زمانی از آی‌فریم استفاده کنیدشروع سریعاتصال به آی‌فریمقواعد زمان‌بندینشانه‌های آماده‌شدنبدون کد اتصالکارهای رایجشناسایی کاربر واردشده به حساببازنشانی گفتگو در هر بار بارگذاریبازنشانی گفتگو با یک دکمهنمایش گفتگو فقط پس از آماده‌شدنساخت دکمهٔ اختصاصی باز و بسته‌کردندادن اطلاعات زمینه‌ای صفحه به موچتخروج کاربر از حسابرهگیری آمادگی و ورود کاربرتنظیم زبان و ظاهر گفتگوهماهنگ‌کردن گفتگو با صفحه‌نمایش موبایلپشتیبانی از قابلیت‌هاقابلیت‌های قابل استفاده در آی‌فریماسکریپت نصب و کنترل‌های صفحهٔ میزبانپیام‌هایی که می‌توانید بفرستیدinitConfigset-userresetchange-urlرویدادهایی که دریافت می‌کنیدهویت و داده‌های کاربرانتخاب زمان شناسایی کاربرJWTخروج از حسابتاریخچهٔ گفتگوپرکردن اولیهٔ فرم‌هاعملیات هوش مصنوعی در آی‌فریمفرم‌های داخل گفتگوتنظیمات گفتگو و چیدمان میزبانپارامترهای URLمثال‌های کاملاپلیکیشن‌های موبایلشیوهٔ کارمثال‌هانکته‌هایی که باید بدانیدامنیتمبدأهادامنه‌های مجازکلیدهای محرمانه و داده‌هاویژگی‌های عنصر آی‌فریمرفع مشکلدیدن کنسول آی‌فریممشکلات رایجگام‌های بعدی