رفتن به محتوا
دانشیارمستندات
ورود
  • معرفی
  • شروع سریع
  • دانشیار چیست؟تازه اضافه شده: تازه
  • صفحهٔ اپ‌هاتازه اضافه شده: تازه
  • داخل یک اپتازه اضافه شده: تازه
  • فضای کاری: فایل‌ها و گفت‌وگوتازه اضافه شده: تازه
  • اشتراک‌گذاری و اعضاتازه اضافه شده: تازه
  • یادداشت و دیکتهتازه اضافه شده: تازه
  • خودکارسازیتازه اضافه شده: تازه
  • صفحهٔ خواندن فایلتازه اضافه شده: تازه
  • پروفایل شماتازه اضافه شده: تازه
  • کلیدهای API
  • احراز هویت
  • اپ، فضای کاری، سند
  • پردازش سند
  • گفت‌وگو و نشست‌ها
  • ارجاع‌ها
  • مهارت‌ها
  • قراردادها
  • فضاهای کاری
  • سندها
  • گفت‌وگو
  • مهارت‌ها
  • خطاها
  • دستیار پشتیبانی مشتری
  • پایگاه دانش داخلی
  • چت‌بات مستندات
  • ابزارک سایتتازه اضافه شده: تازه
  • تنظیمات ابزارکتازه اضافه شده: تازه
  • راهنمای فریم‌ورک‌هاتازه اضافه شده: تازه
  • امنیتتازه اضافه شده: تازه
  • رفع اشکالتازه اضافه شده: تازه
  • پرسش‌های پرتکرارتازه اضافه شده: تازه
  • SDK برای TypeScriptدر نقشهٔ راه: به‌زودی
  1. مستندات
  2. ابزارک سایت
  3. راهنمای فریم‌ورک‌ها

راهنمای فریم‌ورک‌ها

جای کد ابزارک در HTML، React، Next.js، Vue، Nuxt، Angular، SvelteKit و Laravel.

ابزارک یک اسکریپت است، پس در هر فریم‌ورکی کار یکی است: یک بار، با سه ویژگی، بارگذاری‌اش کنید. فقط جای گذاشتن اسکریپت فرق می‌کند.

پیش از شروع

  • کد ابزارک را از صفحهٔ ابزارک در کنسول بگیرید. کلید، شناسهٔ اپ و شناسهٔ فضای کاری شما در آن هست.
  • دامنهٔ سایتتان و نشانی محیط توسعه‌تان (مثل localhost:5173) را به دامنه‌های مجاز اضافه کنید.
  • اسکریپت را یک بار و در بخشی از برنامه بارگذاری کنید که هیچ‌وقت از صفحه حذف نمی‌شود. ابزارک راهی برای حذف شدن ندارد و نسخهٔ دوم را نادیده می‌گیرد؛ پس آن را داخل کامپوننت یک صفحه نگذارید. در نمونه‌های زیر، dk_live_… یک کلید نمونه است.

اگر این سه مقدار را در متغیرهای محیطی نگه دارید، می‌توانید برای محیط آزمایشی (staging) یک اپ و برای محیط اصلی (production) اپ دیگری داشته باشید:

.env
DANESHYAR_WIDGET_KEY=dk_live_…
DANESHYAR_APP_ID=…
DANESHYAR_WORKSPACE_ID=…
متغیر محیطی سمت کاربر داخل صفحه ساخته می‌شود، پس عمومی است. برای کلید ابزارک که به هر حال عمومی است مشکلی ندارد، اما هیچ‌وقت کلیدی را که با آن REST API را صدا می‌زنید این‌طور نگه ندارید.

HTML ساده

تگ را در هر صفحه‌ای که باید گفت‌وگو داشته باشد، درست پیش از </body> بگذارید. اگر سایتتان پانویس یا قالب مشترک دارد، یک بار همان‌جا بگذاریدش.

index.html
<!doctype html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="utf-8" />
    <title>My clinic</title>
  </head>
  <body>
    <h1>Welcome</h1>

    <!-- Daneshyar widget: once per page, just before </body> -->
    <script
      src="https://app.daneshyar.info/widget.js"
      data-api-key="dk_live_9f3aC2xQ7mB1vT8sE4nK6pR0jY5wZ2hL"
      data-app-id="2d7c0e91-4a5b-4f8e-b3c6-9e1f0a7d5c42"
      data-workspace-id="8f14e45f-ceea-467a-9f4c-1a2b3c4d5e6f"
      async
    ></script>
  </body>
</html>

کار دیگری لازم نیست. اسکریپت با async و بعد از محتوای صفحه بارگذاری می‌شود.

React (با Vite)

یک کامپوننت کوچک بسازید و یک بار در App.tsx نمایشش دهید. اسکریپت را اولین باری که برنامه بالا می‌آید اضافه می‌کند.

src/DaneshyarWidget.tsx
import { useEffect } from "react";

const WIDGET_SRC = "https://app.daneshyar.info/widget.js";

/** Render once, in your root component (App.tsx). */
export function DaneshyarWidget() {
  useEffect(() => {
    // widget.js runs once per page. Don't add it twice.
    if (document.querySelector(`script[src="${WIDGET_SRC}"]`)) return;

    const script = document.createElement("script");
    script.src = WIDGET_SRC;
    script.async = true;
    // dataset.apiKey becomes data-api-key, and so on.
    script.dataset.apiKey = import.meta.env.VITE_DANESHYAR_WIDGET_KEY;
    script.dataset.appId = import.meta.env.VITE_DANESHYAR_APP_ID;
    script.dataset.workspaceId = import.meta.env.VITE_DANESHYAR_WORKSPACE_ID;
    script.dataset.locale = "fa";
    document.body.appendChild(script);
  }, []);

  return null; // the widget draws its own button
}

اگر از Create React App استفاده می‌کنید، به‌جای import.meta.env.VITE_… بنویسید process.env.REACT_APP_…. در محیط توسعه، Strict Mode در React افکت‌ها را دو بار اجرا می‌کند؛ بررسی querySelector جلوی نسخهٔ دوم را می‌گیرد.

Next.js (با App Router)

از next/script در layout اصلی، یعنی app/layout.tsx، استفاده کنید تا وقتی بازدیدکننده بین صفحه‌ها جابه‌جا می‌شود اسکریپت بارگذاری‌شده بماند.

app/layout.tsx
import Script from "next/script";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="fa" dir="rtl">
      <body>
        {children}
        <Script
          src="https://app.daneshyar.info/widget.js"
          strategy="afterInteractive"
          data-api-key={process.env.NEXT_PUBLIC_DANESHYAR_WIDGET_KEY}
          data-app-id={process.env.NEXT_PUBLIC_DANESHYAR_APP_ID}
          data-workspace-id={process.env.NEXT_PUBLIC_DANESHYAR_WORKSPACE_ID}
        />
      </body>
    </html>
  );
}

متغیرهایی که در مرورگر به کار می‌روند باید با NEXT_PUBLIC_ شروع شوند. اگر از Pages Router استفاده می‌کنید، همین <Script> را در pages/_app.tsx بگذارید.

Vue 3

اسکریپت را از کامپوننت اصلی، یعنی App.vue، و داخل onMounted اضافه کنید.

src/App.vue
<script setup lang="ts">
import { onMounted } from "vue";

const WIDGET_SRC = "https://app.daneshyar.info/widget.js";

onMounted(() => {
  // widget.js runs once per page. Don't add it twice.
  if (document.querySelector(`script[src="${WIDGET_SRC}"]`)) return;

  const script = document.createElement("script");
  script.src = WIDGET_SRC;
  script.async = true;
  script.dataset.apiKey = import.meta.env.VITE_DANESHYAR_WIDGET_KEY;
  script.dataset.appId = import.meta.env.VITE_DANESHYAR_APP_ID;
  script.dataset.workspaceId = import.meta.env.VITE_DANESHYAR_WORKSPACE_ID;
  document.body.appendChild(script);
});
</script>

<template>
  <RouterView />
</template>

اگر برنامهٔ Vue شما مرحلهٔ ساخت ندارد، کد HTML را مستقیم در index.html بگذارید.

Nuxt 3

اسکریپت را به app.head در nuxt.config.ts اضافه کنید. Nuxt آن را به همهٔ صفحه‌ها اضافه می‌کند.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      script: [
        {
          src: "https://app.daneshyar.info/widget.js",
          async: true,
          tagPosition: "bodyClose",
          "data-api-key": "dk_live_9f3aC2xQ7mB1vT8sE4nK6pR0jY5wZ2hL",
          "data-app-id": "2d7c0e91-4a5b-4f8e-b3c6-9e1f0a7d5c42",
          "data-workspace-id": "8f14e45f-ceea-467a-9f4c-1a2b3c4d5e6f",
        },
      ],
    },
  },
});

برای خواندن مقدارها از متغیرهای محیطی، به‌جای این روش از runtimeConfig.public و useHead() در app.vue استفاده کنید.

Angular

کد ابزارک را در src/index.html و بعد از <app-root> بگذارید.

src/index.html
<!doctype html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="utf-8" />
    <base href="/" />
  </head>
  <body>
    <app-root></app-root>

    <script
      src="https://app.daneshyar.info/widget.js"
      data-api-key="dk_live_9f3aC2xQ7mB1vT8sE4nK6pR0jY5wZ2hL"
      data-app-id="2d7c0e91-4a5b-4f8e-b3c6-9e1f0a7d5c42"
      data-workspace-id="8f14e45f-ceea-467a-9f4c-1a2b3c4d5e6f"
      async
    ></script>
  </body>
</html>

ساده‌ترین جا همین است و برای همهٔ مسیرها کار می‌کند. برای مقدارهای جدا در هر محیط، برای هر ساخت یک index.html داشته باشید و با fileReplacements در angular.json جایگزینش کنید.

SvelteKit

کد ابزارک را در src/app.html و بعد از %sveltekit.body% بگذارید.

src/app.html
<!doctype html>
<html lang="fa" dir="rtl">
  <head>
    <meta charset="utf-8" />
    %sveltekit.head%
  </head>
  <body data-sveltekit-preload-data="hover">
    <div style="display: contents">%sveltekit.body%</div>

    <script
      src="https://app.daneshyar.info/widget.js"
      data-api-key="dk_live_9f3aC2xQ7mB1vT8sE4nK6pR0jY5wZ2hL"
      data-app-id="2d7c0e91-4a5b-4f8e-b3c6-9e1f0a7d5c42"
      data-workspace-id="8f14e45f-ceea-467a-9f4c-1a2b3c4d5e6f"
      async
    ></script>
  </body>
</html>

در Svelte ساده با Vite، آن را به index.html اضافه کنید. برای خواندن مقدارها از متغیرهای محیطی، اسکریپت را مثل نمونهٔ React، داخل onMount در +layout.svelte اصلی اضافه کنید.

Laravel (با Blade)

تگ را در layout اصلی Blade بگذارید و مقدارها را از config/services.php بخوانید.

resources/views/layouts/app.blade.php
{{-- config/services.php:
     'daneshyar' => [
         'widget_key'   => env('DANESHYAR_WIDGET_KEY'),
         'app_id'       => env('DANESHYAR_APP_ID'),
         'workspace_id' => env('DANESHYAR_WORKSPACE_ID'),
     ], --}}

<body>
    @yield('content')

    <script
        src="https://app.daneshyar.info/widget.js"
        data-api-key="{{ config('services.daneshyar.widget_key') }}"
        data-app-id="{{ config('services.daneshyar.app_id') }}"
        data-workspace-id="{{ config('services.daneshyar.workspace_id') }}"
        async
    ></script>
</body>

بعد از تغییر .env، دستور php artisan config:clear را اجرا کنید تا Laravel مقدارهای تازه را بخواند.

Node.js و Express

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

server.js
import express from "express";

const BASE = "https://api.daneshyar.info/api/v1";
const KEY = process.env.DANESHYAR_API_KEY; // server only, never in the browser
const WORKSPACE = process.env.DANESHYAR_WORKSPACE_ID;

const app = express();
app.use(express.json());

// Your frontend calls POST /api/ask. Only this server knows the key.
app.post("/api/ask", async (req, res) => {
  const { question, sessionId } = req.body;
  if (typeof question !== "string" || !question.trim()) {
    return res.status(400).json({ error: "question is required" });
  }

  const upstream = await fetch(`${BASE}/workspaces/${WORKSPACE}/chat/`, {
    method: "POST",
    headers: { "X-API-Key": KEY, "Content-Type": "application/json" },
    body: JSON.stringify({
      message: question,
      session_id: sessionId ?? undefined,
      // One id per signed-in user keeps their chats apart.
      external_user_id: String(req.user?.id ?? "anonymous"),
    }),
  });

  const body = await upstream.json();
  if (!upstream.ok) {
    return res.status(upstream.status).json({ error: body.message ?? body.detail });
  }

  const reply = body.data.assistant_message;
  res.json({
    sessionId: body.data.session.id,
    answer: reply.content,
    sources: reply.citations,
  });
});

app.listen(3000);

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

چه چیزی باید ببینید

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

چیزی نمایش داده نمی‌شود یا پیام خطا می‌بینید؟ رفع اشکال را ببینید.

قبلیتنظیمات ابزارکبعدیامنیت

در این صفحه

  • پیش از شروع
  • HTML ساده
  • React (با Vite)
  • Next.js (با App Router)
  • Vue 3
  • Nuxt 3
  • Angular
  • SvelteKit
  • Laravel (با Blade)
  • Node.js و Express
  • چه چیزی باید ببینید

همهٔ نمونه‌های این مستندات روی API واقعی اجرا می‌شوند. اگر نمونه‌ای کار نکرد، به ما بگویید؛ آن یک باگ در مستندات است.

خدماتدربارهٔ ماگفت‌وگو با ما