• שדרוג אתר הניהול - חוו"ד המשתמשים

    נעוץ נעול
    1
    36 הצבעות
    1 פוסטים
    1k צפיות
    אין תגובות
  • תקנון קטגוריית עזרה הדדית

    נעוץ נעול הועבר
    1
    16 הצבעות
    1 פוסטים
    2k צפיות
    אין תגובות
  • פאנל ניהול מותאם אישית

    36
    0 הצבעות
    36 פוסטים
    80 צפיות
    B
    @א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": {} } ] } } Spoiler ההנחיה שנתתי לגימני היה לנו שיחה ארוכה בסוף הגענו לקוד הזה אם אני מגביל דרך הקוד זה עובד מעולה הבעיה שב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 של מעלה הקובץ אם חסר מידע בתיעוד תכתוב לי אני ישלים
  • דוח מקיף על השמעות במערכת, איך עושים?

    10
    0 הצבעות
    10 פוסטים
    19 צפיות
    A
    @אA אשמח למקור
  • משחק קליקר לקו -- אפשרי?

    2
    0 הצבעות
    2 פוסטים
    5 צפיות
    י
    @sz קליקרים תוך כדי שיגור חי מדומה - קליקרים להשמעת קבצים
  • שלוחת API

    5
    0 הצבעות
    5 פוסטים
    23 צפיות
    י
    @BEN-ZION תנסה לשלוח לשרת השני, במקום private תשנה ל www
  • הודעה פרטית + הקשת מספר פלאפון

    3
    0 הצבעות
    3 פוסטים
    29 צפיות
    ה
    @sh0548534047 תודה רבה רבה על ההסבר המפורט, לא הצלחתי להבין איזה שורה תגרום להוציא שיחה לשמעון כאילו מה מקשר בין שתי השלוחות?
  • הסרת מספר מרשימה שחורה בשלוחה (מודול הסרת ערך)

    8
    0 הצבעות
    8 פוסטים
    22 צפיות
    י
    @אבטיח הגדרות המודול כאן remove_id_from_list_mode=key_only remove_id_from_list_location_list=/1/XX.ini type=remove_id_from_list remove_id_from_list_key=selection_menu תשנה את הנתיב.
  • השמעת הודעה לפני הפילטר לפי רשימת הצינתוקים

    לא נפתר
    18
    1
    0 הצבעות
    18 פוסטים
    71 צפיות
    ש
    @sh0548534047 למה? - לא כל כך הבנתי במה הסתבכת?
  • איך אני משנה את תפריט שלוחה כוכבית?

    13
    0 הצבעות
    13 פוסטים
    15 צפיות
    ל
    @anti-malware שלחנ כוכסית נקראת בקו Star
  • איך אני מוריד את השלום ל...

    נפתר
    3
    0 הצבעות
    3 פוסטים
    13 צפיות
    S
    תסמן כנפתר
  • 07 לא נכנס

    נפתר
    7
    0 הצבעות
    7 פוסטים
    18 צפיות
    ל
    @נועם-אלימלך זה ניהול נציגים type=queue # מצב ניהול נציגים - מאפשר הוספה והסרה queue_agent_action=add_remove # שם קובץ התור queue_name=queue # הגדרת הודעות (אופציונלי) # המערכת תשמיע "הצטרפת לתור" או "הוסרת מהתור" בהתאם לפעולה
  • נסגר מלהתחבר להמערכת שלי

    16
    0 הצבעות
    16 פוסטים
    26 צפיות
    ה
    @CUBASE סוף סוף הצלחתי ברוך השם להתחבר וזה דווקא היה מאוד פשוט. אתמול פשוט החלפתי את סיסמת הניהול דרך הטלפון והיום ניסתי עוד פעם להתחבר וזה פשוט עבד כרגיל! תודה שוב פעם על העזרה שלך אתמול.
  • 0 הצבעות
    2 פוסטים
    11 צפיות
    B
    @anti-malware יש מודל של הגבלת זמן השהייה בשלוחה פה
  • תזכורת ספירת העומר

    8
    0 הצבעות
    8 פוסטים
    77 צפיות
    B
    @אA מצרף נוסחה לתזכורת ספירת העומר בשלוחה ראשית להגדיר שישמיע הודעה לקמפיין פעיל בלבד שלוחה לדיווח על ספירה שלוחה 2 הוספת ערך זה להוסיף את המספר של המחייג לדיווח type=add_id_to_list enter_id=yes enter_id_type=phone record_name=no say_name=no add_id_to_list_location_list=/2/1/ext add_id_to_list_value_type=EnterID add_id_to_list_key=api_add_3 add_id_to_list_value_first=phone= add_id_to_list_value_change=yes add_id_to_list_end_goto=1 להשתיק הודעה M3411 שלוחה 1 בתוך שלוחה 2 שלוחת API type=api title=דיווח על ספירה api_link=https://private.call2all.co.il/ym/api/UpdateTemplateEntry api_add_0=token=להכניס כאן טוקן api_add_1=templateId=מזהה רשימת תפוצה api_add_2=blocked=1 api_end_goto=נתיב לאן יחזור בסיום להעלות הודעה M1607 "הדיווח התקבל בהצלחה" קוד PHP לשחרור כל החסימות <?php // ========================================== // הגדרות מערכת ופרטי התחברות // ========================================== $token = 'token'; // הכנס כאן את הטוקן שלך $templateId = 'מזהה_רשימה'; // הכנס כאן את מזהה התבנית $apiUrl = 'https://private.call2all.co.il/ym/api/'; // קואורדינטות לחישוב השקיעה (ברירת מחדל: אזור המרכז/ירושלים) $latitude = 31.7690; $longitude = 35.2163; // ========================================== // 1. בדיקת תאריך עברי (בין ט"ז ניסן ל-ה' סיוון) // ========================================== $todayJd = gregoriantojd(date('n'), date('j'), date('Y')); $hebrewDate = cal_from_jd($todayJd, CAL_JEWISH); $monthName = $hebrewDate['monthname']; // שם החודש באנגלית (Nisan, Iyyar, Sivan) $day = $hebrewDate['day']; $isValidDate = false; if ($monthName === 'Nisan' && $day >= 16) { $isValidDate = true; } elseif ($monthName === 'Iyyar') { $isValidDate = true; } elseif ($monthName === 'Sivan' && $day <= 5) { $isValidDate = true; } if (!$isValidDate) { exit("התאריך העברי הנוכחי אינו בטווח של ימי ספירת העומר (ט\"ז ניסן - ה' סיוון). הסקריפט מופסק.\n"); } // ========================================== // 2. בדיקת זמן השקיעה (האם זו הריצה הקרובה ביותר?) // ========================================== $sunInfo = date_sun_info(time(), $latitude, $longitude); $sunsetTime = $sunInfo['sunset']; $currentTime = time(); // אנחנו מריצים את הסקריפט כל 10 דקות (600 שניות). // הריצה הקרובה ביותר לשקיעה תהיה במרחק של עד 5 דקות (300 שניות) מהשקיעה. // אנו משתמשים ב- >= -300 ו- < 300 כדי להבטיח שאם השקיעה נופלת בדיוק באמצע, הסקריפט ירוץ רק פעם אחת. $diff = $currentTime - $sunsetTime; if ($diff < -300 || $diff >= 300) { exit("השעה הנוכחית (" . date('H:i:s', $currentTime) . ") אינה הקרובה ביותר לזמן השקיעה (" . date('H:i:s', $sunsetTime) . "). הסקריפט מופסק.\n"); } echo "תנאי התאריך והשעה התקיימו (שקיעה ב-" . date('H:i:s', $sunsetTime) . "). מתחיל בפעולה מול השרת...\n"; // ========================================== // 3. שליפת רשימת המספרים והוצאת המספרים החסומים // ========================================== $getEntriesUrl = $apiUrl . 'GetTemplateEntries?token=' . urlencode($token) . '&templateId=' . urlencode($templateId); $ch = curl_init($getEntriesUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); if (!$response) { exit("שגיאה בהתקשרות לשרת לשליפת הנתונים.\n"); } $data = json_decode($response, true); $rowidsToUnblock = []; if (isset($data['entries']) && is_array($data['entries'])) { foreach ($data['entries'] as $entry) { if (isset($entry['blocked']) && $entry['blocked'] === true) { $rowidsToUnblock[] = $entry['rowid']; } } } if (empty($rowidsToUnblock)) { exit("לא נמצאו מספרים חסומים ברשימת התפוצה. אין פעולה לבצע.\n"); } // ========================================== // 4. ביטול החסימה למספרים שנמצאו // ========================================== $rowidsString = implode('-', $rowidsToUnblock); $postData = [ 'token' => $token, 'templateId' => $templateId, 'rowids' => $rowidsString, 'action' => 'unblock' ]; $ch = curl_init($apiUrl . 'UpdateTemplateEntries'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData)); $updateResponse = curl_exec($ch); curl_close($ch); echo "בקשת שחרור חסימה נשלחה עבור " . count($rowidsToUnblock) . " מספרים.\n"; echo "תגובת השרת: " . $updateResponse . "\n"; ?> זה עובד בצורה כזו שכל מי שמדווח על ספירה בעצם חוסם את עצמו ברשימת תפוצה הקוד בשקיעה של יום הבא משחרר לכולם את החסימה ככה הם ישמעו שוב את הודעת הקמפיין הקוד מתוזמן לעבוד רק בין ט"ז ניסן ל ה' סיוון אני תיזמנתי לו ריצה כל 10 דקות משעה 18:00 עד 19:59 שזה טווח השקיעה ל10 שנים קדימה כל פעם שהוא רץ הוא בודק אם עכשיו אנחנו בטווח של 5 דקות מהשקיעה אז הוא מבצע איפוס נ.ב. אני משתמש בשלוחה של הקראת הודעה יומית אם תאריך עברי להשמיע את נוסח הספירה Spoiler @אa אם יש לך כוח לסדר את זה בפוסט הסבר מסודר לתועלת הציבור
  • שגיאה! IllegalStateException ב API | מה זה אומר?

    4
    0 הצבעות
    4 פוסטים
    36 צפיות
    Y
    @BEN-ZION אני משתמש עם אותה לוגיקה בעוד מקומות ושם זה כן עובד... אבל מה זה עוזר לי? אני רוצה לדעת מה הבעיה פה, ובשביל זה גם ימות החזירו לי "הודעה" למה זה לא הצליח, רק שאני לא רואה בתיעוד מה ההודעה הזו אומרת...
  • SMS במערכת

    1
    0 הצבעות
    1 פוסטים
    15 צפיות
    אין תגובות
  • וובהוק לאחר עסקה

    10
    0 הצבעות
    10 פוסטים
    23 צפיות
    M
    @799233627 כתב בוובהוק לאחר עסקה: במקרה דרך נדרים פלוס, אבל יכול להיות כל חברה אחרת אתה יכול לקבל מהחברת סליקה עצמה וובהוק, שישלחו לך על כל עסקה, ותמצא דרך להשוות שהוא הלקוח שאכן סלק
  • איפוס מערכת IVR לברירית מחדל

    הועבר
    68
    0 הצבעות
    68 פוסטים
    5k צפיות
    ת
    @שמואל זה דווקא לא עבד לי אבל יש אפשרות פשוט למחוק ידני את כל המערכת ואז להתקשר למערכת ולהקיש 1 וזה מתאפס
  • האם יש דרך להקיש במודל תור (בטא)?

    נפתר
    7
    0 הצבעות
    7 פוסטים
    22 צפיות
    א
    @CUBASE בדקתי עכשיו ועובד, ככל הנראה כיון שהגדרתי שאם הנציג מקיש משהו זה מבצע פעולה, אז גם שאר המקשים מספסיקים לעבוד