დეველოპერის გზამკვლევი
ვიჯეტის ჩაშენება, კონფიგურაცია, კითხვარის სქემა და პარტნიორული REST API — ყველაფერი, რაც ინტეგრაციისთვის გჭირდება.
მიმოხილვა
Base URL: https://api.chkuiskolopi.ge/api
ორი ტიპის წვდომა არსებობს:
- ვიჯეტის ენდფოინთები — ავტორიზაცია არ სჭირდება; ბოტის ამოსაცნობად საკმარისია
public_key(body/query-ში). ამათ ვიჯეტი ავტომატურად იყენებს. - პარტნიორული API — ბოტების პროგრამული მართვისთვის; ითხოვს header-ს
Authorization: Bearer <access_token>(ტოკენს ავტორიზაციით იღებ). ვადაგასული/არასწორი ტოკენი →401.
ბოტების უმეტესობა კოდის გარეშე, პორტალიდან იმართება — API გჭირდება მხოლოდ მაშინ, თუ საკუთარი ავტომატიზაცია გინდა.
სწრაფი სტარტი
- პორტალში შექმენი ბოტი და აიღე მისი
public_key(ჩასაშენებელი კოდის მოდალში ჩანს). - ჩასვი ერთი ხაზი საიტის
<body>-ის ბოლოს:
<script src="https://api.chkuiskolopi.ge/api/scrap/widget.js?key=PUBLIC_KEY"></script>
- სურვილისამებრ შეამოწმე ბოტი პირდაპირ API-თი:
curl -X POST -H "Content-Type: application/json" \
-d '{"partner_key":"PUBLIC_KEY","query":"გამარჯობა","session_id":"test-1","deviceInfo":{"device_name":"curl","ip_address":""}}' \
https://api.chkuiskolopi.ge/api/scrap/widget/query/
ვიჯეტის ჩაშენება
სკრიპტი თვითონ ქმნის მცურავ ღილაკს (ქვედა-მარჯვენა კუთხე) და ჩატის პანელს. სერვერული აწყობა, CSS ან დამატებითი კოდი არ სჭირდება.
სესია
- სესია ინახება ვიზიტორის
localStorage-ში, გასაღებითck_session_<key-ის პირველი 8 სიმბოლო>. - ვადა — 1 საათი (მოქმედებისას ვადა უახლდება). ვადის გასვლის შემდეგ ახალი სესია იწყება.
- საუბრის ისტორია სესიას მიჰყვება — ბოტს ერთი სესიის ფარგლებში წინა კითხვა-პასუხი ახსოვს.
CORS
ვიჯეტის ენდფოინთები (/api/scrap/widget/…) ნებისმიერი Origin-იდან დაშვებულია — გასაღები body-შია და cookie არ გამოიყენება. CORS-ის კონფიგურაცია პარტნიორს არ სჭირდება.
დომენების სია (allowed domains) — დაცვის კარიბჭე
public_keyგვერდის HTML-ში ჩანს — ეს განზრახ ასეა (საჯარო იდენტიფიკატორი). ბოროტად გამოყენებას დომენების სია აჩერებს.- ცარიელი სია = ვიჯეტი ყველა საიტზე მუშაობს.
- არაცარიელი სია → სერვერი შეკითხვისას ამოწმებს
Origin/Referer-ს: ჰოსტი უნდა ემთხვეოდეს ზუსტად ან იყოს ქვედომენი. ჩავარდნა →403 {"error":"domain_not_allowed"}. - ჩაწერისას მისამართები ნორმალიზდება:
https://Example.com/x→example.com; მძიმეებით გამოყოფილი სიაც მიიღება. - გათიშული ბოტის (
is_active=false) გასაღები →401 Invalid partner_key.
პორტალის სატესტო ფანჯარა: დომენ-ჩაკეტილი ბოტი პორტალის preview-ში 403 domain_not_allowed-ს დააბრუნებს (preview სხვა დომენზეა) — ეს დაცვის მუშაობის ნიშანია და არა ხარვეზი. ტესტისთვის დომენი დროებით მოხსენი.
ვიჯეტის კონფიგურაცია (config)
ბოტის config JSON-ობიექტია. იცვლება პორტალიდან, ოსტატის თხოვნით ან PATCH-ით. ცვლილება merge-ით ერწყმის არსებულს — გადააგზავნე მხოლოდ შესაცვლელი გასაღები, დანარჩენი ხელუხლებელი რჩება. ყოველი ცვლილების წინ ძველი მდგომარეობა ავტომატურად ინახება (აღდგენადია).
მისალმება — greeting
- ტექსტი, რომელსაც ვიჯეტი პანელის პირველ გახსნაზე აჩვენებს ბოტის ბუშტად.
- ლოკალურად ჩნდება — სერვერზე არაფერი იგზავნება და არ ფასიანდება.
- თუ ბოტს კითხვარიც აქვს: ჯერ მისალმება, მერე ხე იწყება.
Enter ღილაკი — enter_sends
- ნაგულისხმევად: Enter = ახალი ხაზი; შეტყობინება იგზავნება მხოლოდ „Send" ღილაკით.
"enter_sends": true→ Enter აგზავნის, Shift+Enter = ახალი ხაზი. მობილურზეც მოქმედებს.
ქცევები — behaviors
ობიექტი boolean-ჩამრთველებით; რაც არ წერია — გამორთულია:
| გასაღები | რას რთავს |
|---|---|
typing | „წერს…" ანიმაცია პასუხის მოლოდინში |
processing | გრძელ (>100 სიმბ.) შეკითხვაზე შუალედური ბუშტი „ინფორმაციას ვამუშავებ ⏳" |
reset | „ახალი ჩატი"/„თავიდან"/„/reset" ტექსტით ან ↺ ღილაკით ახალი სესია (მთლიანად კლიენტის მხარეს) |
debounce | ~2.5 წამში მიყოლებით გამოგზავნილი მესიჯები ერთ შეკითხვად ერთიანდება |
voice | 🎤 ღილაკი — ხმის გარდაქმნა ტექსტად (ქართული ენა); ტექსტი ველში ჯდება და ვიზიტორი თვითონ აგზავნის |
file_upload | 📎 ღილაკი — დოკუმენტის (PDF/DOCX/XLSX/CSV/TXT) ან სურათის (JPG/PNG/WEBP) ატვირთვა; შიგთავსი (OCR-ის ჩათვლით) მომდევნო შეკითხვას მიჰყვება |
ხმა ფასიანია: ტრანსკრიფცია პარტნიორის ბალანსიდან იხარჯება გაშიფვრის მომენტში. გამორთულ ქცევაზე შესაბამისი ენდფოინთი 403-ს აბრუნებს; ბალანსი < $1 → 402. ჩაწერისას 10 წამი სიჩუმე → ავტო-გაჩერება და გაშიფვრა; სუფთა სიჩუმე არ იშიფრება და არაფერი ღირს; ერთი ჩანაწერი მაქს. 15 წუთი.
იერსახე — theme
ფერები და ფორმა CSS-ცვლადებად ესმება ვიჯეტს. theme რომ არ აქვს — ნაგულისხმევი ლურჯი/თეთრი იერი. ყველა ველი არჩევითია; არასწორი მნიშვნელობა უბრალოდ იგნორირდება.
| ჯგუფი | გასაღებები |
|---|---|
| ფერები (hex ან rgb/rgba) | accent (მთავარი — ღილაკი/სათაური/Send/იუზერის ბუშტი), on_accent, panel, bot_bg/bot_text, user_bg/user_text, field_bg/field_text/field_border/line, muted |
| ფორმა (px ან %) | radius (პანელი), bubble_radius, field_radius, btn_radius, launcher_radius (50%=წრე, 28px=აბი, 12px=კვადრატი) |
| მცურავი ღილაკი | launcher_icon (ემოჯი) ან launcher_logo (სურათის URL, ლოგოს ატვირთვით). ლოგო თუ მითითებულია — ხატი იგნორირდება |
| ბრენდინგი | hide_branding: true → „powered by chkuiskolopi.ge" ბმული იმალება (white-label) |
Markdown-რენდერი პასუხებში
ვიჯეტი ბოტის პასუხს ავტომატურად აფორმატებს Markdown-ად — ყველა ბოტისთვის, კონფიგის გარეშე: bold/italic, სათაურები (#–######), ბულეტ- და ნუმერირებული სიები, ციტატები (>), ინლაინ-კოდი და კოდის ბლოკები, ბმულები [ტექსტი](https://…) (ახალ ტაბში; http/https/mailto), აბზაცები.
უსაფრთხოება: ტექსტი ჯერ HTML-escape-დება და მერე ფორმატდება — <script> და სხვა HTML არასდროს სრულდება.
რჩევა: ბოტის ინსტრუქციაში ჩაწერე: „პასუხები დააფორმატე Markdown-ით: მთავარი ტერმინები bold-ით, ვარიანტები ბულეტ-სიად, სექციები სათაურებით, გრძელი პასუხი აბზაცებად."
კითხვარი — ღილაკებიანი ხის სქემა
ინახება config.questionnaire-ში. ხე მთლიანად ვიჯეტში (ბრაუზერში) მუშაობს — სერვერამდე მხოლოდ ერთი ჩვეულებრივი ტექსტური შეკითხვა მიდის კითხვარის ბოლოს. questionnaire რომ არ აქვს — ვიჯეტი თავისუფალი ჩატია.
ნაბიჯის სქემა
"step_key": {
"text": "ბოტის შეტყობინება ამ ნაბიჯზე",
"buttons": [
{ "label": "ღილაკის წარწერა", "value": "მნიშვნელობა", "next_step": "შემდეგი_ნაბიჯი" }
],
"show_stop_button": true,
"allow_custom_input": false
}
| ველი | მნიშვნელობა |
|---|---|
text | ბოტის ბუშტში გამოჩნდება ნაბიჯის გახსნისას |
buttons[].label | ღილაკზე წერია და არჩევისას user-ბუშტად ემატება |
buttons[].value | ინახება პასუხებში |
buttons[].next_step | შემდეგი ნაბიჯის გასაღები; "END" ან ცარიელი → დასრულება |
show_stop_button | true → ემატება ნაცრისფერი ღილაკი „შეწყვეტა" |
allow_custom_input | true → ტექსტის ველი ჩართულია; აკრეფილი ტექსტი ხდება პასუხი და გადადის პირველი ღილაკის next_step-ზე (ღილაკი თუ არაა — END) |
რეზერვირებული „_"-გასაღებები
questionnaire-ში ქვედა ტირეთი დაწყებული გასაღებები ველებია და არა ნაბიჯები:
| გასაღები | მნიშვნელობა | ნაგულისხმევი |
|---|---|---|
_final_prompt | დასკვნითი ინსტრუქცია, რომელიც კითხვარის ბოლოს ბოტს ეგზავნება პასუხებთან ერთად | „ამ პასუხების მიხედვით დაეხმარე ვიზიტორს." |
_stop_prompt | იგივე, „შეწყვეტა"-თი ნახევრად გავლილ კითხვარზე | „ვიზიტორმა კითხვარი შეწყვიტა. აქამდე არსებული პასუხების მიხედვით დაეხმარე." |
ნაბიჯის სახელი „_"-ით არასდროს დაიწყო — ძრავი მას ნაბიჯად არ ჩათვლის.
ძრავის ქცევა
- საწყისი ნაბიჯი (root): ის გასაღები, რომელსაც ვერც ერთი
next_stepვერ ასახელებს. ხეს ჰქონდეს ზუსტად ერთი root. - კითხვარი იწყება პანელის პირველ გახსნაზე, ერთხელ. თუ ბოტს
greeting-იც აქვს — ჯერ მისალმება, მერე ხე. - ღილაკიან ნაბიჯზე ტექსტის ველი გათიშულია (გარდა
allow_custom_input: true-სი). - უცნობი
next_step→ ხე ნაადრევად სრულდება — გატეხილ ბმულებს მიჰყევი თვალი. - დასრულებაზე ვიჯეტი აწყობს ერთ ტექსტს (კითხვა-პასუხების სია +
_final_prompt) და ჩვეულებრივ შეკითხვად აგზავნის — ბოტი პასუხობს უკვე თავისი ინსტრუქციით და ცოდნის ფაილებით. - „შეწყვეტაზე": პასუხები თუ არსებობს — იგზავნება
_stop_prompt-ით; თუ არა — თავისუფალი ჩატი ირთვება.
სრული მაგალითი (გამოგონილი კაფეს ბოტი)
{
"questionnaire": {
"start": {
"text": "გამარჯობა! რით დაგეხმაროთ?",
"buttons": [
{ "label": "მენიუ მაინტერესებს", "value": "menu", "next_step": "menu_type" },
{ "label": "მაგიდის დაჯავშნა", "value": "booking", "next_step": "guests" }
],
"show_stop_button": true
},
"menu_type": {
"text": "რა გირჩევნიათ?",
"buttons": [
{ "label": "ყავა და დესერტი", "value": "coffee", "next_step": "END" },
{ "label": "საუზმე", "value": "breakfast", "next_step": "END" }
],
"show_stop_button": true
},
"guests": {
"text": "რამდენი სტუმარი იქნებით? (შეგიძლიათ აკრიფოთ)",
"buttons": [
{ "label": "2", "value": "2", "next_step": "END" },
{ "label": "4", "value": "4", "next_step": "END" }
],
"allow_custom_input": true,
"show_stop_button": true
}
}
}
პარტნიორული REST API
ავტორიზაცია
Body: {email, password, deviceInfo:{device_name, ip_address}, source:"partner"} → იწყება ელფოსტის ვერიფიკაცია. "source":"partner"-ით რეგისტრირებული ანგარიში ვერიფიკაციისას იღებს $5 საჩუქარს და უბრუნდება პორტალს.
Body: {email, password} → {access_token, refresh_token}. ყველა პარტნიორული ენდფოინთი ითხოვს Authorization: Bearer <access_token> header-ს; ვადაგასულზე → 401, ხელახლა შედი.
→ {api_key} — ძველი საერთო გასაღები. POST /user/api-key/regenerate/ ახალს ქმნის და ძველი უქმდება — ეს ტეხავს მხოლოდ legacy გასაღებით ჩაშენებულ ვიჯეტებს; ბოტების per-agent public_key-ებს არ ეხება. ახალი ინტეგრაციებისთვის ყოველთვის ბოტის public_key გამოიყენე.
ბოტები (agents)
agent ობიექტი: {id, name, public_key, system_prompt, enabled_tools, model_tier, is_active, allowed_domains, config, telegram_connected, telegram_bot_username, facebook_connected, facebook_page_name, …}
→ {"tools":[{id, label, description}]} — ჩართვადი ხელსაწყოების კატალოგი: ინტერნეტში ძებნა, მეხსიერება, ვირტუალური ეკრანი/ბრაუზერი, ჭკუის დონის გადართვა და ექსპერტებზე გადამისამართებები. enabled_tools: [] = სრული საბაზო ნაკრები გადამისამართებების გარეშე; არაცარიელი სია = მხოლოდ ჩამოთვლილი. უცნობი ID ჩუმად იგნორირდება.
→ {"agents":[…]} — მხოლოდ საკუთარი ბოტები.
Body: {name, system_prompt, model_tier, enabled_tools, allowed_domains?, config?} → 201 + agent.
model_tier:cheap|medium|strong(სხვა მნიშვნელობა → ჩუმადcheap). ეს საწყისი დონეა ახალი სესიისთვის — ვიზიტორის მიერ საუბარში არჩეული დონე სესიის ბოლომდე იმარჯვებს.allowed_domains: სია ან მძიმეებიანი ტექსტი; URL-ებიდან ჰოსტი ავტომატურად ამოიჭრება.config: მხოლოდ ობიექტი → სხვა ტიპზე400 config_must_be_object.
curl -X POST -H "Authorization: Bearer $T" -H "Content-Type: application/json" \
-d '{"name":"კონსულტანტი","system_prompt":"შენ ხარ...","enabled_tools":[],"model_tier":"cheap"}' \
https://api.chkuiskolopi.ge/api/scrap/partner/agents/create/
ნაწილობრივი განახლება — იცვლება მხოლოდ გაგზავნილი ველები. config merge-ით ერწყმის არსებულს (გადააგზავნე მხოლოდ შესაცვლელი გასაღები); ყოველი ცვლილების წინ ძველი მდგომარეობა ავტომატურად ინახება. is_active: false → ვიჯეტი ჩერდება. → 200 + agent · 404 თუ ბოტი ვერ მოიძებნა.
Body: {recipient: "ელფოსტა"} → ბოტი მიმღების ანგარიშზე გადადის. შეუქცევადია. შეცდომები: recipient_required, agent_not_found, recipient_not_found, recipient_not_unique, cannot_transfer_to_self.
ცოდნის ფაილები
→ {files:[{id, file_name, char_count, created_at}], total_chars, max_total_chars: 30000, max_files: 5}
multipart, ველი file. ფაილიდან მხოლოდ ტექსტი ინახება — ორიგინალი არ რჩება. ტიპები: PDF, DOCX, XLSX, TXT, CSV, MD, JSON, LOG. დასკანერებული PDF ტექსტს ვერ იძლევა → extraction_failed.
curl -X POST -H "Authorization: Bearer $T" -F "file=@katalogi.pdf" \
https://api.chkuiskolopi.ge/api/scrap/partner/agents/7/files/upload/
→ {ok: true, total_chars}. შეუქცევადია (ორიგინალი არ ინახება).
შეცდომის კოდები: file_required · too_many_files (მაქს. 5) · file_too_large (მაქს. 5MB) · unsupported_type · extraction_failed · knowledge_limit_exceeded (ჯამური 30 000 სიმბოლო; პასუხს მოჰყვება used, file_chars, limit).
ლოგოს ატვირთვა
multipart, ველი file — PNG/JPG/WEBP/GIF, ≤ 1MB → {"url": "https://…"}. დააბრუნებული URL ჩასვი config.theme.launcher_logo-ში. შეცდომები: file_required, unsupported_type, file_too_large, upload_failed.
არხები — Telegram და Messenger
Body: {bot_token: "@BotFather-ის ტოკენი"}. სერვერი ტოკენს ამოწმებს და ბოტს ავტომატურად უკავშირებს — სხვა ნაბიჯი არ გჭირდება. → {ok: true, telegram_connected: true, telegram_bot_username}. ტოკენი პასუხებში არასდროს ბრუნდება. შეცდომები: bot_token_required, invalid_bot_token, setwebhook_failed, telegram_unreachable, agent_not_found.
→ {ok: true, telegram_connected: false}.
Body: {page_token: "Page Access Token"} (შენი ვერიფიცირებული Meta-ბიზნესის აპიდან). → {ok: true, facebook_connected: true, facebook_page_name, webhook_url, verify_token} — ეს ორი მნიშვნელობა ჩასვი შენი Meta-აპის Webhooks განყოფილებაში (Callback URL + Verify Token) და გამოიწერე გვერდის messages, messaging_postbacks ივენთები. Page-ტოკენი პასუხებში არასდროს ბრუნდება. შეცდომები: page_token_required, invalid_page_token, facebook_unreachable, agent_not_found.
→ {ok: true, facebook_connected: false}.
ბალანსი და შევსება
Body: {} (Bearer) → {balance} (USD).
Body: {amount: ≥10} (USD) → გადახდის ბმული: საქართველოდან — ბარათით ლარში (ეროვნული ბანკის კურსით), საზღვარგარეთიდან — დოლარში (PayPal). პასუხში მოძებნე payment_url ან approval_url და გადაამისამართე მომხმარებელი. 400 — თანხა 10 დოლარზე ნაკლებია.
ვიჯეტის ენდფოინთები (ავტორიზაციის გარეშე)
→ ვიჯეტის JavaScript — გასაღების მიხედვით უკვე შეიცავს ბოტის კითხვარს, მისალმებას, ქცევებს და თემას.
Body: {partner_key, query, session_id, deviceInfo:{device_name, ip_address}}
→ 200: {response, DocumentLinks, chat_id, …} — მთავარი ველი response-ია (ბოტის პასუხი, Markdown-ტექსტი); დანარჩენი დამხმარე ველებია და შეიძლება ცარიელი იყოს.
შეცდომები: 400 partner_key is required · 401 Invalid partner_key · 402 ბალანსი < $1 · 403 domain_not_allowed.
/scrap/widget/transcribe/ და /scrap/widget/upload/ ვიჯეტის შიდა ენდფოინთებია (🎤 და 📎 ღილაკები მათ ავტომატურად იყენებენ): მუშაობენ მხოლოდ შესაბამისი ქცევის ჩართვისას (403 გამორთულზე), ხმა ფასიანია, ფაილი ≤ 6MB — დოკუმენტები და სურათები (სურათებზე და დასკანერებულ PDF-ზე ტექსტს OCR კითხულობს).
შეცდომების ცნობარი
| კოდი | როდის | რა ვქნა |
|---|---|---|
400 | არასწორი მოთხოვნა — აკლია ველი ან ტიპი არასწორია (config_must_be_object, Min amount 10 USD…) | შეასწორე body პასუხის error-ის მიხედვით |
401 | არასწორი/ვადაგასული ტოკენი ან Invalid partner_key (გათიშული ბოტის გასაღების ჩათვლით) | ხელახლა შედი ან შეამოწმე გასაღები და ბოტის აქტიურობა |
402 | ბალანსი ამოიწურა (ვიჯეტი მუშაობს ბალანსზე ≥ $1) | შეავსე ბალანსი |
403 | domain_not_allowed — საიტი დომენების სიაში არ არის; ან გამორთული ქცევის ენდფოინთი | დაამატე დომენი სიაში / ჩართე ქცევა |
404 | ბოტი/ფაილი ვერ მოიძებნა (ან სხვისია) | შეამოწმე id |
413 | ფაილი ზედმეტად დიდია | შეამცირე ფაილი |
502 | გარე არხი (Telegram/Facebook) დროებით მიუწვდომელია | ცოტა ხანში სცადე თავიდან |
ლიმიტების ცნობარი
| რა | ლიმიტი |
|---|---|
| ცოდნის ფაილები ბოტზე | 5 ფაილი · თითო ≤ 5MB · ჯამური ტექსტი ≤ 30 000 სიმბოლო |
| ვიჯეტის სესია | 1 საათი უმოქმედობაზე (მოქმედებისას უახლდება) |
| ვიჯეტის 🎤 ხმა | ერთი ჩანაწერი ≤ 15 წთ; 10 წმ სიჩუმეზე ავტო-გაჩერება; სუფთა სიჩუმე უფასოა |
| Telegram ხმოვანი | ≤ 3 წუთი — გრძელზე ბოტი მოკლეს ითხოვს (ხარჯი 0) |
| Messenger აუდიო | ≤ ~2MB |
| ვიჯეტის 📎 ფაილი | ≤ 6MB (PDF/DOCX/XLSX/CSV/TXT/JPG/PNG/WEBP) |
| ლოგო | ≤ 1MB (PNG/JPG/WEBP/GIF) |
| ბალანსი | ვიჯეტი მუშაობს ≥ $1-ზე; მინიმალური შევსება $10; რეგისტრაციაზე $5 საჩუქარი |
კარგი პრაქტიკა
- ბრძანე Markdown: ინსტრუქციაში ჩაუწერე ბოტს პასუხების Markdown-ით ფორმატირება — ვიჯეტი ლამაზად აჩვენებს.
- დააყენე მისალმება: უფასოა და ბოტს პირველი შთაბეჭდილება აძლევს.
- ჩაკეტე დომენები: გაშვებამდე ჩაწერე შენი საიტები დომენების სიაში — გასაღები საჯაროა და ეს ერთადერთი კარიბჭეა.
- config-ს ნაწილობრივ წერე: PATCH merge-ით მუშაობს — გადააგზავნე მხოლოდ შესაცვლელი გასაღები და კითხვარს/თემას ვერ წაშლი შემთხვევით.
- ცოდნა კომპაქტურად: ბოტი ცოდნის კალათას ყოველ პასუხზე მთლიანად ითვალისწინებს — ზედმეტი „წყლის" გარეშე ტექსტი უკეთეს პასუხებს იძლევა.
- ტესტი პორტალშივე: ბოტის რედაქტირებისას გვერდზე ცოცხალი preview-ა — ცვლილება მაშინვე მოქმედებს, გადატვირთვა არ სჭირდება.
კითხვა დაგრჩა? პორტალის „ოსტატი" ტექნიკურ კითხვებზეც პასუხობს, ან მოგვწერე: info@chkuiskolopi.ge