פאנל ניהול מותאם אישית
-
-
@אA @לימוד-בתורת-מרן כזה סגנון אני רוצה
-
-
@אa
יש מבין? -
@לימוד-בתורת-מרן
מבין לגמרי
עודכן -
כלום לא הישתנה שאלתי אם תוכל להקפיץ לכאן את הקוד?
-
@לימוד-בתורת-מרן
מבין לגמרי
לך לשרשור המקור -
@אA
הוא מביא אותי לקובץ לא לקוד נכנס שגיאת 404 -
@לימוד-בתורת-מרן
הבאתי את שירשור המקור.
הקובץ הוא של איל משולש לא שלי. -
@אA יצרתי קוד PHP לניהול שלוחה ספציפית
כרגע אני מצליח ליצור את ההגבלה רק דרך הקוד לא דרך המפתח לכן הוא לא מתאים לHTML אני ימשיך לנסות לסדר את זה שיעבוד אם מפתח מוגבל בצורה מלאה בינתיים אני מעלה את הקוד אם יהיה לך זמן לבדוק<?php // === הגדרות מערכת === $token = 'Xh-nVBQis7mP3C58aBaHUOCQfMXxRMj8RQHXZXpbqM'; // החלף בטוקן שלך $baseUrl = 'https://private.call2all.co.il/ym/api/'; $baseExtension = 'ivr2:/18'; // התחלה מהשלוחה הראשית (Root) // === טיפול בבקשות הורדה ישירה === if (isset($_GET['download'])) { $path = $_GET['path']; $url = $baseUrl . "DownloadFile?token=" . $token . "&path=" . urlencode($path); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($path) . '"'); readfile($url); exit; } // === טיפול בבקשות API === if (isset($_GET['ajax'])) { header('Content-Type: application/json'); $action = $_GET['ajax']; function callApi($endpoint, $postData =[], $isMultipart = false) { global $baseUrl, $token; $postData['token'] = $token; $ch = curl_init($baseUrl . $endpoint); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); if ($isMultipart) { curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); } else { curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); } $result = curl_exec($ch); curl_close($ch); return $result; } switch ($action) { case 'get_dir': $path = $_POST['path'] ?? $baseExtension; echo callApi('GetIVR2Dir',['path' => $path]); break; case 'delete': echo callApi('FileAction', ['action' => 'delete', 'what' => $_POST['what']]); break; case 'get_text': echo callApi('GetTextFile',['what' => $_POST['what']]); break; case 'save_text': echo callApi('UploadTextFile',['what' => $_POST['what'], 'contents' => $_POST['contents']]); break; case 'upload': if (isset($_FILES['file'])) { $cfile = new CURLFile($_FILES['file']['tmp_name'], $_FILES['file']['type'], $_FILES['file']['name']); echo callApi('UploadFile', ['path' => $_POST['path'], 'file' => $cfile], true); } else { echo json_encode(['success' => false, 'message' => 'No file uploaded']); } break; } exit; } ?> <!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>מערכת תוכן - ימות המשיח</title> <!-- פונט גוגל ואייקונים --> <link href="https://fonts.googleapis.com/css2?family=Heebo:wght@300;400;600;700&display=swap" rel="stylesheet"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0" /> <style> :root { --primary: #2563eb; --primary-hover: #1d4ed8; --bg-color: #f8fafc; --card-bg: #ffffff; --text-main: #1e293b; --text-muted: #64748b; --border: #e2e8f0; } body { font-family: 'Heebo', sans-serif; margin: 0; padding: 0; background-color: var(--bg-color); color: var(--text-main); } /* אזור עליון */ .top-header { background: white; padding: 20px 40px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border); box-shadow: 0 1px 3px rgba(0,0,0,0.05); } .top-header h1 { margin: 0; font-size: 28px; font-weight: 600; } .actions-bar { display: flex; gap: 15px; } button { display: flex; align-items: center; gap: 8px; font-family: 'Heebo', sans-serif; font-size: 15px; font-weight: 500; cursor: pointer; border: none; border-radius: 8px; padding: 10px 20px; transition: 0.2s; } .btn-primary { background: var(--primary); color: white; } .btn-primary:hover { background: var(--primary-hover); } .btn-secondary { background: #475569; color: white; } .btn-secondary:hover { background: #334155; } .btn-danger { background: #ef4444; color: white; } .btn-danger:hover { background: #dc2626; } .btn-warning { background: #f59e0b; color: white; } .btn-warning:hover { background: #d97706; } .btn-icon { padding: 8px; font-size: 14px; } .main-container { max-width: 1400px; margin: 0 auto; padding: 30px; } /* ניווט / פירורי לחם */ .breadcrumbs { font-size: 16px; color: var(--text-muted); margin-bottom: 20px; display: flex; align-items: center; gap: 10px; } .breadcrumbs span.clickable { cursor: pointer; transition: 0.2s; font-weight: 600; } .breadcrumbs span.clickable:hover { color: var(--primary); } .breadcrumbs .separator { color: #cbd5e1; cursor: default; } /* כרטיסיות (Tabs) */ .tabs-header { display: flex; gap: 30px; border-bottom: 2px solid var(--border); margin-bottom: 30px; } .tab-btn { background: none; border: none; color: var(--text-muted); font-size: 18px; font-weight: 600; padding: 10px 5px; cursor: pointer; border-bottom: 3px solid transparent; margin-bottom: -2px; border-radius: 0; } .tab-btn.active { color: var(--primary); border-bottom-color: var(--primary); } .tab-content { display: none; } .tab-content.active { display: block; } /* גריד תיקיות */ .folders-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px; margin-bottom: 40px; } .folder-card { background: var(--card-bg); border: 1px solid var(--border); border-radius: 12px; padding: 20px; display: flex; align-items: center; gap: 15px; cursor: pointer; transition: box-shadow 0.2s, transform 0.2s; box-shadow: 0 1px 3px rgba(0,0,0,0.05); } .folder-card:hover { box-shadow: 0 10px 15px -3px rgba(0,0,0,0.1); transform: translateY(-2px); border-color: #cbd5e1; } .folder-icon { color: var(--text-muted); font-size: 40px; } .folder-details { flex: 1; } .folder-title { font-size: 20px; font-weight: 700; margin: 0 0 5px 0; } .folder-subtitle { font-size: 14px; color: var(--text-muted); margin: 0; } /* טבלאות קבצים */ .files-section { background: white; border-radius: 12px; border: 1px solid var(--border); overflow: hidden; } .section-title { padding: 15px 20px; background: #f8fafc; border-bottom: 1px solid var(--border); margin: 0; font-size: 16px; color: var(--text-muted); } table { width: 100%; border-collapse: collapse; } th, td { padding: 15px 20px; text-align: right; border-bottom: 1px solid var(--border); } th { color: var(--text-muted); font-weight: 600; font-size: 14px; } tr:hover { background: #f1f5f9; } .td-actions { display: flex; gap: 8px; justify-content: flex-end; } /* עורכי טקסט */ .editor-container { background: white; padding: 20px; border-radius: 12px; border: 1px solid var(--border); } textarea.code-editor { width: 100%; height: 400px; font-family: monospace; font-size: 16px; direction: ltr; padding: 15px; box-sizing: border-box; border: 1px solid var(--border); border-radius: 8px; background: #1e1e1e; color: #d4d4d4; margin-bottom: 15px; resize: vertical;} /* Modal לעריכת כל INI */ .modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.6); z-index: 1000; justify-content: center; align-items: center; } .modal-content { background: white; width: 700px; max-width: 90%; border-radius: 12px; padding: 25px; display: flex; flex-direction: column; gap: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.2); } .modal-content h3 { margin: 0; font-size: 20px; } .modal-actions { display: flex; justify-content: flex-end; gap: 10px; } /* כפתורי העלאה נסתרים */ .hidden-input { display: none; } </style> </head> <body> <!-- כותרת עליונה --> <header class="top-header"> <h1>מערכת תוכן</h1> <div class="actions-bar"> <button class="btn-primary" onclick="document.getElementById('file-upload-new').click()"> <span class="material-symbols-outlined">upload</span> העלה קובץ חדש </button> <input type="file" id="file-upload-new" class="hidden-input" onchange="uploadNewFile(this)"> <!-- אינפוט נסתר להחלפת קובץ קיים --> <input type="file" id="file-replace-input" class="hidden-input" onchange="submitReplaceFile(this)"> </div> </header> <div class="main-container"> <!-- ניווט (פירורי לחם) --> <div class="breadcrumbs" id="breadcrumbs"> <!-- יטען דרך JS --> </div> <!-- כרטיסיות ניווט --> <div class="tabs-header"> <button class="tab-btn active" onclick="switchTab('tab-folders')">תיקיות וקבצים</button> <button class="tab-btn" onclick="switchTab('tab-messages')">הודעות מערכת</button> <button class="tab-btn" onclick="switchTab('tab-settings')">הגדרות שלוחה (ext.ini)</button> </div> <!-- תוכן 1: תיקיות וקבצים --> <div id="tab-folders" class="tab-content active"> <div class="folders-grid" id="folders-grid"> <!-- תיקיות יטענו לכאן --> </div> <div class="files-section"> <h3 class="section-title">קבצים בשלוחה (כולל קבצי שמע, הגדרות ודוחות)</h3> <table> <thead><tr><th>שם קובץ</th><th>סוג</th><th>גודל</th><th>תאריך שינוי</th><th>פעולות</th></tr></thead> <tbody id="files-list"></tbody> </table> </div> </div> <!-- תוכן 2: הודעות מערכת --> <div id="tab-messages" class="tab-content"> <div class="files-section"> <h3 class="section-title">הודעות מערכת מוקלטות (קבצי M)</h3> <table> <thead><tr><th>שם קובץ</th><th>תיאור הודעה</th><th>גודל/אורך</th><th>פעולות</th></tr></thead> <tbody id="messages-list"></tbody> </table> </div> </div> <!-- תוכן 3: הגדרות שלוחה מהירות --> <div id="tab-settings" class="tab-content"> <div class="editor-container"> <h3 style="margin-top:0;">עריכת ext.ini (שלוחה נוכחית)</h3> <p style="color:#64748b; font-size:14px;">כאן תוכל לערוך במהירות את הגדרות התנהגות השלוחה.</p> <textarea id="ini-editor" class="code-editor" spellcheck="false" placeholder="טוען נתונים..."></textarea> <div style="text-align: left;"> <button class="btn-primary" onclick="saveExtIniFile(this)"> <span class="material-symbols-outlined">save</span> שמור הגדרות </button> </div> </div> </div> </div> <!-- מודל לעריכת כל קובץ INI/טקסט שאינו ext.ini --> <div id="file-editor-modal" class="modal-overlay"> <div class="modal-content"> <h3 id="modal-editor-title">עריכת קובץ</h3> <textarea id="modal-editor-textarea" class="code-editor" spellcheck="false"></textarea> <div class="modal-actions"> <button class="btn-secondary" onclick="closeEditorModal()">ביטול</button> <button class="btn-primary" onclick="saveModalFile(this)"> <span class="material-symbols-outlined">save</span> שמור קובץ </button> </div> <input type="hidden" id="modal-editor-path"> </div> </div> <script> const BASE_EXTENSION = '<?php echo $baseExtension; ?>'; let currentPath = BASE_EXTENSION; let currentReplacePath = ''; document.addEventListener('DOMContentLoaded', () => { loadDirectory(currentPath); }); function switchTab(tabId) { document.querySelectorAll('.tab-content').forEach(el => el.classList.remove('active')); document.querySelectorAll('.tab-btn').forEach(el => el.classList.remove('active')); document.getElementById(tabId).classList.add('active'); event.currentTarget.classList.add('active'); } async function loadDirectory(path) { try { const formData = new FormData(); formData.append('path', path); const response = await fetch('?ajax=get_dir', { method: 'POST', body: formData }); const data = await response.json(); if (data.responseStatus === 'ERROR' || data.responseStatus === 'EXCEPTION') { alert('שגיאה: ' + (data.message || data.exceptionMessage)); return; } currentPath = path; renderBreadcrumbs(path); renderFolders(data.dirs ||[]); // איחוד קבצים: שמע, HTML, וגם כל קבצי ה-INI שבשלוחה renderFiles(data.files ||[], data.html || [], data.ini || []); renderMessages(data.messages ||[], data.msgDescriptions || {}); loadExtIniEditor(path); } catch (error) { console.error('Error:', error); alert('שגיאת תקשורת'); } } // ניווט פירורי לחם (חזרה אחורה) מתוקן function renderBreadcrumbs(path) { const container = document.getElementById('breadcrumbs'); container.innerHTML = ''; // כפתור חזרה לראשי (בית) let rootSpan = document.createElement('span'); rootSpan.className = 'material-symbols-outlined clickable'; rootSpan.style.fontSize = '24px'; rootSpan.innerText = 'home'; rootSpan.onclick = () => loadDirectory(BASE_EXTENSION); container.appendChild(rootSpan); // ניקוי הקידומת ivr2: לצורך תצוגה let cleanPath = path.replace(/^ivr2:/, ''); if (cleanPath === '/' || cleanPath === '') return; // אם אנחנו בראשי, אין צורך להמשיך let parts = cleanPath.split('/').filter(p => p.trim() !== ''); let buildPath = 'ivr2:'; parts.forEach((part, index) => { buildPath += (index === 0 ? '' : '/') + part; let clickPath = buildPath; let sep = document.createElement('span'); sep.className = 'separator'; sep.innerText = ' / '; container.appendChild(sep); let span = document.createElement('span'); span.className = 'clickable'; span.innerText = part; span.onclick = () => loadDirectory(clickPath); container.appendChild(span); }); } function renderFolders(dirs) { const grid = document.getElementById('folders-grid'); grid.innerHTML = ''; dirs.forEach(dir => { const title = dir.extTitle || 'ללא תיאור'; const type = dir.extType || 'תיקייה / תפריט'; grid.innerHTML += ` <div class="folder-card" onclick="loadDirectory('${dir.what}')"> <span class="material-symbols-outlined folder-icon">folder</span> <div class="folder-details"> <h3 class="folder-title">${dir.name}</h3> <p class="folder-subtitle">${type} • ${title}</p> </div> </div> `; }); } // טבלת קבצים רגילים + INI function renderFiles(files, htmlFiles, iniFiles) { const tbody = document.getElementById('files-list'); tbody.innerHTML = ''; let allRegular = [...files, ...htmlFiles, ...iniFiles]; if (allRegular.length === 0) { tbody.innerHTML = '<tr><td colspan="5" style="text-align:center;">אין קבצים בשלוחה זו</td></tr>'; return; } allRegular.forEach(file => { let sizeInfo = file.size ? (file.size / 1024).toFixed(2) + ' KB' : '-'; let isEditable = file.fileType === 'INI' || file.fileType === 'HTML' || file.name.endsWith('.txt'); let icon = 'description'; if(file.fileType === 'AUDIO' || file.name.endsWith('.wav') || file.name.endsWith('.mp3')) icon = 'audio_file'; if(file.fileType === 'INI') icon = 'settings'; let editBtn = isEditable ? `<button class="btn-primary btn-icon" onclick="openFileEditorModal('${file.what}', '${file.name}')" title="ערוך קובץ טקסט"><span class="material-symbols-outlined">edit</span></button>` : ''; tbody.innerHTML += ` <tr> <td><span class="material-symbols-outlined" style="vertical-align: middle; margin-left:5px;">${icon}</span> ${file.name}</td> <td>${file.fileType || 'FILE'}</td> <td dir="ltr" style="text-align: right;">${sizeInfo}</td> <td dir="ltr" style="text-align: right;">${file.mtime || '-'}</td> <td class="td-actions"> ${editBtn} <button class="btn-warning btn-icon" onclick="triggerReplace('${file.what}')" title="החלף קובץ קיים"><span class="material-symbols-outlined">find_replace</span></button> <button class="btn-secondary btn-icon" onclick="downloadFile('${file.what}')" title="הורדה"><span class="material-symbols-outlined">download</span></button> <button class="btn-danger btn-icon" onclick="deleteFile('${file.what}')" title="מחיקה"><span class="material-symbols-outlined">delete</span></button> </td> </tr> `; }); } function renderMessages(messages, descriptions) { const tbody = document.getElementById('messages-list'); tbody.innerHTML = ''; if (messages.length === 0) { tbody.innerHTML = '<tr><td colspan="4" style="text-align:center;">אין הודעות מערכת (M) בשלוחה זו</td></tr>'; return; } messages.forEach(file => { let desc = descriptions[file.name.replace('.wav','')] || 'ללא תיאור'; let sizeInfo = file.durationStr ? file.durationStr : (file.size ? (file.size / 1024).toFixed(2) + ' KB' : '-'); tbody.innerHTML += ` <tr> <td style="font-weight:bold; color:var(--primary);">${file.name}</td> <td>${desc}</td> <td dir="ltr" style="text-align: right;">${sizeInfo}</td> <td class="td-actions"> <button class="btn-warning btn-icon" onclick="triggerReplace('${file.what}')" title="החלף קובץ"><span class="material-symbols-outlined">find_replace</span></button> <button class="btn-secondary btn-icon" onclick="downloadFile('${file.what}')" title="הורדה"><span class="material-symbols-outlined">download</span></button> <button class="btn-danger btn-icon" onclick="deleteFile('${file.what}')" title="מחיקה"><span class="material-symbols-outlined">delete</span></button> </td> </tr> `; }); } // --- מנגנון החלפת קובץ --- function triggerReplace(targetPath) { currentReplacePath = targetPath; document.getElementById('file-replace-input').click(); } async function submitReplaceFile(inputElement) { if (inputElement.files.length === 0) return; const file = inputElement.files[0]; // מציג למשתמש התראת טעינה alert('הקובץ מועלה כעת, אנא המתן...'); const formData = new FormData(); formData.append('path', currentReplacePath); // שומרים על הנתיב המקורי בדיוק! formData.append('file', file); try { const response = await fetch('?ajax=upload', { method: 'POST', body: formData }); const result = await response.json(); if (result.responseStatus === 'OK' || result.path) { alert('הקובץ הוחלף בהצלחה!'); loadDirectory(currentPath); } else { alert('שגיאה בהחלפה: ' + JSON.stringify(result)); } } catch (error) { alert('שגיאת תקשורת בהחלפת הקובץ'); } inputElement.value = ''; // ניקוי הזיכרון של האינפוט } // --- העלאת קובץ חדש רגיל --- async function uploadNewFile(inputElement) { if (inputElement.files.length === 0) return; const file = inputElement.files[0]; // בגלל שזה קובץ חדש, מצרפים את שם הקובץ לנתיב התיקייה הנוכחית let targetPath = currentPath; if (targetPath === '/') targetPath = 'ivr2:'; else if (!targetPath.startsWith('ivr2:')) targetPath = 'ivr2:' + targetPath; targetPath = targetPath + '/' + file.name; const formData = new FormData(); formData.append('path', targetPath); formData.append('file', file); alert('מעלה קובץ חדש, אנא המתן...'); try { const response = await fetch('?ajax=upload', { method: 'POST', body: formData }); const result = await response.json(); if (result.responseStatus === 'OK' || result.path) { alert('הקובץ הועלה בהצלחה!'); loadDirectory(currentPath); } else { alert('שגיאה: ' + JSON.stringify(result)); } } catch (error) { alert('שגיאת תקשורת'); } inputElement.value = ''; } function downloadFile(what) { window.location.href = '?download=1&path=' + encodeURIComponent(what); } async function deleteFile(what) { if (!confirm('האם למחוק קובץ זה לצמיתות?')) return; const formData = new FormData(); formData.append('what', what); await fetch('?ajax=delete', { method: 'POST', body: formData }); loadDirectory(currentPath); } // --- מנגנון עריכת קבצי INI (במודל צף) --- async function openFileEditorModal(what, name) { document.getElementById('modal-editor-title').innerText = `עורך קובץ: ${name}`; document.getElementById('modal-editor-path').value = what; document.getElementById('modal-editor-textarea').value = 'טוען תוכן...'; document.getElementById('file-editor-modal').style.display = 'flex'; const formData = new FormData(); formData.append('what', what); try { const response = await fetch('?ajax=get_text', { method: 'POST', body: formData }); const result = await response.json(); document.getElementById('modal-editor-textarea').value = result.contents !== undefined ? result.contents : ''; } catch (e) { document.getElementById('modal-editor-textarea').value = 'שגיאה בטעינת הקובץ'; } } function closeEditorModal() { document.getElementById('file-editor-modal').style.display = 'none'; } async function saveModalFile(btn) { const what = document.getElementById('modal-editor-path').value; const contents = document.getElementById('modal-editor-textarea').value; btn.innerHTML = '<span class="material-symbols-outlined">hourglass_empty</span> שומר...'; const formData = new FormData(); formData.append('what', what); formData.append('contents', contents); try { const response = await fetch('?ajax=save_text', { method: 'POST', body: formData }); const result = await response.json(); if (result.responseStatus === 'OK') { alert('הקובץ נשמר!'); closeEditorModal(); loadDirectory(currentPath); } else { alert('שגיאה בשמירה'); } } catch (e) { alert('שגיאת תקשורת'); } btn.innerHTML = '<span class="material-symbols-outlined">save</span> שמור קובץ'; } // --- מנגנון עריכת ext.ini המהיר (בכרטיסייה ה-3) --- async function loadExtIniEditor(path) { let targetPath = path; if (targetPath === '/') targetPath = 'ivr2:'; else if (!targetPath.startsWith('ivr2:')) targetPath = 'ivr2:' + targetPath; const editor = document.getElementById('ini-editor'); editor.value = 'טוען...'; const formData = new FormData(); formData.append('what', targetPath + '/ext.ini'); try { const response = await fetch('?ajax=get_text', { method: 'POST', body: formData }); const result = await response.json(); editor.value = result.contents !== undefined ? result.contents : ''; } catch (e) { editor.value = ''; } } async function saveExtIniFile(btn) { let targetPath = currentPath; if (targetPath === '/') targetPath = 'ivr2:'; else if (!targetPath.startsWith('ivr2:')) targetPath = 'ivr2:' + targetPath; const contents = document.getElementById('ini-editor').value; btn.innerHTML = '<span class="material-symbols-outlined">hourglass_empty</span> שומר...'; const formData = new FormData(); formData.append('what', targetPath + '/ext.ini'); formData.append('contents', contents); try { await fetch('?ajax=save_text', { method: 'POST', body: formData }); alert('הגדרות השלוחה נשמרו בהצלחה!'); loadDirectory(currentPath); } catch (e) { alert('שגיאת תקשורת'); } btn.innerHTML = '<span class="material-symbols-outlined">save</span> שמור הגדרות'; } </script> </body> </html>אולי ההגבלות שעשיתי למפתח לא טובות אני צריך גם לבדוק את זה
{ "tokenNike": "הגבלה לשלוחה 18", "tokenUser": "pIi0j5kxIJmxCGStG3DNiQ", "tokenMore": { "ws_parms_whitelist": [ "wath", "path", "what" ], "ws_parms_mismatch_action": "remove", "default_acl_policy": "deny", "acl_rules": [ { "ip": [], "name": null, "active": true, "params": [ "what=ivr2:/18/**", "wath=ivr2:/18/**", "path=ivr/18/**" ], "policy": "allow", "endpoint": [], "set_params": {} } ] } }ההנחיה שנתתי לגימני היה לנו שיחה ארוכה בסוף הגענו לקוד הזה אם אני מגביל דרך הקוד זה עובד מעולה הבעיה שבHTML כל אחד יכול לשנות
אני צריך קוד PHP משולב HTML לניהול המערכת הטלפונית שלי אני צריך יכולת להעלות קבצים להוריד קבצים להציג את הקבצים הקיימים שאני בוחר שלוחה מחיקת קבצים עריכת קבצי EXT עריכת קבצי INI החיבור הוא באמצעות מפתח טוקן אני רוצה להטמיע בקוד מה שלוחה שממנה מתחיל להציג דוגמה משלוחה 8 וכל התיקיות שבתוכה שאני נכנס מציג לי את עץ התיקיות בצד ימין בחלונית שמה אני יכול לבחור לאיזה תיקייה להיכנס ובצד שמאל אחרי שבחרתי תיקייה מציג את הקבצים שבתוך התיקייה מצרף תיעוד API של הפעולות הנצרכות כתובת לשליחת הבקשות https://private.call2all.co.il/ym/api/ העלאה והורדה העלאת קובץ הפקודה היא - UploadFile מתודת פניה יש לפנות ב-HTTP POST בפורמט multipart/form-data. (פרמטרים כמו token path וכדומה ניתן לצרף בגוף הפנייה או במחרוזת השאילתה כמו בבקשת GET) שימו לב! ניתן לעלות קובץ בודד בכל פנייה. חשוב לשים לב שיש מגבלה על גודל הקובץ שאפשר לעלות בבקשה אחת (נכון לתאריך 28/09/2022 המגבלה היא 50MB) ולכן אם הקובץ שלכם שוקל יותר מזה, צריך לפצל את הקובץ ולהעלות אותו בחלקים נפרדים וכפי שיובא להלן. הפרמטרים הנדרשים פרמטר תיאור הערות token טוקן חובה path נתיב להעלאה חובה. עבור העלאת קבצים לתיקיות במערכת יש לציין בהתחלה ivr2: ולאחר מכן את הנתיב המלא. למשל לקובץ 000.wav בתיקייה 5 הנתיב יהיה ivr2:5/000.wav. שימו לב שבהעלאה רגילה חובה לציין את שם הקובץ הרצוי, בהעלאה עם מספור אוטומטי (ראה להלן) יש לציין את התיקייה בלבד convertAudio המרת הקובץ בוליאני (1/0). ברירת המחדל היא ללא המרה. אם convertAudio = 1, הקובץ שהועלה יומר אוטומטית לפורמט wav המתאים לטלפוניה. קובץ המקור יכול להיות בכל אחד מפורמטי האודיו הפופולריים (MP3, OGG, WMA וכו '). הערה: פרמטר הנתיב חייב להיות בשם של קובץ היעד לאחר ההמרה (כך שהוא חייב להיות עם סיומת .wav) autoNumbering מספור אוטומטי כנ"ל tts הצהרה על קובץ tts בוליאני (1/0). נצרך במקרה של מספור אוטומטי לקבצי tts כדי שהמערכת לא תתן לקובץ את הסיומת wav אלא tts פיצול קובץ לחלקים נפרדים והעלאה לשרת שלב א' - העלאת הקבצים פרמטר תיאור דוגמה qquuid ID יש ליצור באופן רנדומלי לפני הבקשה הראשונה 2017390a-60cf-44ea-822f-27017c13de69 qqpartindex אינדקס העלאה 1 qqpartbyteoffset עד כה עלה ללא הבקשה הנוכחית בבתים 4000000 qqchunksize גודל הבקשה הנוכחית בבתים 4000000 qqtotalparts סה"כ חלקים לביצוע (מתחיל ב0 כולל הבקשה האחרונה של החיבור) 8 qqtotalfilesize גודל כולל של הקובץ בבתים 29863882 qqfilename השם המקורי של הקובץ בוקר טוב.mp3 qqfile מקטע של הקובץ שאותו אנחנו מעלים בבקשה הנוכחית (קובץ) uploader מחלקה שמבצעת את העלאה yemot-admin שלב ב' - סיום העלאה ובקשת חיבור לקבצים בסיום העלאה יש לפנות אל - UploadFile?done הפרמטרים שיש לצרף לבקשה פרמטר תיאור דוגמה token טוקן כנ"ל path נתיב כנ"ל convertAudio המרת אודיו כנ"ל autoNumbering מספור אוטומטי כנ"ל tts קובץ tts כנ"ל qquuid ID של מזהה הפעולה 2017390a-60cf-44ea-822f-27017c13de69 qqfilename שם מקורי בוקר טוב.mp3 qqtotalfilesize גודל כולל 29863882 qqtotalparts סך הכל חלקים 8 מאפייני תגובת השרת: מאפיין סוג הסבר path string נתיב הקובץ שהועלה, כפי שהועבר על ידי פרמטר הנתיב size long גודל הקובץ שהועלה בבייטים אם convertAudio = 1, יוחזרו בתגובה מאפיינים נוספים : מאפיין סוג הסבר convertedSize long גודל קובץ ה- WAV שהומר בבייטים duration double משך האודיו בשניות במקרה של שגיאה בביצוע ההעברה ההודעות והקודים האפשריים הם כדלקמן: messageCode message הסבר 105 System error שגיאה כללית במהלך הטיפול בהעלאה 107 File upload expected לא נמצאה קובץ להעלאה בבקשה 108 Only single upload per request is supported הועלה יותר מקובץ אחד בבקשה אחת 109 path is required דרוש נתיב 110 path is invalid הנתיב אינו חוקי על מנת לבדוק העלאות HTTP ניתן להשתמש בטופס פשוט זה: https://www.call2all.co.il/ym/api_upload_test.php Eמנותק eliyahu ניהול 4 בנוב׳ 2020, 17:33 הורדת קובץ הפקודה היא - DownloadFile הפרמטרים הנדרשים: פרמטר תיאור הערות token טוקן path שם הקובץ להורדה בהמשך יפורט איך לציין את הנתיב של כל קובץ מאפייני תגובת השרת: במידה והקובץ קיים - התגובה תכיל את את תוכן הקובץ המבוקש. במידה והקובץ לא קיים או שהתרחשה שגיאה - התגובה תהיה HTTP 404 Not Found. הערה: שימו לב שהתגובה לבקשה זו אינה JSON (בשונה משאר הבקשות) הצגת קבצים וניהול הקבצים הצגת תוכן שלוחה (תיקייה) הפקודה היא GetIVR2Dir הפרמטרים הנדרשים פרמטר תיאור הערות token טוקן חובה path נתיב תיקייה חובה. לדוגמה: / עבור שלוחה ראשית. 1 עבור שלוחה 1 ext/1 עבור שלוחה ext/1 filesFrom הצג קבצים מ רשות. 0 יציג מהקובץ הראשון 1 יציג מהקובץ השני וכן הלאה. ברירת מחדל מציג מהקובץ הראשון. filesLimit הצג קבצים עד רשות. לדוגמה, 5 יציג את הקובץ החמישי (כולל). ברירת מחדל מציג עד הקובץ האחרון orderBy מיין קבצים לפי ראה להלן "ערכים אפשריים לפרמטר orderBy" orderDir סדר קבצים asc - סדר עולה. desc - סדר יורד. ערכים אפשריים לפרמטר orderBy ערך תיאור name שם קובץ (ברירת מחדל) date תאריך יצירה mtime תאריך שינוי אחרון customerdid מספר מערכת uploader מעלה הקובץ size גודל source מקור מאפייני תגובת השרת מאפיין סוג הסבר extIni object אובייקט הכולל את הגדרות השלוחה thisPath string נתיב תיקייה נוכחית parentPath string נתיב תיקיית אב dirs Array מערך הכולל את התיקיות והשלוחות שבתיקייה הנוכחית files Array מערך הכולל את הקבצים שבתיקייה הנוכחית (מלבד קבצי ini ו-html שנמצאים במערך נפרד) ini Array מערך הכולל את קבצי ההגדרות (ini) שבשלוחה messages Array מערך הכולל את הודעות המערכת הקשורות לשלוחה html Array מערך הכולל את קבצי הדוחות (html) שבשלוחה msgDescriptions object אובייקט הכולל את התיאור של כל הודעות המערכת בשלוחה (למשל M0000=הודעת ברוכים הבאים) מאפיינים משותפים לאובייקטים במערכים "dirs" "files" "ini" "messages" "html" מאפיין סוג הסבר exists boolean האם התיקייה/קובץ קיימים name string שם התיקייה/קובץ uniqueId string מזהה ייחודי לתיקייה/קובץ what string נתיב תיקייה/קובץ fileType string סוג תיקייה/קובץ מאפיינים משותפים לאובייקטים במערכים "files" "ini" "messages" "html" מאפיין סוג הסבר size int גודל קובץ (בבתים) mtime string תאריך שינוי אחרון מאפיינים משותפים לאובייקטים במערכים "files" "messages" הערה: המאפיינים הבאים הינם עבור קבצי שמע בלבד מאפיין סוג הסבר duration אורך (בדקות) durationStr string אורך בפורמט mm:ss customerDid string מספר מערכת בה נוצר הקובץ meta string אובייקט המכיל מידע נוסף על הקובץ date string זמן יצירת קובץ dd/mm/yyyy hh:mm source string מקור הקובץ phone string טלפון יוצר הקובץ ip string כתובת IP של מעלה הקובץ מאפייני אובייקטים במערך dirs הערה: המאפיינים הבאים הינם עבור תיקיות המוגדרות כשלוחה ולא עבור תיקיות רגילות מאפיין סוג הסבר extType string סוג שלוחה extTitle string תיאור שלוחה Eמנותק eliyahu ניהול 4 בנוב׳ 2020, 17:35 קבלת מידע על קובץ בודד הפקודה היא - GetFile הפרמטרים הנדרשים פרמטר תיאור סוג token טוקן string what נתיב במערכת string (דוגמה למטה) דוגמה לנתיב what=ivr2:2/000.wav /// מידע על קובץ 000 בשלוחה 2 תגובה (במידה והקובץ קיים) דומה למאפיינים של קובץ כפי שמופיע בGetIVR2Dir במידה וקובץ לא קיים יחזור שגיאה { "responseStatus": "ERROR", "message": "file does not exist", "messageCode": null, "yemotAPIVersion": 6 } במידה ונתיב לא חוקי יחזור { "responseStatus": "EXCEPTION", "exceptionClass": "IllegalArgumentException", "exceptionMessage": "bad descriptor format. don't know what is xyz", "nestedException": null, "yemotAPIVersion": 6 } Eמנותק eliyahu ניהול 4 בנוב׳ 2020, 17:35 ניהול תיקיות וקבצים הפקודה היא FileAction הפרמטרים הנדרשים פרמטר תיאור הערה token טוקן action סוג הפעולה לביצוע ראה להלן what נתיב ראה להלן target יעד ראה להלן בפרמטר action האפשרויות הקיימות הן: copy - העתקה move - העברה (לשינוי שם של שלוחה או קובץ יש להשתמש בהעברה) delete - מחיקה בפרמטר what האפשרויות הקיימות הן: ניהול קובץ בודד או שלוחה בודדת. ניהול קבצים מרובים כאשר בפרמטר what יש לציין כל קובץ או שלוחה בנפרד. לדוגמה: ניהול קובץ בתבנית קמפיין. ראה כאן u r l F i l e A c t i o n ? t o k e n = urlFileAction?token= {token}&action=${action}&what0=ivr2:1&what1=ivr2:2/ext.ini בדוגמה: ניהול שלוחה 1 וניהול קובץ ext.ini שבשלוחה 2. בפעולה מסוג העברה או העתקה חובה לציין פרמטר target. האפשרויות הקיימות הן: בניהול קבצים מרובים או שלוחות מרובות יש לציין את נתיב היעד הרצוי. לדוגמה, במידה והיעד הוא שלוחה 1 יש לציין את הנתיב כך target=ivr2:1. הערה: שימו לב! השם המקורי נשמר. במידה ומדובר בהעברת או העתקת קבצים עם שם בעל מספר סידורי שמות הקבצים ישתנו בהתאם לשמות הקבצים בשלוחת היעד. (לדוגמה, אם בוצעה העתקה של קובץ 001 משלוחה 2 לשלוחה 1 ששם קיים קובץ בשם 050 אז השם של הקובץ שהועתק ישתנה ל-051). בניהול קובץ בודד או שלוחה בודדת ניתן גם לציין נתיב מלא כולל השם הרצוי ביעד. מאפייני תגובת השרת: מאפיין סוג הסבר הערה reports array מערך אובייקטים ראה להלן success boolean האם הפעולה בוצעה במידה וכן, יופיע הערך true. במידה ולא, יופיע הערך false action סוג הפעולה שבוצעה תבנית אובייקט מאפיין ערך what נתיב מקור target נתיב יעד success האם בוצע (זהה לתיאור לעיל) Eמנותק eliyahu ניהול 4 בנוב׳ 2020, 17:36 קבלת תוכן קובץ טקסט הפקודה היא - GetTextFile הפרמטרים הנדרשים: פרמטר תיאור הערות token טוקן what נתיב מלא כולל שם הקובץ והסיומת לדוגמה ivr2:1/ext.ini מאפייני תגובת השרת: מאפיין סוג ערך contents string התוכן הכתוב בקובץ file array מערך אובייקטים (ראה להלן) תבנית אובייקט: מאפיין סוג ערך exists boolean האם הפעולה בוצעה (במידה וכן, יופיע הערך true. במידה ולא, יופיע הערך false) name string שם הקובץ uniqueId string מזהה תנועה ייחודי fileType string סוג קובץ (למשל: INI) size int גודל קובץ mtime string תאריך ושעה שהקובץ השתנה (פורמט: dd/MM/yyyy HH:mm) what string נתיב מלא Eמנותק eliyahu ניהול 4 בנוב׳ 2020, 17:36 העלאת טקסט לקובץ הערה: במידה והקובץ לא קיים בשלוחה, ייווצר קובץ חדש. הפקודה היא - UploadTextFile הפרמטרים הנדרשים: פרמטר תיאור הערות token טוקן what שם הקובץ והסיומת יש לציין את הנתיב המלא. לדוגמה ivr2:1/ext.ini contents תוכן הקובץ להעלאה במידה וקיים כבר טקסט בקובץ הוא יימחק אין מאפיינים מיוחדים בתגובת השרת Eמנותק eliyahu ניהול 4 בנוב׳ 2020, 17:49 עדכון הגדרות שלוחה שימו לב! בשונה מהפקודה UploadTextFile כאן המערכת לא מוחקת את הקיים בקובץ ext.ini והדבר היחיד שמשתנה הוא מה שאתם שולחים לשרת הפקודה היא - UpdateExtension הפרמטרים הנדרשים: פרמטר תיאור / הערות token טוקן path נתיב בפרמטרים הנוספים תוכלו לצרף ערכים לעדכון בקובץ ext.ini לדוגמה: u r l U p d a t e E x t e n s i o n ? t o k e n = urlUpdateExtension?token= {token}&path=ivr2:1&type=menu&title=בדיקה&enter_id=yes בדוגמה, עדכון הגדרות לשלוחה 1, סוג השלוחה - תפריט, כינוי השלוחה - בדיקה, תתבצע כניסה לפי מספר אישי. אין מאפיינים מיוחדים בתגובת השרת הערה: במידה והשלוחה לא קיימת במערכת, תיווצר שלוחה חדשה. קבלת מידע כללי על תיקיה (שלוחה) הפקודה היא GetIVR2DirStats הפרמטרים הנדרשים פרמטר תיאור הערות token טוקן חובה path נתיב תיקייה חובה. לדוגמה: / עבור שלוחה ראשית. 1 עבור שלוחה 1 ext/1 עבור שלוחה ext/1 מאפייני תגובת השרת מאפיין סוג הסבר type string סוג השלוחה thisPath string נתיב תיקייה נוכחית parentPath string נתיב תיקיית אב dirsCount int כמות תיקיות בשלוחה filesCount int כמות קבצים בשלוחה contentFilesCount int כמות קבצי שמע בשלוחה minFile object מידע על קובץ השמע הנמוך בשלוחה maxFile object מידע על קובץ השמע הגבוה בשלוחה מאפייני קובץ שמגיעים באובייקטים minFile/maxFile מאפיין סוג הסבר exists boolean האם התיקייה/קובץ קיימים name string שם התיקייה/קובץ uniqueId string מזהה ייחודי לתיקייה/קובץ what string נתיב תיקייה/קובץ fileType string סוג תיקייה/קובץ size int גודל קובץ (בבתים) mtime string תאריך שינוי אחרון duration אורך (בדקות) durationStr string אורך בפורמט mm:ss customerDid string מספר מערכת בה נוצר הקובץ meta string אובייקט המכיל מיגע נוסף על הקובץ date string זמן יצירת קובץ dd/mm/yyyy hh:mm source string מקור הקובץ phone string טלפון יוצר הקובץ ip string כתובת IP של מעלה הקובץ אם חסר מידע בתיעוד תכתוב לי אני ישלים -
@BEN-ZION
אולי בהמשך לכאן @תפארת-יעקבב יוכל לומר לנו אם משהו התקדם ואם הוא משחרר את זה לציבור זה אחד מהדברים היותר נצרכים אבל איך שזה נשמע שם זה לא מגביל לפי הרשאת המפתח ג"כ (הוא אומר שהוא יכניס את זה לפיתוח).

