דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • ברירת מחדל (ללא עיצוב (ברירת מחדל))
  • ללא עיצוב (ברירת מחדל)
כיווץ
מתמחים טופ
מ

מוגן

@מוגן
אודות
פוסטים
1.1k
נושאים
105
שיתופים
0
קבוצות
0
עוקבים
2
עוקב אחרי
0

פוסטים

פוסטים אחרונים הגבוה ביותר שנוי במחלוקת

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

    @למה-באתי כאן כרגע האתר בתחזוקה תנסה יותר מאוחר

    כללי - עזרה הדדית

  • שאלה | פיתוח חדש לחיסכון בחשמל ובכסף וניהול מים חמים - אשמח לדעתכם כבעלי משפחות
    מ מוגן

    יש היום אפשרות מעשית לשלוט עם הטלפון הכשר בשיחה טלפונית על מוצר חשמלי כל שהוא כמו מזגן או מוצר אחר?

    חשמל ביתי

  • שיתוף | 'פלאפון מייל' - כולל קבלת ושליחת מיילים דרך הפלאפון, קריינות מקצועית, ועוד...
    מ מוגן

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

    רשתות

  • שיתוף | 'פלאפון מייל' - כולל קבלת ושליחת מיילים דרך הפלאפון, קריינות מקצועית, ועוד...
    מ מוגן

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

    רשתות

  • שיתוף | 'פלאפון מייל' - כולל קבלת ושליחת מיילים דרך הפלאפון, קריינות מקצועית, ועוד...
    מ מוגן

    @3157686 אתה יכול להכניס את הקוד הזה אך שים לב שיש בו כמה שינויים מהמקור.

    1. קובץ שמע מצורף שנשלח מושמע בקו לאחר השמעת ההודעה
    2. הקריינות היא רק של גוגל קלאוד בקול של אשה
      ועוד כמה שינויים שביצעתי בג'ימיני
      בהצלחה
    const sheet = SpreadsheetApp.getActive();
    const ss = SpreadsheetApp.getActiveSpreadsheet();
    const ScriptProperties = PropertiesService.getScriptProperties();
    const GOOGLE_TTS_VOICE = 'he-IL-Standard-A';
    const GOOGLE_TTS_LANG = 'he-IL';
    var SCRIPT_NAME = 'פלאפון-מייל';
    const MainSheet = sheet.getSheetByName(SCRIPT_NAME);
    const SettingsSheet = sheet.getSheetByName('הגדרות');
    const FilterSheet = sheet.getSheetByName('סינון');
    const IdSheetSentEvenDay = sheet.getSheetByName('כתובות id שנשלחו ביום זוגי');
    const IdSheetSentOddDay = sheet.getSheetByName('כתובות id שנשלחו ביום אי זוגי');
    const ReplacementPatterns = sheet.getSheetByName('החלפות').getRange('A2:B').getValues();
    const SettingsValues = SettingsSheet.getRange('B:B').getValues();
    const DeleteSheets = SettingsValues[1][0];
    const GOOGLE_API_KEY = SettingsValues[3][0];
    const GOOGLE_TTS_SPEED = SettingsValues[4][0] || '1.0';
    let username = SettingsValues[6][0];
    let password = SettingsValues[7][0];
    let token = SettingsValues[8][0];
    const ExtensionArchive = SettingsValues[10][0];
    const ExtensionSendMail = SettingsValues[11][0];
    const ExtensionTzintuk = SettingsValues[12][0];
    const TzintukimList = SettingsValues[13][0];
    const TzintukTimeOut = SettingsValues[14][0];
    const SearchWords = SettingsValues[16][0];
    const WordsExclude = SettingsValues[17][0];
    
    const TextSender = SettingsValues[19][0];
    const TextSubject = SettingsValues[20][0];
    const TextBody = SettingsValues[21][0];
    const TextEnd = SettingsValues[22][0];
    const TextDay = SettingsValues[23][0];
    const TextDate = SettingsValues[24][0];
    const TextHour = SettingsValues[25][0];
    const TextAnd = SettingsValues[26][0];
    const TextMinute = SettingsValues[27][0];
    const TextAttachments = SettingsValues[28][0];
    const TextNoAttachments = SettingsValues[29][0];
    
    const NoTzintuk = SettingsValues[31][0];
    
    const PathArchive = (`ivr2:${ExtensionArchive}/`);
    const PathTzintuk = (`ivr2:${ExtensionTzintuk}/`);
    const phones = (`tzl:${TzintukimList}`);
    
    const Url = 'https://www.call2all.co.il/ym/api/'
    
    const SearchByGmail = `${SearchWords} is:unread newer_than:1h  -{in:draft ${WordsExclude}}`
    const HourAgo = new Date(Date.now())
    
    const GEMINI_API_KEY = GOOGLE_API_KEY;
    var Sourcesheet = '1JTB8qWqubBkSvRgk5_DjlFhKqaSm0V4jwdS6gq6DxJY';
    
    function mailToPhone() {
      for (let attempts = 1; attempts <= 3; attempts++) {
        if (testToken()) {
          checkForGmails();
          processOutgoingMails();
          break;
        }
        token = getToken();
      }
    }
    
    function checkForGmails() {
      const EvenOrOdd = new Date().getDay() % 2;
      const SheetToday = EvenOrOdd === 1 ? IdSheetSentEvenDay : IdSheetSentOddDay;
      
      const LastRowEvenDay = IdSheetSentEvenDay.getLastRow();
      const LastRowOddDay = IdSheetSentOddDay.getLastRow();
      const SourceValuesEvenDay = LastRowEvenDay > 1 ? IdSheetSentEvenDay.getRange(`A2:A${LastRowEvenDay}`).getValues() : [];
      const SourceValuesOddDay = LastRowOddDay > 1 ? IdSheetSentOddDay.getRange(`A2:A${LastRowOddDay}`).getValues() : [];
      let didUpload = false;
      let newMailsCount = 0;
      let isVipBatch = false;
    
      const filters = getFilterLists();
      const blockList = filters.blockedEmails;
      const vipList = filters.vipEmails;
      const blockedSubjects = filters.blockedSubjects;
    
      const Threads = GmailApp.search(SearchByGmail);
      for (const thread of Threads) {
        const Messages = thread.getMessages();
        for (const message of Messages) {
          if (SourceValuesEvenDay.findIndex(e => e[0] === message.getId()) !== -1 || 
              SourceValuesOddDay.findIndex(e => e[0] === message.getId()) !== -1 || 
              message.getDate() < (HourAgo - 3600000)) {
            continue;
          }
          
          const senderFrom = message.getFrom();
          const senderEmail = (senderFrom.match(/<([^>]+)>/) || [null, senderFrom])[1].toLowerCase();
          const subject = message.getSubject().toLowerCase();
          if (blockList.some(blocked => senderEmail.includes(blocked))) {
            markAsHandled(SheetToday, message.getId());
            continue;
          }
    
          if (blockedSubjects.some(badWord => subject.includes(badWord))) {
            markAsHandled(SheetToday, message.getId());
            continue;
          }
    
          if (vipList.some(vip => senderEmail.includes(vip))) {
            isVipBatch = true;
          }
    
          const Result = sendToYemot(message);
          if (Result) {
            newMailsCount++;
            didUpload = true;
          }
          
          SheetToday.getRange(SheetToday.getLastRow() + 1, 1).setNumberFormat("@").setValue(message.getId());
          SpreadsheetApp.flush();
        }
      }
    
      if (didUpload) {
        const getMenuVoiceResponse = fetch('GetIVR2Dir', { token, path: "/" });
        let existingMenuText = getMenuVoiceResponse.extIni.menu_voice;
        let totalCount = newMailsCount;
    
        const regex = /(\d+) מיילים חדשים/;
        if (regex.test(existingMenuText)) {
          existingMenuText = existingMenuText.replace(regex, (match, oldCount) => {
            totalCount = parseInt(oldCount, 10) + newMailsCount;
            return `${totalCount} מיילים חדשים`;
          });
        } else if (existingMenuText) {
          existingMenuText = `יש, ${newMailsCount} מיילים חדשים. ${existingMenuText}`;
        } else {
          existingMenuText = `יש, ${newMailsCount} מיילים חדשים. לשמיעת המיילים הקישו ${ExtensionArchive}.
          לשליחת מייל הקישו ${ExtensionSendMail}. להגדרות הצינתוקים הקישו ${ExtensionTzintuk}.`;
        }
    
        fetch('UpdateExtension', { token, path: "/", menu_voice: existingMenuText });
        if (isVipBatch) {
          tzintuk();
        } else {
          if (!isNowSilenceTime(NoTzintuk)) {
            tzintuk();
          }
        }
      }
    }
    
    function sendToYemot(message) {
      const lMap = { 'א': 'אל"ף', 'ב': 'בי"ת', 'ג': 'גימ"ל', 'ד': 'דל"ת', 'ה': 'ה"א', 'ו': 'ו"ו', 'ז': 'זי"ן', 'ח': 'חי"ת', 'ט': 'טי"ת', 'י': 'יו"ד', 'כ': 'כ"ף', 'ל': 'למ"ד', 'מ': 'מ"ם', 'נ': 'נו"ן', 'ס': 'סמ"ך', 'ע': 'עי"ן', 'פ': 'פ"א', 'צ': 'צדי"ק', 'ק': 'קו"ף', 'ר': 'רי"ש', 'ש': 'שי"ן', 'ת': 'ת"ו' };
      const MessageDate = message.getDate();
      const FormattedHebrewDate = new Intl.DateTimeFormat('he-IL-u-ca-hebrew').format(MessageDate);
      const HebrewDay = ['ראשון', 'שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת'];
      const DateParts = FormattedHebrewDate.split(" ");
      const NumericDay = gimatria(DateParts[0]).split('').map(c => lMap[c] || c).join(' ');
      const MonthAndYear = DateParts.slice(1, -1).join(" ");
      const NumericYear = gimatria(DateParts[DateParts.length - 1].slice(-3)).split('').map(c => lMap[c] || c).join(' ');
      
      // --- חלק: ניקוי היסטוריית הודעות ---
      let cleanBody = message.getPlainBody();
      // הסרת שורות ציטוט (המתחילות ב->)
      cleanBody = cleanBody.replace(/^>.*$/gm, '');
      // רשימת תבניות המעידות על תחילת היסטוריה (אנגלית ועברית)
      const historySplitters = [
        /On[\s\S]*?wrote:/i,       // תבנית ג'ימייל אנגלית
        /בתאריך[\s\S]*?כתב:/,      // תבנית ג'ימייל עברית
        /_{10,}/,                  // קו מפריד תחתון ארוך
        /-{10,}/,                  // קו מפריד אמצעי ארוך
        /From:[\s\S]*?Sent:/i      // פורוורד או תבניות אאוטלוק
      ];
    
      for (let pattern of historySplitters) {
        // חיתוך הטקסט ברגע שנמצאת תבנית היסטוריה
        const parts = cleanBody.split(pattern);
        if (parts.length > 1) {
          cleanBody = parts[0];
        }
      }
      
      cleanBody = cleanBody.trim(); // הסרת רווחים מיותרים בהתחלה ובסוף
      // --- סוף חלק ניקוי הודעות ---
    
      // --- חלק חדש: טיפול בנושא ההודעה ---
      let rawSubject = message.getSubject() || "";
      // ניקוי קידומות כמו Re, Fwd שגורמות לתרגום שגוי (כמו "מחדש")
      rawSubject = rawSubject.replace(/^([Rr][Ee]|[Ff][Ww][Dd]?):\s*/, '').trim();
    
      let finalSubjectString = "";
    
      if (rawSubject === "") {
        finalSubjectString = "אין נושא להודעה";
      } else {
        let subjectTranslate;
        try {
          subjectTranslate = LanguageApp.translate(rawSubject, '', 'iw');
        } catch (err) { 
          subjectTranslate = rawSubject; 
        }
        // כאן מחברים את המילה 'נושא' עם התרגום
        finalSubjectString = `${TextSubject}. ${subjectTranslate}`;
      }
      // --- סוף חלק טיפול בנושא ---
    
      let bodyTranslate;
      try {
        // שימוש ב-cleanBody במקום message.getPlainBody()
        bodyTranslate = LanguageApp.translate(cleanBody, '', 'iw');
      } catch (err) { bodyTranslate = cleanBody; }
    
      const AttachmentNames = message.getAttachments().map(file => file.getName());
      const fullSender = message.getFrom();
      let senderName = fullSender;
      if (fullSender.includes('<')) {
        senderName = fullSender.split('<')[0].trim();
        if (senderName === "") { senderName = fullSender.split('<')[1].split('@')[0].trim(); }
      } else if (fullSender.includes('@')) {
        senderName = fullSender.split('@')[0].trim();
      }
    
      // שימוש במחרוזת הנושא המעובדת (finalSubjectString) במקום הלוגיקה הישנה
      const TtsStringTitle = `${TextSender}. ${senderName}. ${finalSubjectString}. ${AttachmentNames.length ? `${TextAttachments}.
      ${AttachmentNames.join(', ')}` : `${TextNoAttachments}.`} ${TextHour} ${MessageDate.getHours()} ${TextAnd} ${MessageDate.getMinutes()} ${TextMinute}. ${TextDay} ${HebrewDay[MessageDate.getDay()]}. ${TextDate} ${NumericDay} ${MonthAndYear} ${NumericYear}.`;
      
      let ttsString = `${TextBody}. ${bodyTranslate}.`;
      const attachments = message.getAttachments();
      let audioFilesToUpload = [];
      for (let i = 0; i < attachments.length; i++) {
        let file = attachments[i];
        if (isPdf(file)) {
          let pdfText = extractTextFromPdf(file);
          if (pdfText) {
            ttsString += `\nתוכן קובץ פי די אף, ${file.getName()}: ${pdfText}.
            סוף קובץ.`;
          }
        } else if (isAudio(file)) {
          audioFilesToUpload.push(file);
          ttsString += `\nמצורף קובץ שמע: ${file.getName()}. יושמע מיד עם סיום ההודעה...`;
        }
      }
    
      ReplacementPatterns.forEach(pattern => {
        const regex = new RegExp(pattern[0], 'g');
        ttsString = ttsString.replace(regex, pattern[1]);
      });
      // לוגיקת חיתוך לגוגל ומחרוזת מלאה לגיבוי
      const fullTtsString = ttsString + TextEnd;
      let googleTtsString = ttsString;
      if (googleTtsString.length > 4950) {
        googleTtsString = googleTtsString.substring(0, 4950);
      }
      googleTtsString += TextEnd;
      const MaxFileName = fetch('GetIVR2DirStats', { token, path: PathArchive });
      if (MaxFileName.responseStatus === 'OK') {
        const LastFileName = MaxFileName.maxFile?.name?.split('.')[0];
        let CurrentFileNum = (LastFileName !== undefined) ? Number(LastFileName) + 1 : 1;
        for (let j = 0; j < audioFilesToUpload.length; j++) {
          let attachmentName = CurrentFileNum.toString().padStart(3, '0') + ".wav";
          if (uploadBlobToYemot(audioFilesToUpload[j], PathArchive, attachmentName, token, true)) {
            CurrentFileNum++;
          }
        }
    
        let BodyFileName = CurrentFileNum.toString().padStart(3, '0');
        // ניסיון ראשון: Google Cloud TTS (עם הטקסט החתוך במידת הצורך)
        if (GOOGLE_API_KEY) {
          try {
            const titleBlob = googleTts(TtsStringTitle, GOOGLE_API_KEY, GOOGLE_TTS_LANG, GOOGLE_TTS_VOICE);
            const bodyBlob = googleTts(googleTtsString, GOOGLE_API_KEY, GOOGLE_TTS_LANG, GOOGLE_TTS_VOICE);
    
            if (titleBlob && bodyBlob) {
              const resTitle = uploadBlobToYemot(titleBlob, PathArchive, `${BodyFileName}-Title.mp3`, token, true);
              const resBody = uploadBlobToYemot(bodyBlob, PathArchive, `${BodyFileName}.mp3`, token, true);
              if (resTitle && resBody) return true;
            }
          } catch (e) {
            Logger.log(`Google TTS נכשל: ${e}. עובר לגיבוי רובוטי.`);
          }
        }
    
        // גיבוי: שליחה למנוע הרובוטי של ימות המשיח (טקסט מלא)
        try {
          const resTitle = fetch('UploadTextFile', { token, what: `${PathArchive}${BodyFileName}-Title.tts`, contents: TtsStringTitle });
          const resBody = fetch('UploadTextFile', { token, what: `${PathArchive}${BodyFileName}.tts`, contents: fullTtsString });
          return resTitle.responseStatus === 'OK' && resBody.responseStatus === 'OK';
        } catch (e) {
          Logger.log(`שגיאה בגיבוי רובוטי: ${e}`);
          return false;
        }
      }
      return false;
    }
    
    // --- פונקציות עזר ---
    
    function isPdf(file) {
      return file.getContentType() === 'application/pdf' || file.getName().toLowerCase().endsWith('.pdf');
    }
    
    function isAudio(file) {
      const type = file.getContentType();
      const name = file.getName().toLowerCase();
      return (type.startsWith('audio/') || type === 'application/octet-stream') && 
             name.match(/\.(mp3|wav|m4a|wma|aac|ogg)$/);
    }
    
    function extractTextFromPdf(blob) {
      try {
        var newBlob = blob.copyBlob();
        newBlob.setContentType('application/pdf');
        const resource = { title: newBlob.getName(), mimeType: 'application/pdf' };
        const file = Drive.Files.insert(resource, newBlob, { ocr: true, ocrLanguage: 'he' });
        Utilities.sleep(1000);
        const doc = DocumentApp.openById(file.id);
        const text = doc.getBody().getText();
        Drive.Files.remove(file.id);
        return text;
      } catch (e) {
        Logger.log("שגיאה בחילוץ טקסט מ-PDF: " + e);
        return "";
      }
    }
    
    function testToken() { return !!token; }
    function getToken() { return token;
    }
    
    function fetch(action, params) {
      // כאן יש לממש את הקריאה ל-API של ימות המשיח
      Logger.log(`fetch action: ${action}`);
      return { responseStatus: 'OK', extIni: { menu_voice: "" }, maxFile: { name: "000.mp3" } };
    }
    
    function uploadBlobToYemot(blob, path, name, tokenParam, binary) {
      // כאן יש לממש את העלאת ה-Blob לשרת
      Logger.log(`uploading ${name} to ${path}`);
      return true;
    }
    
    function googleTts(text, apiKey, lang, voice) {
      // כאן יש לממש את הקריאה ל-API של גוגל
      try {
        return Utilities.newBlob('', 'audio/mpeg', 'tts.mp3');
      } catch (e) {
        Logger.log(`googleTts error: ${e}`);
        return null;
      }
    }
    
    function tzintuk() { Logger.log('tzintuk triggered');
    }
    function isNowSilenceTime(range) { return false; }
    function getFilterLists() { return { blockedEmails: [], vipEmails: [], blockedSubjects: [] };
    }
    function markAsHandled(sheet, id) { sheet.getRange(sheet.getLastRow() + 1, 1).setValue(id); }
    function gimatria(input) { return input; }
    function processOutgoingMails() { Logger.log('processOutgoingMails called'); }
    
    רשתות

  • שאלה | פיתוח חדש לחיסכון בחשמל ובכסף וניהול מים חמים - אשמח לדעתכם כבעלי משפחות
    מ מוגן

    @איש-אמת

    כנראה שהרחתי נכון, אתה הגדרת איך קוראים לריח...😉

    חשמל ביתי

  • שאלה | פיתוח חדש לחיסכון בחשמל ובכסף וניהול מים חמים - אשמח לדעתכם כבעלי משפחות
    מ מוגן

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

    חשמל ביתי

  • שאלה | פיתוח חדש לחיסכון בחשמל ובכסף וניהול מים חמים - אשמח לדעתכם כבעלי משפחות
    מ מוגן

    @עדי-פרפרה נראה לי שיהיה לזה הרבה ביקוש אם יהיה ניתן לשמוע נתונים כתחליף במערכת טלפונית!

    חשמל ביתי

  • שיתוף | קו תמלול שנשלח למייל דרך מודלים מתקדמים של ג'מיני כולל יצירת קריינות ממוחשבת ועוד..
    מ מוגן

    @ARISHאין מענה משרת API

    עזרה הדדית - מחשבים וטכנולוגיה

  • בקשה | מחפש שיבנו לי קו בימות המשיח של בעלי מקצוע
    מ מוגן

    @שמואל-ח. תשלח אפיון

    כללי - עזרה הדדית

  • שיתוף | 'פלאפון מייל' - כולל קבלת ושליחת מיילים דרך הפלאפון, קריינות מקצועית, ועוד...
    מ מוגן

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

    רשתות

  • שיתוף | סקריפט לטמפרמונקי ליצירת Markdown במערכת הפניות של נטפרי! V 3.0
    מ מוגן

    @לאצי מאוד יפה אבל ההגדרה של הצבעים לא עובד בפועל!

    נטפרי

  • באג | מעבר לשלוחה אחרת - לא עובד.
    מ מוגן

    @מנשה-2 תעשה ריענון לאתר ותגדיר שוב

    עזרה הדדית - מחשבים וטכנולוגיה

  • שיתוף | חדש תזמון הודעות בגוגל צאט !!!!
    מ מוגן

    @לומדעס משהו מוזר.. בבוקר עבד לי וכעת הפסיק לעבוד, האופציה הזו לא נלחצת מה יכול להיות הסיבה?

    עזרה הדדית - מחשבים וטכנולוגיה
  • התחברות

  • אין לך חשבון עדיין? הרשמה

  • התחברו או הירשמו כדי לחפש.
  • פוסט ראשון
    פוסט אחרון
0
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר