• דף הבית
    • אינדקס קישורים
    • פוסטים אחרונים
    • משתמשים
    • חיפוש בהגדרות המתקדמות
    • חיפוש גוגל בפורום
    • ניהול המערכת
    • ניהול המערכת - שרת private
    • הרשמה
    • התחברות
    1. דף הבית
    2. דוד_מלך_ישראל
    3. פוסטים
    ד מנותק
    • פרופיל
    • עוקב אחרי 0
    • עוקבים 11
    • נושאים 76
    • פוסטים 748
    • קבוצות 0

    פוסטים

    פוסטים אחרונים הגבוה ביותר שנוי במחלוקת
    • RE: עריכת קובץ שמע כמו במערכות אחרות

      @סוד-כמוב אני חושב לבנות פיתוח פרטי לזה, נראה.

      פורסם בבקשות לפיתוח
      ד
      דוד_מלך_ישראל
    • RE: בקרוב: מודול פרטי לשליחת פקסים מהמערכת

      @קו-הרהיטים כתב:

      @דוד_מלך_ישראל כדאי מאוד שזה יתמוך גם בקבצי הרישום במערכת כך שיהיה ניתן לשלוח קובץ רישום והוא ישלח לפקס כטבלה מסודרת זה נראה לי מאוד משמעותי למי שאין לו מחשב זמין והוא רוצה לקבל לידיו רשימות של שלוחת רישום וכדומה

      רעיון בהחלט, רק שיהיה צריך להמיר את קובץ ה YMGR לשליחה בפקס, אבל זה אפשרי, בנוסף, צריך לחשוב על דרך קלה לבחור את הקובץ המבוקש מתוך המערכת, כי להקליד את השם שלו יכול להיות מסובך למשתמשים.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: בקרוב: מודול פרטי לשליחת פקסים מהמערכת

      @343767535 כתב:

      @דוד_מלך_ישראל יש לך צפי מתי המודול יהיה מוכן?

      אני בדיוק מחפש עכשו משהו כזה די בדחיפות, השאלה אם כדאי לחכות

      המודול למערכת הטלפונית - בעז"ה בעוד כשבוע, לגבי המודול של השליחה האינטרנטית, התחלתי לבדוק את הענין, אבל זה ייקח יותר זמן.

      @הדיבל-המעופף כתב:

      @דוד_מלך_ישראל
      מה העלות לשליחה??????????????????????????

      לפי חבילה חודשית, X שליחות לחודש בתשלום חודשי קבוע, ככל שהחבילה גדולה יותר, העלות פר שליחה תהיה נמוכה יותר.

      @isi כתב:

      @דוד_מלך_ישראל זה יהיה תשלום באמצעות יחידות של ימות, או בתשלום נפרד אליך?

      חשבתי על מודול לפי יחידות, אבל זה מורכב, ראשית, כי א"א להעביר יחידה בודדת בין מערכות, ושנית, ובעיקר, כי אין לי הרבה שימוש ביחידות...

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: בקרוב: מודול פרטי לשליחת פקסים מהמערכת

      @isi @343767535 רעיון, אפשרי עקרונית אבל לא חשבתי על זה, אבדוק.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • בקרוב: מודול פרטי לשליחת פקסים מהמערכת

      שלום וברכה

      מכיון שימות המשיח הפסיקו את התמיכה במודול שליחת הפקסים (המודול עדיין קיים, אך במקרים רבים השליחה נכשלת, תלוי בחברות השונות, וימות כבר לא מספקים תמיכה למודול), ובעקבות כמה משתמשים ששמעתי מהם שהדבר נחוץ להם, אני מתכוון להשיק בעז"ה בקרוב מודול חדש לשליחת פקסים בפיתוח פרטי.

      המודול יעבוד באופן דומה למודול של ימות המשיח - העלאת קובץ PDF לשלוחה, והמתקשר מזמין אותו למספר הפקס.

      עלות השימוש במודול, בשונה מהמודול של ימות, תהיה לפי שליחות ולא לפי עמודים, כך שגם פקס בן מספר עמודים יחויב כיחידת שליחה אחת.

      אשמח לשמוע מהמשתמשים על דבר הצורך והשימוש, בפרט ממי שהתנסה במודול של ימות ומעונין להאיר ולהעיר.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: חדש! ניתוב שיחה ליעד מוגדר מראש במודול ניתוביה - ללא עלות יחידות!

      @יעקב-ברייער מבדיקה שלי מושמעות (לעיתים פרסומות במודול, גם בקו ללא פרסומות.

      פורסם בחדש במערכת
      ד
      דוד_מלך_ישראל
    • RE: לקראת תחילת חיוב היחידות: סריקת המערכת לאיתור מודולים עם שליחת אימייל

      הקובץ עודכן.

      כעת בכל שלוחה שמופיעה בתוצאות הסריקה ישנה אפשרות לערוך את הגדרות השלוחה ישירות מתוך הקובץ.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: לקראת תחילת חיוב היחידות: סריקת המערכת לאיתור מודולים עם שליחת אימייל

      @מנסה @לימוד-בתורת-מרן אני חושב שלא כדאי להוסיף כפתור שמוחק שרירותית את כל ההופעות של המייל, בעז"ה בהמשך היום אוסיף אפשרות לערוך את ההגדרות שלוחה מתוך הקובץ.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: לקראת תחילת חיוב היחידות: סריקת המערכת לאיתור מודולים עם שליחת אימייל

      @שיבקשו-שלשתם תלוי במודולים.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: לקראת תחילת חיוב היחידות: סריקת המערכת לאיתור מודולים עם שליחת אימייל

      או לפתוח פנקס רשימות, להדביק בו את כל התוכן הבא, ואז לשמור בכל שם שהוא בסיומת html:

      <!DOCTYPE html>
      <html lang="he" dir="rtl">
      <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>סורק מייל IVR</title>
      <style>
        @import url('https://fonts.googleapis.com/css2?family=Heebo:wght@300;400;500;700&display=swap');
      
        *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
      
        :root {
          --bg: #f7f5f0;
          --surface: #ffffff;
          --border: #e2ddd6;
          --border-strong: #c8c1b8;
          --text: #1a1714;
          --text-muted: #7a746d;
          --text-faint: #b0a89f;
          --purple: #534AB7;
          --purple-light: #EEEDFE;
          --purple-border: #AFA9EC;
          --amber: #854F0B;
          --amber-light: #FAEEDA;
          --amber-border: #FAC775;
          --red: #A32D2D;
          --red-light: #FCEBEB;
          --red-border: #F7C1C1;
          --green: #3B6D11;
          --green-light: #EAF3DE;
          --green-border: #C0DD97;
          --radius: 10px;
          --radius-sm: 6px;
        }
      
        html { font-size: 16px; }
      
        body {
          font-family: 'Heebo', sans-serif;
          background: var(--bg);
          color: var(--text);
          min-height: 100vh;
          padding: 2rem 1rem;
          line-height: 1.6;
        }
      
        .container {
          max-width: 720px;
          margin: 0 auto;
        }
      
        header {
          margin-bottom: 2rem;
          padding-bottom: 1.5rem;
          border-bottom: 1px solid var(--border);
        }
      
        header h1 {
          font-size: 22px;
          font-weight: 700;
          color: var(--text);
          margin-bottom: 4px;
        }
      
        header p {
          font-size: 14px;
          color: var(--text-muted);
        }
      
        .card {
          background: var(--surface);
          border: 1px solid var(--border);
          border-radius: var(--radius);
          padding: 1.5rem;
          margin-bottom: 1.25rem;
        }
      
        .card-title {
          font-size: 14px;
          font-weight: 500;
          color: var(--text-muted);
          margin-bottom: 1rem;
          text-transform: uppercase;
          letter-spacing: 0.05em;
          font-size: 12px;
        }
      
        .fields {
          display: grid;
          grid-template-columns: 1fr 1fr;
          gap: 12px;
          margin-bottom: 1rem;
        }
      
        .field label {
          display: block;
          font-size: 13px;
          color: var(--text-muted);
          margin-bottom: 5px;
        }
      
        .field input {
          width: 100%;
          padding: 9px 12px;
          border: 1px solid var(--border-strong);
          border-radius: var(--radius-sm);
          font-family: 'Heebo', sans-serif;
          font-size: 14px;
          color: var(--text);
          background: var(--bg);
          outline: none;
          transition: border-color 0.15s;
          direction: ltr;
          text-align: left;
        }
      
        .field input:focus {
          border-color: var(--purple);
          background: #fff;
        }
      
        .btn {
          width: 100%;
          padding: 11px 20px;
          border: none;
          border-radius: var(--radius-sm);
          background: var(--purple);
          color: #fff;
          font-family: 'Heebo', sans-serif;
          font-size: 15px;
          font-weight: 500;
          cursor: pointer;
          transition: opacity 0.15s, transform 0.1s;
          display: flex;
          align-items: center;
          justify-content: center;
          gap: 8px;
        }
      
        .btn:hover { opacity: 0.88; }
        .btn:active { transform: scale(0.99); }
        .btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; }
      
        .progress-wrap { margin-top: 1rem; display: none; }
      
        .progress-bar-bg {
          background: var(--bg);
          border-radius: 999px;
          height: 5px;
          overflow: hidden;
          border: 1px solid var(--border);
        }
      
        .progress-bar {
          height: 100%;
          background: var(--purple);
          border-radius: 999px;
          width: 0;
          transition: width 0.4s ease;
        }
      
        .progress-label {
          font-size: 13px;
          color: var(--text-muted);
          margin-top: 7px;
        }
      
        .stats {
          display: grid;
          grid-template-columns: repeat(3, 1fr);
          gap: 10px;
          margin-bottom: 1.25rem;
          display: none;
        }
      
        .stat {
          background: var(--surface);
          border: 1px solid var(--border);
          border-radius: var(--radius-sm);
          padding: 1rem;
          text-align: center;
        }
      
        .stat-num {
          font-size: 28px;
          font-weight: 700;
          color: var(--text);
          line-height: 1;
        }
      
        .stat-lbl {
          font-size: 12px;
          color: var(--text-muted);
          margin-top: 5px;
          line-height: 1.4;
        }
      
        .section {
          border-radius: var(--radius);
          padding: 1.25rem;
          margin-bottom: 1rem;
          border: 1px solid;
          display: none;
        }
      
        .sec-danger { background: var(--red-light); border-color: var(--red-border); }
        .sec-warn   { background: var(--amber-light); border-color: var(--amber-border); }
        .sec-ok     { background: var(--green-light); border-color: var(--green-border); }
      
        .sec-header {
          display: flex;
          align-items: center;
          gap: 8px;
          margin-bottom: 8px;
        }
      
        .sec-danger .sec-header { color: var(--red); }
        .sec-warn   .sec-header { color: var(--amber); }
        .sec-ok     .sec-header { color: var(--green); }
      
        .sec-title {
          font-size: 14px;
          font-weight: 700;
        }
      
        .sec-desc {
          font-size: 13px;
          margin-bottom: 10px;
          line-height: 1.5;
        }
      
        .sec-danger .sec-desc { color: #792020; }
        .sec-warn   .sec-desc { color: #6b3e08; }
        .sec-ok     .sec-desc { color: var(--green); }
      
        .path-list { list-style: none; }
      
        .path-list li {
          padding: 6px 0;
          border-bottom: 1px solid rgba(0,0,0,0.07);
          font-size: 13px;
        }
      
        .path-list li:last-child { border-bottom: none; }
      
        .path-code {
          font-family: 'Courier New', monospace;
          font-size: 13px;
          color: var(--text);
          direction: ltr;
          display: inline-block;
        }
      
        .match-tags {
          margin-top: 3px;
          display: flex;
          flex-wrap: wrap;
          gap: 5px;
        }
      
        .tag {
          display: inline-block;
          font-family: 'Courier New', monospace;
          font-size: 11px;
          padding: 2px 7px;
          border-radius: 4px;
          background: rgba(163,45,45,0.12);
          color: var(--red);
          direction: ltr;
        }
      
        .sec-warn .tag {
          background: rgba(133,79,11,0.12);
          color: var(--amber);
        }
      
        .ico {
          width: 18px;
          height: 18px;
          flex-shrink: 0;
        }
      
        footer {
          margin-top: 2.5rem;
          padding-top: 1rem;
          border-top: 1px solid var(--border);
          font-size: 12px;
          color: var(--text-faint);
          text-align: center;
        }
      
        footer a { color: var(--text-muted); }
      
        .error-msg {
          background: var(--red-light);
          border: 1px solid var(--red-border);
          color: var(--red);
          border-radius: var(--radius-sm);
          padding: 10px 14px;
          font-size: 14px;
          margin-top: 10px;
          display: none;
        }
      
        @media (max-width: 520px) {
          .fields { grid-template-columns: 1fr; }
          .stats { grid-template-columns: 1fr 1fr; }
        }
      
        /* editor inline */
        .ext-editor {
          display: none;
          margin-top: 10px;
          border: 1px solid var(--border-strong);
          border-radius: var(--radius-sm);
          overflow: hidden;
        }
        .ext-editor textarea {
          width: 100%;
          min-height: 160px;
          padding: 10px 12px;
          font-family: 'Courier New', monospace;
          font-size: 12px;
          line-height: 1.6;
          color: var(--text);
          background: var(--bg);
          border: none;
          outline: none;
          resize: vertical;
          direction: ltr;
          text-align: left;
        }
        .ext-editor-footer {
          display: flex;
          align-items: center;
          gap: 8px;
          padding: 8px 10px;
          background: var(--surface);
          border-top: 1px solid var(--border);
        }
        .btn-sm {
          padding: 6px 14px;
          border: none;
          border-radius: var(--radius-sm);
          font-family: 'Heebo', sans-serif;
          font-size: 13px;
          font-weight: 500;
          cursor: pointer;
          transition: opacity 0.15s;
        }
        .btn-sm:hover { opacity: 0.85; }
        .btn-sm:disabled { opacity: 0.45; cursor: not-allowed; }
        .btn-save { background: var(--purple); color: #fff; }
        .btn-cancel { background: var(--bg); color: var(--text-muted); border: 1px solid var(--border-strong); }
        .editor-status {
          font-size: 12px;
          margin-right: auto;
        }
        .editor-status.ok  { color: var(--green); }
        .editor-status.err { color: var(--red); }
        .btn-edit {
          margin-top: 5px;
          padding: 3px 10px;
          border: 1px solid var(--border-strong);
          border-radius: var(--radius-sm);
          background: var(--surface);
          font-family: 'Heebo', sans-serif;
          font-size: 12px;
          color: var(--text-muted);
          cursor: pointer;
          transition: border-color 0.15s, color 0.15s;
          display: block;
        }
        .btn-edit:hover { border-color: var(--purple); color: var(--purple); }
      </style>
      </head>
      <body>
      <div class="container">
      
        <header>
          <h1>🔍 סורק הגדרות מייל ב-IVR</h1>
          <p>סריקה רקורסיבית של כל שלוחות המערכת לאיתור שליחת אימייל מוגדרת</p>
        </header>
      
        <div class="card">
          <div class="card-title">פרטי התחברות</div>
          <div class="fields">
            <div class="field">
              <label>מספר מערכת</label>
              <input type="text" id="sys-num" placeholder="077777" />
            </div>
            <div class="field">
              <label>סיסמה</label>
              <input type="password" id="sys-pass" placeholder="סיסמה" />
            </div>
          </div>
          <button class="btn" id="scan-btn" onclick="startScan()">
            <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
            התחל סריקה
          </button>
          <div class="error-msg" id="error-msg"></div>
          <div class="progress-wrap" id="progress-wrap">
            <div class="progress-bar-bg"><div class="progress-bar" id="progress-bar"></div></div>
            <div class="progress-label" id="progress-label">מאתחל...</div>
          </div>
        </div>
      
        <div class="stats" id="stats">
          <div class="stat"><div class="stat-num" id="stat-total">0</div><div class="stat-lbl">שלוחות נסרקו</div></div>
          <div class="stat"><div class="stat-num" id="stat-mail">0</div><div class="stat-lbl">נמצאה מילת mail</div></div>
          <div class="stat"><div class="stat-num" id="stat-default">0</div><div class="stat-lbl">מייל ברירת מחדל</div></div>
        </div>
      
        <div class="section sec-danger" id="danger-section">
          <div class="sec-header">
            <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
            <span class="sec-title">שלוחות עם הגדרות מייל כברירת מחדל</span>
          </div>
          <p class="sec-desc">בשלוחות הבאות מצאנו הגדרות אשר כברירת מחדל יש בהן שליחת אימייל, מומלץ לוודא האם בוטלה בהן שליחת המייל</p>
          <ul class="path-list" id="danger-list"></ul>
        </div>
      
        <div class="section sec-warn" id="warn-section">
          <div class="sec-header">
            <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
            <span class="sec-title">שלוחות עם מילת mail בהגדרות</span>
          </div>
          <p class="sec-desc">בשלוחות הבאות מצאנו את המילה mail בהגדרות השלוחה, מומלץ לבדוק האם מתבצעת שליחת מייל משלוחה זו</p>
          <ul class="path-list" id="warn-list"></ul>
        </div>
      
        <div class="section sec-ok" id="ok-section">
          <div class="sec-header">
            <svg class="ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
            <span class="sec-title">לא נמצאו שלוחות עם הגדרות מייל</span>
          </div>
          <p class="sec-desc">הסריקה הושלמה ולא נמצאו שלוחות עם הגדרות שליחת מייל.</p>
        </div>
      
        <footer>
          פותח ע"י דוד מלך ישראל &bull; <a href="mailto:cs@shemanet.com">cs@shemanet.com</a>
        </footer>
      
      </div>
      <script>
      const BASE = 'https://www.call2all.co.il/ym/api/';
      const DEFAULT_TRIGGERS = [
        { label: 'after_play=tfr_message', test: c => c.includes('after_play=tfr_message') },
        { label: 'key_NNN_record=yes',     test: c => /key_.+_record=yes/.test(c) },
        { label: 'type=sale_seats',        test: c => c.includes('type=sale_seats') },
        { label: 'emeil_send=yes',         test: c => c.includes('emeil_send=yes') },
        { label: 'checking_units=yes',     test: c => c.includes('checking_units=yes') },
        { label: 'type=missed_calls',      test: c => c.includes('type=missed_calls') },
      ];
      
      let token = '';
      
      function setProgress(pct, label) {
        document.getElementById('progress-bar').style.width = pct + '%';
        document.getElementById('progress-label').textContent = label;
      }
      
      function showError(msg) {
        const el = document.getElementById('error-msg');
        el.textContent = msg;
        el.style.display = 'block';
      }
      
      function hideError() {
        document.getElementById('error-msg').style.display = 'none';
      }
      
      async function apiGet(cmd, params) {
        const qs = Object.entries({ token, ...params })
          .map(([k, v]) => k + '=' + encodeURIComponent(v)).join('&');
        const r = await fetch(BASE + cmd + '?' + qs);
        if (!r.ok) throw new Error('HTTP ' + r.status);
        return r.json();
      }
      
      async function apiPost(cmd, params) {
        const formData = new URLSearchParams({ token, ...params });
        const r = await fetch(BASE + cmd, { method: 'POST', body: formData });
        if (!r.ok) throw new Error('HTTP ' + r.status);
        return r.json();
      }
      
      async function openEditor(path, li) {
        const btn = li.querySelector('.btn-edit');
        let editor = li.querySelector('.ext-editor');
      
        // אם כבר פתוח — סגור
        if (editor && editor.style.display === 'block') {
          editor.style.display = 'none';
          btn.textContent = 'עריכה';
          return;
        }
      
        // סגירת editor פתוח אחר
        document.querySelectorAll('.ext-editor').forEach(el => {
          if (el.style.display === 'block') {
            el.style.display = 'none';
            const prevBtn = el.parentElement && el.parentElement.querySelector('.btn-edit');
            if (prevBtn) prevBtn.textContent = 'עריכה';
          }
        });
      
        const filePath = 'ivr2:' + path + '/ext.ini';
        btn.textContent = 'טוען...';
        btn.disabled = true;
      
        let content = '';
        try {
          const f = await apiGet('GetTextFile', { what: filePath });
          content = (f && f.contents) ? f.contents : '';
        } catch (e) {
          btn.textContent = 'שגיאה';
          btn.disabled = false;
          return;
        }
      
        if (!editor) {
          editor = document.createElement('div');
          editor.className = 'ext-editor';
          editor.innerHTML = `
            <textarea></textarea>
            <div class="ext-editor-footer">
              <button class="btn-sm btn-save">שמור</button>
              <button class="btn-sm btn-cancel">ביטול</button>
              <span class="editor-status"></span>
            </div>`;
          li.appendChild(editor);
      
          editor.querySelector('.btn-cancel').onclick = () => {
            editor.style.display = 'none';
            li.querySelector('.btn-edit').textContent = 'עריכה';
          };
          editor.querySelector('.btn-save').onclick = async () => {
            const saveBtn = editor.querySelector('.btn-save');
            const status = editor.querySelector('.editor-status');
            const newContent = editor.querySelector('textarea').value;
            saveBtn.disabled = true;
            status.textContent = 'שומר...';
            status.className = 'editor-status';
            try {
              const res = await apiPost('UploadTextFile', { what: filePath, contents: newContent });
              if (res && res.responseStatus === 'OK') {
                status.textContent = '✓ נשמר בהצלחה';
                status.className = 'editor-status ok';
                setTimeout(() => {
                  editor.style.display = 'none';
                  li.querySelector('.btn-edit').textContent = 'עריכה';
                }, 800);
              } else {
                status.textContent = 'שגיאה: ' + (res && res.message ? res.message : 'לא ידוע');
                status.className = 'editor-status err';
              }
            } catch (e) {
              status.textContent = 'שגיאת רשת: ' + e.message;
              status.className = 'editor-status err';
            }
            saveBtn.disabled = false;
          };
        }
      
        editor.querySelector('textarea').value = content;
        editor.style.display = 'block';
        btn.textContent = 'סגור';
        btn.disabled = false;
      }
      
      async function scanAll(rootDirs, results) {
        // BFS queue — עיבוד סדרתי, שלוחה אחת בכל פעם
        const queue = [...rootDirs.map(d => d.path)];
        let scanned = 0;
      
        while (queue.length > 0) {
          const path = queue.shift();
      
          // 1. קריאת תיקייה
          let data;
          try { data = await apiGet('GetIVR2Dir', { path }); } catch (e) { continue; }
          if (!data || data.responseStatus === 'ERROR' || data.responseStatus === 'EXCEPTION') continue;
      
          // 2. קריאת ext.ini של השלוחה הזו
          const filePath = 'ivr2:' + (path === '/' ? '' : path + '/') + 'ext.ini';
          let content = '';
          try {
            const f = await apiGet('GetTextFile', { what: filePath });
            content = (f && f.contents) ? f.contents : '';
          } catch (e) {}
      
          if (content) {
            const mailHit = /mail/i.test(content);
            const defaultHits = DEFAULT_TRIGGERS.filter(t => t.test(content)).map(t => t.label);
            if (mailHit || defaultHits.length > 0) {
              results.push({ path, mailHit, defaultHits });
            }
          }
      
          scanned++;
          const inQueue = queue.length;
          setProgress(
            Math.min(95, Math.round(scanned / (scanned + inQueue + 1) * 90 + 5)),
            'סורק: ' + path + '  (' + scanned + ' נסרקו, ' + inQueue + ' בתור)'
          );
      
          // 3. הוספת בנות לתור — לא רקורסיה, לא parallel
          const dirs = Array.isArray(data.dirs) ? data.dirs : [];
          dirs.forEach(d => queue.push(d.path));
        }
      
        return scanned;
      }
      
      function buildList(listEl, items, isDefault) {
        listEl.innerHTML = '';
        items.forEach(r => {
          const li = document.createElement('li');
      
          const code = document.createElement('span');
          code.className = 'path-code';
          code.textContent = r.path + '/ext.ini';
          li.appendChild(code);
      
          if (isDefault && r.defaultHits.length > 0) {
            const tags = document.createElement('div');
            tags.className = 'match-tags';
            r.defaultHits.forEach(h => {
              const t = document.createElement('span');
              t.className = 'tag';
              t.textContent = h;
              tags.appendChild(t);
            });
            li.appendChild(tags);
          }
      
          const editBtn = document.createElement('button');
          editBtn.className = 'btn-edit';
          editBtn.textContent = 'עריכה';
          editBtn.onclick = () => openEditor(r.path, li);
          li.appendChild(editBtn);
      
          listEl.appendChild(li);
        });
      }
      
      async function startScan() {
        const num = document.getElementById('sys-num').value.trim();
        const pass = document.getElementById('sys-pass').value.trim();
        if (!num || !pass) { showError('נא להזין מספר מערכת וסיסמה'); return; }
        hideError();
        token = num + ':' + pass;
      
        document.getElementById('scan-btn').disabled = true;
        document.getElementById('progress-wrap').style.display = 'block';
        document.getElementById('stats').style.display = 'none';
        ['danger-section', 'warn-section', 'ok-section'].forEach(id => {
          document.getElementById(id).style.display = 'none';
        });
      
        setProgress(5, 'מתחבר למערכת...');
      
        let rootData;
        try {
          rootData = await apiGet('GetIVR2Dir', { path: '/' });
        } catch (e) {
          showError('שגיאת רשת: ' + e.message);
          document.getElementById('scan-btn').disabled = false;
          return;
        }
      
        if (!rootData || rootData.responseStatus === 'ERROR' || rootData.responseStatus === 'EXCEPTION') {
          showError('שגיאת אימות: ' + (rootData && rootData.message ? rootData.message : 'בדוק פרטי התחברות'));
          document.getElementById('scan-btn').disabled = false;
          return;
        }
      
        setProgress(10, 'מתחיל סריקה...');
        const results = [];
        const rootDirs = Array.isArray(rootData.dirs) ? rootData.dirs : [];
        const totalScanned = await scanAll(rootDirs, results);
      
        setProgress(100, 'הסריקה הושלמה!');
      
        const withDefaults = results.filter(r => r.defaultHits.length > 0);
        const mailOnly = results.filter(r => r.mailHit && r.defaultHits.length === 0);
      
        document.getElementById('stat-total').textContent = totalScanned;
        document.getElementById('stat-mail').textContent = results.filter(r => r.mailHit).length;
        document.getElementById('stat-default').textContent = withDefaults.length;
        document.getElementById('stats').style.display = 'grid';
      
        if (withDefaults.length > 0) {
          buildList(document.getElementById('danger-list'), withDefaults, true);
          document.getElementById('danger-section').style.display = 'block';
        }
        if (mailOnly.length > 0) {
          buildList(document.getElementById('warn-list'), mailOnly, false);
          document.getElementById('warn-section').style.display = 'block';
        }
        if (withDefaults.length === 0 && mailOnly.length === 0) {
          document.getElementById('ok-section').style.display = 'block';
        }
      
        document.getElementById('scan-btn').disabled = false;
      }
      </script>
      </body>
      </html>
      
      
      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: לקראת תחילת חיוב היחידות: סריקת המערכת לאיתור מודולים עם שליחת אימייל

      @שואל-שאלה
      מסתבר שא"א להעלות לפורום קבצי html ישירות, קישור להורדה:
      https://shemanet.com/ivr_email_scanner.html

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • לקראת תחילת חיוב היחידות: סריקת המערכת לאיתור מודולים עם שליחת אימייל

      שלום וברכה

      בעקבות תחילת עלות היחידות בכל שליחת אימייל מהמערכת, והצורך לבדוק האם יש שלוחות או מודולים במערכת השולחים מיילים, בניתי קובץ קטן הסורק את כל קבצי ההגדרות בכל שלוחות המערכת, מחזיר את רשימת השלוחות בהם ישנה הגדרת שליחת אימייל, ומאפשר לערוך את הגדרות השלוחה ישירות מתוך הקובץ.

      הקובץ רץ על הדפדפן שלכם בלבד והנתונים לא נשלחים לשום מקום.

      אופן פעולת הקובץ:

      הקובץ מחפש את כל השלוחות שבהגדרות השלוחה מופיעה המילה mail, אשר על פי בדיקה שלי מופיעה בכל מודול השולח מיילים.
      בנוסף, מכיון שיש מספר (קטן) של מודולים השולחים מייל כברירת מחדל, הקובץ מחפש האם אחד מהמודולים האלו קיים במערכת.

      הערה חשובה:

      כאמור, בדקתי את כל המודולים מאינדקס הקישורים שהופיעה בהם אפשרות שליחת מיילים, ובכולם הופיעה המילה mail, ועל סמך זה השתמשתי בזה בחיפוש, אך כמובן שאין לי אחריות על הענין, ובאופן כללי על פעולת הקובץ.

      להורדת הקובץ:
      https://shemanet.com/ivr_email_scanner.html

      או ע"י העתקת תוכן הקובץ, ראה בפוסטים הבאים.

      פורסם בטיפים עצות והדגמות מהמשתמשים
      ד
      דוד_מלך_ישראל
    • RE: תגובה למודול העתקת מערכת של דוד מלך ישראל

      @אA לא חושב שיש היום שרת חינמי שעובד עם ימות, להוסטינגר היה אבל זה הסתיים.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ד
      דוד_מלך_ישראל
    • RE: תגובה למודול העתקת מערכת של דוד מלך ישראל

      @אA נכון, בעז"ה בגרסה הבאה זה יפתח כתוכנה.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ד
      דוד_מלך_ישראל
    • RE: תגובה למודול העתקת מערכת של דוד מלך ישראל

      @אA תלוי כנראה הגדרות הסינון (אני בנטפרי ופתוח לי).
      עכ"פ הוספתי אפשרות להוריד את התוכנה גם מדרייב, עיין בפוסט המקורי

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ד
      דוד_מלך_ישראל
    • RE: תגובה למודול העתקת מערכת של דוד מלך ישראל

      @אA תודה!
      וכל הכבוד על הפיתוחים שלך...
      מה אתה מתכוון בקובץ להורדה, להעלות את הקובץ לפורום? ניסיתי, הוא חורג מהגודל האפשרי, אבל הקישור שהבאתי מוריד ישירות.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ד
      דוד_מלך_ישראל
    • RE: תגובה למודול העתקת מערכת של דוד מלך ישראל

      @R.E.T-מערכות מוזר... (ופליז, תבטל את הטרנסלייט, אני לא יכול לראות את השגיאות כתיב שהוא עושה לי, מה זה "כנישה למערכת"? 😉).

      מה שרואים כאן שהבקשה נשלחת (ולכן המשתמש שיצרת מופיע למעשה ברשימת שמות המשתמשים) אבל התגובה שמתקבלת לא תקינה, מה שאופייני באמת למקרה של חסימה על האינטרנט, (כשניסיתי להריץ את זה על מחשב עם מייל בלבד זו באמת היתה התגובה), אבל במסלול שכולל אתרים עבד לי תקין, אולי בכ"ז זה תלוי בתגיות מסוימות.
      נסה להכנס לקישור הזה ותדביק כאן את התגובה, זה ייתן לנו אינדיקציה אם זה קשור לסינון.

      פורסם בעזרה הדדית למשתמשים מתקדמים
      ד
      דוד_מלך_ישראל