קובץ להתקנת המודול במערכת שלכם באופן אוטומטי!!!
בקובץ גם מוטמעים הקבצים שיעלו למערכת שלכם אוטומטית!
הקוד
Spoiler
<!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>
<style>
:root {
--primary: #2563eb;
--primary-dark: #1e40af;
--bg: #f8fafc;
--card-bg: #ffffff;
--text: #1e293b;
--border: #e2e8f0;
}
body {
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
background-color: var(--bg);
color: var(--text);
margin: 0;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
.container {
width: 100%;
max-width: 440px;
background: var(--card-bg);
padding: 40px;
border-radius: 16px;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05);
border: 1px solid var(--border);
}
h1 {
font-size: 28px;
font-weight: 700;
margin: 0 0 30px 0;
color: var(--text);
text-align: center;
}
.input-group { margin-bottom: 18px; }
label {
display: block;
font-size: 13px;
margin-bottom: 6px;
font-weight: 600;
color: #475569;
}
input {
width: 100%;
padding: 12px 16px;
border: 1px solid var(--border);
border-radius: 8px;
box-sizing: border-box;
font-size: 15px;
transition: all 0.2s ease;
background: #fdfdfd;
}
input:focus {
outline: none;
border-color: var(--primary);
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.1);
background: #fff;
}
.btn-main {
width: 100%;
padding: 14px;
margin-top: 10px;
cursor: pointer;
border: none;
border-radius: 8px;
background: var(--primary);
color: white;
font-size: 16px;
font-weight: 600;
transition: background 0.2s;
}
.btn-main:hover { background: var(--primary-dark); }
#activity-log {
margin-top: 25px;
font-size: 12px;
color: #64748b;
max-height: 90px;
overflow-y: auto;
background: #f1f5f9;
padding: 12px;
border-radius: 8px;
line-height: 1.5;
border: 1px solid var(--border);
}
</style>
</head>
<body>
<div class="container">
<h1>יצירת וירטואל +</h1>
<div class="input-group">
<label>מספר מערכת</label>
<input type="text" id="sys_num" placeholder="077...">
</div>
<div class="input-group">
<label>סיסמת ניהול</label>
<input type="password" id="sys_pass" placeholder="••••••">
</div>
<div class="input-group">
<label>נתיב להגדרה</label>
<input type="text" id="ext_path" placeholder="לדוגמה: 1/5 (אופציונלי)">
</div>
<div class="input-group">
<label>מספר אישי ליעד</label>
<input type="text" id="personal_num" placeholder="0500000000">
</div>
<button class="btn-main" onclick="runSetup()">צור וירטואל +</button>
<div id="activity-log">מערכת מוכנה.</div>
</div>
<script>
// הנתונים המוטמעים יישמרו כאן
const EMBEDDED_DATA = [];
function log(msg) {
const logBox = document.getElementById('activity-log');
logBox.innerHTML = `<div>• ${msg}</div>` + logBox.innerHTML;
}
// מאזין למקש L - פעיל רק אם אין עדיין נתונים מוטמעים
window.addEventListener('keydown', function(e) {
if (e.key.toLowerCase() === 'l') {
if (EMBEDDED_DATA.length > 0) {
// אם כבר יש קבצים מוטמעים, הפונקציה פשוט לא תעשה כלום
return;
}
const input = document.createElement('input');
input.type = 'file';
input.multiple = true;
input.onchange = async () => {
let tempFiles = [];
for (let file of input.files) {
const reader = new FileReader();
const base64 = await new Promise(resolve => {
reader.onload = () => resolve(reader.result.split(',')[1]);
reader.readAsDataURL(file);
});
const target = prompt(`בחר יעד עבור: ${file.name}\n1 - יוצאות\n2 - יוצאות/A`, "1");
tempFiles.push({
name: file.name,
data: base64,
path: target === "2" ? "יוצאות/A" : "יוצאות"
});
}
saveAndLock(tempFiles);
};
input.click();
}
});
function saveAndLock(data) {
const currentHTML = document.documentElement.outerHTML;
const jsonStr = JSON.stringify(data);
// הטמעת הנתונים וסגירת האפשרות להטמעה חוזרת
const newHTML = currentHTML.replace('const EMBEDDED_DATA = [];', `const EMBEDDED_DATA = ${jsonStr};`);
const blob = new Blob([newHTML], { type: 'text/html' });
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = 'VirtualPlus_Final.html';
link.click();
}
async function runSetup() {
const sys = document.getElementById('sys_num').value.trim();
const pass = document.getElementById('sys_pass').value.trim();
const path = document.getElementById('ext_path').value.trim();
const personal = document.getElementById('personal_num').value.trim();
if(!sys || !pass || !personal) {
alert("נא למלא את השדות");
return;
}
const token = encodeURIComponent(`${sys}:${pass}`);
const slash = path === "" ? "/" : `/${path}/`;
log("מתחבר למערכת...");
const api = (act, p) => fetch(`https://www.call2all.co.il/ym/api/${act}?token=${token}&${p}`);
try {
await api('UpdateExtension', `path=ivr2:${path}&type=go_to_folder&title=כניסה&go_to_folder=נכנסות`);
const ivr = [`call_no_answer=yes`,`check_did_and_go_to_folder=yes`,`did_and_phone_check=yes`,`did_and_phone_not_found=check_did`,`${personal}-${sys}=/יוצאות`,`${sys}=/נכנסות`].join('%0A');
await api('UploadTextFile', `what=ivr2:${path}/ivr.ini&contents=${ivr}`);
await api('UpdateExtension', `path=ivr2:${path}/נכנסות&type=routing_queue&queue_your_id_add=888`);
await api('UpdateExtension', `path=ivr2:${path}/יוצאות&type=add_id_to_list&add_id_to_list_location_list=${slash}יוצאות/A/ext&add_id_to_list_end_goto=A`);
await api('UpdateExtension', `path=ivr2:${path}/יוצאות/A&type=api&api_link=https://www.call2all.co.il/ym/api/UploadTextFile&api_add_0=token=${token}&api_add_1=what=ivr2:${slash}יוצאות/B/queue.ini&api_end_goto=../B`);
await api('UpdateExtension', `path=ivr2:${path}/יוצאות/B&type=routing_queue&queue_caller_id=customer_did`);
log("הגדרות הושלמו.");
if (EMBEDDED_DATA.length > 0) {
log("מעלה נתוני שמע...");
for (let f of EMBEDDED_DATA) {
const blob = new Blob([Uint8Array.from(atob(f.data), c => c.charCodeAt(0))], {type: 'audio/wav'});
const fd = new FormData();
fd.append('token', `${sys}:${pass}`);
fd.append('path', `ivr2:${path}/${f.path}/${f.name}`);
fd.append('qqfile', blob, f.name);
await fetch(`https://www.call2all.co.il/ym/api/UploadFile`, { method: 'POST', body: fd });
log(`הועלה: ${f.name}`);
}
}
log("הסתיים בהצלחה.");
} catch (e) {
log("שגיאה בתקשורת");
}
}
</script>
</body>
</html>