• הבהרה בעניין הצעות פיתוח

    נעוץ נעול
    1
    15 הצבעות
    1 פוסטים
    2k צפיות
    אין תגובות
  • 2 הצבעות
    26 פוסטים
    432 צפיות
    L
    @אA @אA כתב בהעלאת תקיות שלימות בצורה מסודרת להפליא בלי להתאמץ🥱: הקוד המעודכן: <!DOCTYPE html> <html lang="he" dir="rtl"> <head> <meta charset="UTF-8"> <title>מעלה תקיות וקבצים למערכת - עץ שלוחות</title> <style> :root { --primary: #3498db; --success: #2ecc71; --danger: #e74c3c; --bg: #f4f7f6; --dark: #2c3e50; } body { font-family: 'Segoe UI', Arial, sans-serif; margin: 0; background-color: var(--bg); color: var(--dark); text-align: right; } .wrapper { max-width: 900px; margin: 40px auto; padding: 0 20px; position: relative; } .reset-btn { position: absolute; top: -10px; left: 20px; background: var(--danger); color: white; border: none; padding: 8px 15px; border-radius: 5px; cursor: pointer; font-size: 14px; font-weight: bold; transition: all 0.3s; } .card { background: white; padding: 30px; border-radius: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.05); margin-bottom: 25px; border: 1px solid #eee; } h2 { margin-top: 0; color: var(--dark); border-bottom: 3px solid var(--primary); display: inline-block; padding-bottom: 10px; } .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px; } .input-group { display: flex; flex-direction: column; gap: 8px; } label { font-weight: bold; font-size: 14px; } input { padding: 12px; border: 2px solid #eee; border-radius: 8px; font-size: 16px; } .full-width { grid-column: 1 / -1; } .btn-main { background: var(--primary); color: white; border: none; padding: 15px; border-radius: 8px; cursor: pointer; font-size: 18px; font-weight: bold; width: 100%; transition: all 0.3s; } .btn-main:hover { background: #2980b9; } .btn-main:disabled { background: #bdc3c7; cursor: not-allowed; } .progress-wrapper { margin-top: 25px; display: none; padding: 15px; background: #fafafa; border-radius: 10px; border: 1px solid #eee; } .progress-container { width: 100%; background: #e0e0e0; height: 35px; border-radius: 20px; overflow: hidden; position: relative; border: 1px solid #ccc; } .progress-bar { height: 100%; width: 0%; background: linear-gradient(45deg, #2ecc71 25%, #27ae60 25%, #27ae60 50%, #2ecc71 50%, #2ecc71 75%, #27ae60 75%, #27ae60); background-size: 40px 40px; animation: move-stripes 2s linear infinite; transition: width 0.4s; } @keyframes move-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } .progress-text { position: absolute; width: 100%; text-align: center; top: 0; line-height: 35px; color: #fff; font-weight: 900; text-shadow: 1px 1px 2px rgba(0,0,0,0.5); } .log-box { background: #1e1e1e; color: #d4d4d4; padding: 20px; border-radius: 10px; font-family: 'Consolas', monospace; height: 300px; overflow-y: auto; font-size: 13px; line-height: 1.6; border: 4px solid #333; } .log-info { color: #5dade2; } .log-success { color: #58d68d; font-weight: bold; } .log-error { color: #ec7063; } .log-warn { color: #f4d03f; } </style> </head> <body> <div class="wrapper"> <button class="reset-btn" onclick="location.reload()">✕ איפוס תהליך</button> <div class="card"> <h2>מעלה תקיות וקבצים למערכת - עץ שלוחות</h2> <div class="grid"> <div class="input-group"> <label>טוקן:</label> <input type="text" id="token"> </div> <div class="input-group"> <label>שלוחת יעד:</label> <input type="text" id="targetPath"> </div> <div class="input-group" style="flex-direction: row; align-items: center; gap: 5px;"> <input type="checkbox" id="autoFileNum"> <label for="autoFileNum">מספור קבצים (אוטומטי)</label> </div> <div class="input-group" style="flex-direction: row; align-items: center; gap: 5px;"> <input type="checkbox" id="autoFolderNum"> <label for="autoFolderNum">מספור שלוחות (אוטומטי)</label> </div> <div class="input-group full-width"> <label>בחירת תיקייה:</label> <input type="file" id="folderInput" webkitdirectory> </div> <button id="startBtn" class="btn-main" onclick="processUpload()">התחל העלאה</button> </div> <div class="progress-wrapper" id="progBox"> <div class="progress-container"> <div class="progress-bar" id="progBar"></div> <div class="progress-text" id="progText">0%</div> </div> </div> </div> <div class="card"> <div class="log-box" id="logBox">ממתין...</div> </div> </div> <script> const CHUNK_SIZE = 4 * 1024 * 1024; const MAX_SINGLE_FILE = 50 * 1024 * 1024; const sleep = ms => new Promise(res => setTimeout(res, ms)); const generateUUID = () => 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { let r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); function addLog(msg, type = "info") { const logBox = document.getElementById('logBox'); logBox.innerHTML += `<div class="log-${type}">> ${msg}</div>`; logBox.scrollTop = logBox.scrollHeight; } async function processUpload() { const token = document.getElementById('token').value.trim(); const targetPath = document.getElementById('targetPath').value.trim().replace(/\/$/, ""); const fileList = document.getElementById('folderInput').files; const autoFileNum = document.getElementById('autoFileNum').checked; const autoFolderNum = document.getElementById('autoFolderNum').checked; if (!token || !fileList.length || !targetPath) { alert("מלא פרטים"); return; } document.getElementById('startBtn').disabled = true; document.getElementById('progBox').style.display = 'block'; const folderStructure = {}; for (let file of fileList) { const parts = file.webkitRelativePath.split('/'); parts.shift(); const fileName = parts.pop(); const relPath = parts.join('/'); if (!folderStructure[relPath]) folderStructure[relPath] = []; folderStructure[relPath].push({ name: fileName, file: file }); } if (!folderStructure[""]) folderStructure[""] = []; const sortedPaths = Object.keys(folderStructure).sort((a,b) => (a===""?-1:b===""?1:a.split('/').length - b.split('/').length)); // לוגיקת מספור שלוחות const folderRenameMap = {}; if (autoFolderNum) { sortedPaths.forEach(path => { if (path === "") return; const parts = path.split('/'); const mappedParts = []; parts.forEach((part, index) => { const parentPath = parts.slice(0, index).join('/'); const siblings = sortedPaths.filter(p => p !== "" && p.split('/').length === index + 1 && p.split('/').slice(0, index).join('/') === parentPath).sort(); mappedParts.push(siblings.indexOf(parts.slice(0, index + 1).join('/')) + 1); }); folderRenameMap[path] = mappedParts.join('/'); }); } for (let i = 0; i < sortedPaths.length; i++) { const relPath = sortedPaths[i]; const finalSubPath = (autoFolderNum && relPath !== "") ? folderRenameMap[relPath] : relPath; const currentIvrPath = finalSubPath ? `${targetPath}/${finalSubPath}` : targetPath; const files = folderStructure[relPath]; // ext.ini const extFileObj = files.find(f => f.name.toLowerCase().split('.')[0] === 'ext'); let extContent = extFileObj ? await extFileObj.file.text() : (relPath === "" ? "type=menu" : "type=playfile"); await uploadFileNormal(token, `${currentIvrPath}/ext.ini`, new Blob([extContent], {type: 'text/plain'})); addLog(`שלוחה ${currentIvrPath} הוגדרה`, "success"); files.sort((a, b) => a.name.localeCompare(b.name, undefined, {numeric: true})); let audioCount = 0; for (let fObj of files) { if (fObj.name.toLowerCase().split('.')[0] === 'ext') continue; let destName = fObj.name; let blob = fObj.file; if (/\.(wav|mp3|ogg|wma)$/i.test(fObj.name)) { destName = (autoFileNum ? audioCount.toString().padStart(3, '0') : fObj.name.replace(/\.[^/.]+$/, "")) + ".wav"; audioCount++; } else if (fObj.name.toLowerCase().includes('.tts')) { destName = fObj.name.split('.')[0] + ".tts"; blob = new Blob([await fObj.file.text()], {type: 'text/plain'}); } if (blob.size > MAX_SINGLE_FILE) { await uploadFileChunked(token, currentIvrPath, destName, blob); } else { await uploadFileNormal(token, `${currentIvrPath}/${destName}`, blob); } addLog(`הועלה: ${destName}`, "info"); } const pct = Math.round(((i + 1) / sortedPaths.length) * 100); document.getElementById('progBar').style.width = pct + '%'; document.getElementById('progText').innerText = pct + '%'; } addLog("העלאה הסתיימה בהצלחה!", "success"); document.getElementById('startBtn').disabled = false; } async function uploadFileNormal(token, fullPath, blob) { const fd = new FormData(); fd.append('token', token); fd.append('path', `ivr2:${fullPath}`); fd.append('qqfile', blob, fullPath.split('/').pop()); const res = await fetch(`https://www.call2all.co.il/ym/api/UploadFile`, { method: 'POST', body: fd }); return await res.json(); } async function uploadFileChunked(token, folderPath, fileName, fileBlob) { const uuid = generateUUID(); const totalParts = Math.ceil(fileBlob.size / CHUNK_SIZE); addLog(`מפצל קובץ גדול: ${fileName}`, "warn"); for (let index = 0; index < totalParts; index++) { const start = index * CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE, fileBlob.size); const chunk = fileBlob.slice(start, end); const fd = new FormData(); fd.append('qquuid', uuid); fd.append('qqpartindex', index); fd.append('qqpartbyteoffset', start); fd.append('qqchunksize', chunk.size); fd.append('qqtotalparts', totalParts); fd.append('qqtotalfilesize', fileBlob.size); fd.append('qqfilename', fileName); fd.append('uploader', 'yemot-admin'); fd.append('qqfile', chunk, fileName); await fetch(`https://www.call2all.co.il/ym/api/UploadFile`, { method: 'POST', body: fd }); } const finalUrl = `https://www.call2all.co.il/ym/api/UploadFile?done&token=${token}&path=ivr2:${folderPath}/${fileName}&qquuid=${uuid}&qqfilename=${fileName}&qqtotalfilesize=${fileBlob.size}&qqtotalparts=${totalParts}`; const res = await fetch(finalUrl, { method: 'POST' }); return await res.json(); } </script> </body> </html> זה
  • שכפול השלוחות

    2
    0 הצבעות
    2 פוסטים
    40 צפיות
    א
    @נועם-אלימלך צריך בשביל זה שרת
  • סנכרון בין מנותבים בקמפיינים לפנויים בתור

    2
    0 הצבעות
    2 פוסטים
    27 צפיות
    א
    @רשבי [image: 1770227800576-b31fb244-cbdb-47e3-bfb9-00a194e798fa-image.png]
  • בוט לתמלול טקסט למשתמשי מסלול אינטרנט מצומצם

    5
    0 הצבעות
    5 פוסטים
    101 צפיות
    מ
    @יעקב-יצחק רעיון יפה, אם מישהו עשה את זה אז שיעדכן פה. תודה.
  • שלוחת ניתוב לפי מה שהקיש המשתמש

    2
    0 הצבעות
    2 פוסטים
    31 צפיות
    א
    @BEN-ZION יש מודול שיכול לבצע את הפעולה הזו. כניסה לפי מפתח. אתה מגדיר את המפתח ואז לאן יעביר כל מפתח. כך שלכל שלוחה אתה מגדיר מפתח שונה ופי ההקשה יעבור המאזין לשלוחה. דוג': מפתח 1 דהיינו כשהמאזין יקיש 1, יעביר לשלוחה 1
  • 0 הצבעות
    6 פוסטים
    88 צפיות
    י
    אני בסוף הגדרתי כך type=record hard_link=yes copy_record_link=/01,/04 וזה עבד לי ב"ה... תודה רבה... השורה שניה נצרכת בשביל שהקובץ עצמו יוכפל...
  • -1 הצבעות
    6 פוסטים
    100 צפיות
    7
    @יעקב-יצחק כבר יש כאלהכל תחנות הדרייבריםלמה יש לך צורך באובר דווקא?
  • לייק / דסלייק - ושכלולים נוספים!! 👍🎀🏅✨

    44
    19 הצבעות
    44 פוסטים
    862 צפיות
    ח
    נראה שיש כאן ביקוש עצום ומפתיע. אולי יואילו ימות לעשות את זה לטובת הציבור, אולי יואילו כל אלו שרואים עצמם נשכרים מפיתוח זה שיגשו במייל לימות?
  • ביטול שמיעת השלוחה אליה הקובץ הועתק

    1
    2 הצבעות
    1 פוסטים
    31 צפיות
    אין תגובות
  • מודל פרסומות

    20
    2 הצבעות
    20 פוסטים
    325 צפיות
    א
    לא יודע מה כל הדיון, לא מחייבים אך אחד לשמוע. ובכלל נראה לי שהמבשר בכלל לא יודע מה זה ימות המשיח הוא מתכוון לקול כשר... אבל באמת, צריך אולי לשלוח מכתב תגובה שאם לפני שנה-תיים כשימות עידכנו שאם יבטלו דמי הקישוריות זה יהיה על חשבון הציבור ולא ראינו שום התייחסות מצד היומונים החרדים ולא זכור שהיה על זה איזה שאלה ששאלו את הגדולים האם לקדם את זה או להתנגד לזה וזה פשוט קודם ע"י הח"כים החרדים (שאני אישית תומך בהם כי ע"פ רוב הם עושים את דעת רבותיהם, אבל בענין הזה לא זכור לי משהו... או יותר נכון זכור לי ולא לכיוון הנכון...) והיום אנחנו אוכלים את זה... אז אולי כדאי לראיין את ח"כ ... בענין...
  • MCP Server לAPI של ימות המשיח

    3
    0 הצבעות
    3 פוסטים
    89 צפיות
    S
    נכון לדוגמה: https://github.com/harsha-iiiv/openapi-mcp-generator השאלה האם יש OpenAPI?
  • פורמט תאריך במודל הקשה

    1
    1 הצבעות
    1 פוסטים
    34 צפיות
    אין תגובות
  • פתרון למטרד הצנתוקים!

    24
    4 הצבעות
    24 פוסטים
    968 צפיות
    א
    @קו-הרהיטים דבר ראשון להתייעץ עם בית דין האם מותר. דבר שני שאין לי את הפרטים של מי ששלח צנתוקים אין לי שום מידע עליו כך שאני לא יכול לדעת למי לתבוע וכששואלים לימות המשיח במייל פרטים על בעל הקו הם לא עונים לא יודע למה?
  • במודל תור-השארת הנציג על הקו ומעבר לשלוחה אחרת

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

    5
    1 הצבעות
    5 פוסטים
    133 צפיות
    א
    @יעקב-יצחק סידרתי זאת!!! תודה על תגבותך!!!
  • נושא זה נמחק!

    1
    0 הצבעות
    1 פוסטים
    4 צפיות
    אין תגובות
  • כניסה PhonesName.ini

    3
    0 הצבעות
    3 פוסטים
    69 צפיות
    ק
    @קליטניק תמחק את הנושא!
  • 0 הצבעות
    3 פוסטים
    81 צפיות
    ז
    @אני-בעצמי-1 תפנה ללשונית "שאלות ועזרה הדדית" שם יהיו הרבה שישמחו לסייע לך. כאן הרוב לא רואים בכלל שכתבת, משום שזה מיועד לבקשות פיתוח הגדרות לימות המשיח.
  • הצעה לפיתוח: "צינתוק אינטראקטיבי" – מענה ישיר לשיחה נכנסת

    16
    9 הצבעות
    16 פוסטים
    279 צפיות
    מ
    @HMJE22 אני מבין את החשש שלך לגבי הגבלת ערוצים בצינתוקים, אבל הנקודה שלי היא אחרת: היום, כשיש הודעה דחופה ואלפי אנשים מקבלים צינתוק, נוצר עומס אדיר של שיחות נכנסות בבת אחת שמכביד על המערכת. הפיתוח שאני מציע מאפשר למערכת לווסת את העומס. במקום שכולם יתקשרו יחד, המערכת מחייגת אליהם בקצב שהיא יכולה להכיל, והם פשוט עונים ונכנסים לתוכן. לגבי הטיעון הכלכלי – הטכנולוגיה נועדה לשפר את חוויית המשתמש ולהפוך את הצינתוק לכלי עוצמתי ונגיש יותר. בסוף, המטרה היא להקל על המאזין (שלא צריך לחייג חזרה) ולשפר את אחוזי ההאזנה לתוכן. מסכים איתי ?