דילוג לתוכן
  • חוקי הפורום
  • פופולרי
  • לא נפתר
  • משתמשים
  • חיפוש גוגל בפורום
  • צור קשר
עיצובים
  • 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. דף הבית
  2. מחשבים וטכנולוגיה
  3. עזרה הדדית - מחשבים וטכנולוגיה
  4. המלצה | תוסף להורדת הודעות אודיו בגוגל צ'אט

המלצה | תוסף להורדת הודעות אודיו בגוגל צ'אט

מתוזמן נעוץ נעול הועבר עזרה הדדית - מחשבים וטכנולוגיה
8 פוסטים 3 כותבים 67 צפיות 3 עוקבים
  • מהישן לחדש
  • מהחדש לישן
  • הכי הרבה הצבעות
תגובה
  • תגובה כנושא
התחברו כדי לפרסם תגובה
נושא זה נמחק. רק משתמשים עם הרשאות מתאימות יוכלו לצפות בו.
  • ר מחובר
    ר מחובר
    רפי סאם
    כתב נערך לאחרונה על ידי
    #1

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


    3aafff0d-99a0-4a65-aefd-245ae6977884-image.png

    ר תגובה 1 תגובה אחרונה
    4
    • ר רפי סאם התייחס לנושא זה
    • ר רפי סאם

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


      3aafff0d-99a0-4a65-aefd-245ae6977884-image.png

      ר מחובר
      ר מחובר
      רפי סאם
      כתב נערך לאחרונה על ידי
      #2

      לכל המעוניין
      הנה קוד לטפרמונקי

      // @name         GChat Audio Download
      // @namespace    https://chat.google.com/
      // @version      1.0
      // @description  מוסיף כפתור הורדה להודעות שמע ב-Google Chat
      // @author       You
      // @match        https://chat.google.com/*
      // @grant        none
      // @run-at       document-idle
      // ==/UserScript==
      
      (() => {
        const DONE = 'gchat-dl-done';
      
        function makeBtn(url) {
          const b = document.createElement('button');
          b.textContent = '⬇ הורד שמע';
          b.style.cssText = `
            all: initial;
            display: block !important;
            margin: 4px 8px 6px 8px !important;
            padding: 4px 16px !important;
            background: #1a73e8 !important;
            color: white !important;
            border: none !important;
            border-radius: 20px !important;
            font: 500 12px "Google Sans",Arial,sans-serif !important;
            cursor: pointer !important;
            direction: rtl !important;
            box-sizing: border-box !important;
          `;
          b.onmouseenter = () => b.style.setProperty('background', '#1557b0', 'important');
          b.onmouseleave = () => b.style.setProperty('background', '#1a73e8', 'important');
          b.onclick = async (e) => {
            e.stopPropagation(); e.preventDefault();
            b.textContent = '⏳ מוריד…';
            b.style.setProperty('background', '#f9ab00', 'important');
            b.style.setProperty('color', '#000', 'important');
            try {
              const r = await fetch(url, { credentials: 'include' });
              if (!r.ok) throw new Error(r.status);
              const blob = await r.blob();
              const ext = blob.type.includes('ogg') ? 'ogg'
                        : blob.type.includes('webm') ? 'webm'
                        : blob.type.includes('wav') ? 'wav' : 'mp3';
              const a = document.createElement('a');
              a.href = URL.createObjectURL(blob);
              a.download = `gchat-${Date.now()}.${ext}`;
              document.body.appendChild(a); a.click();
              setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(a.href); }, 9000);
              b.textContent = '✓ הורד!';
              b.style.setProperty('background', '#34a853', 'important');
              b.style.setProperty('color', 'white', 'important');
              setTimeout(() => {
                b.textContent = '⬇ הורד שמע';
                b.style.setProperty('background', '#1a73e8', 'important');
                b.style.setProperty('color', 'white', 'important');
              }, 3000);
            } catch(err) {
              b.textContent = '✗ שגיאה';
              b.style.setProperty('background', '#ea4335', 'important');
              b.style.setProperty('color', 'white', 'important');
              setTimeout(() => {
                b.textContent = '⬇ הורד שמע';
                b.style.setProperty('background', '#1a73e8', 'important');
                b.style.setProperty('color', 'white', 'important');
              }, 3000);
            }
          };
          return b;
        }
      
        function tryInject(el) {
          if (!(el instanceof Element)) return;
          if (el.hasAttribute(DONE)) return;
          const url = el.getAttribute('data-media-url');
          if (!url || !url.includes('get_attachment_url')) return;
          el.setAttribute(DONE, '1');
          const parent = el.closest('.DwygBd') || el.parentElement;
          if (parent) {
            parent.appendChild(makeBtn(url));
            console.log('[DL] ✅ injected');
          }
        }
      
        function scan() {
          document.querySelectorAll('[data-media-url]').forEach(tryInject);
        }
      
        new MutationObserver(muts => {
          for (const m of muts) {
            for (const n of m.addedNodes) {
              if (n.nodeType !== 1) continue;
              tryInject(n);
              n.querySelectorAll?.('[data-media-url]').forEach(tryInject);
            }
            if (m.type === 'attributes' && m.target instanceof Element) {
              tryInject(m.target);
            }
          }
        }).observe(document.documentElement, {
          childList: true, subtree: true,
          attributes: true, attributeFilter: ['data-media-url']
        });
      
        [0, 500, 1000, 2000, 4000, 8000].forEach(t => setTimeout(scan, t));
      })();
      בנימין מחשביםב תגובה 1 תגובה אחרונה
      1
      • ר רפי סאם התייחס לנושא זה
      • ר רפי סאם

        לכל המעוניין
        הנה קוד לטפרמונקי

        // @name         GChat Audio Download
        // @namespace    https://chat.google.com/
        // @version      1.0
        // @description  מוסיף כפתור הורדה להודעות שמע ב-Google Chat
        // @author       You
        // @match        https://chat.google.com/*
        // @grant        none
        // @run-at       document-idle
        // ==/UserScript==
        
        (() => {
          const DONE = 'gchat-dl-done';
        
          function makeBtn(url) {
            const b = document.createElement('button');
            b.textContent = '⬇ הורד שמע';
            b.style.cssText = `
              all: initial;
              display: block !important;
              margin: 4px 8px 6px 8px !important;
              padding: 4px 16px !important;
              background: #1a73e8 !important;
              color: white !important;
              border: none !important;
              border-radius: 20px !important;
              font: 500 12px "Google Sans",Arial,sans-serif !important;
              cursor: pointer !important;
              direction: rtl !important;
              box-sizing: border-box !important;
            `;
            b.onmouseenter = () => b.style.setProperty('background', '#1557b0', 'important');
            b.onmouseleave = () => b.style.setProperty('background', '#1a73e8', 'important');
            b.onclick = async (e) => {
              e.stopPropagation(); e.preventDefault();
              b.textContent = '⏳ מוריד…';
              b.style.setProperty('background', '#f9ab00', 'important');
              b.style.setProperty('color', '#000', 'important');
              try {
                const r = await fetch(url, { credentials: 'include' });
                if (!r.ok) throw new Error(r.status);
                const blob = await r.blob();
                const ext = blob.type.includes('ogg') ? 'ogg'
                          : blob.type.includes('webm') ? 'webm'
                          : blob.type.includes('wav') ? 'wav' : 'mp3';
                const a = document.createElement('a');
                a.href = URL.createObjectURL(blob);
                a.download = `gchat-${Date.now()}.${ext}`;
                document.body.appendChild(a); a.click();
                setTimeout(() => { document.body.removeChild(a); URL.revokeObjectURL(a.href); }, 9000);
                b.textContent = '✓ הורד!';
                b.style.setProperty('background', '#34a853', 'important');
                b.style.setProperty('color', 'white', 'important');
                setTimeout(() => {
                  b.textContent = '⬇ הורד שמע';
                  b.style.setProperty('background', '#1a73e8', 'important');
                  b.style.setProperty('color', 'white', 'important');
                }, 3000);
              } catch(err) {
                b.textContent = '✗ שגיאה';
                b.style.setProperty('background', '#ea4335', 'important');
                b.style.setProperty('color', 'white', 'important');
                setTimeout(() => {
                  b.textContent = '⬇ הורד שמע';
                  b.style.setProperty('background', '#1a73e8', 'important');
                  b.style.setProperty('color', 'white', 'important');
                }, 3000);
              }
            };
            return b;
          }
        
          function tryInject(el) {
            if (!(el instanceof Element)) return;
            if (el.hasAttribute(DONE)) return;
            const url = el.getAttribute('data-media-url');
            if (!url || !url.includes('get_attachment_url')) return;
            el.setAttribute(DONE, '1');
            const parent = el.closest('.DwygBd') || el.parentElement;
            if (parent) {
              parent.appendChild(makeBtn(url));
              console.log('[DL] ✅ injected');
            }
          }
        
          function scan() {
            document.querySelectorAll('[data-media-url]').forEach(tryInject);
          }
        
          new MutationObserver(muts => {
            for (const m of muts) {
              for (const n of m.addedNodes) {
                if (n.nodeType !== 1) continue;
                tryInject(n);
                n.querySelectorAll?.('[data-media-url]').forEach(tryInject);
              }
              if (m.type === 'attributes' && m.target instanceof Element) {
                tryInject(m.target);
              }
            }
          }).observe(document.documentElement, {
            childList: true, subtree: true,
            attributes: true, attributeFilter: ['data-media-url']
          });
        
          [0, 500, 1000, 2000, 4000, 8000].forEach(t => setTimeout(scan, t));
        })();
        בנימין מחשביםב מנותק
        בנימין מחשביםב מנותק
        בנימין מחשבים
        כתב נערך לאחרונה על ידי
        #3

        @רפי-סאם כתב בהמלצה | תוסף להורדת הודעות אודיו בגוגל צ'אט:

        קוד לטפרמונקי

        מישהו ניסה?
        כי ג'יימיני טוען שזה לא יעבוד (כאילו אפשר לסמוך עליו בזה... 🙄)

        "הקוד שכתבת נראה כמו ניסיון יפה "לדוג" את קבצי השמע מתוך הממשק של Google Chat, אבל ב-Google כמו ב-Google, העניינים קצת יותר מורכבים מסריקה פשוטה של ה-DOM. יש כמה סיבות טכניות למה הקוד הזה כנראה לא יספק את הסחורה:

        1. בעיית ה-Selector והמבנה הדינמי
          הסתמכת על ה-Attribute בשם data-media-url. גוגל משנה לעיתים קרובות את שמות המחלקות (Classes) והמאפיינים של האלמנטים שלהם. אם המאפיין הזה לא קיים בדיוק בשם הזה על האלמנט שחיפשת, ה-MutationObserver וה-querySelectorAll פשוט לא ימצאו כלום.

        2. הזרקה ל-Shadow DOM (אולי)
          חלק מהרכיבים החדשים ביישומי Google משתמשים ב-Shadow DOM. אם נגן השמע נמצא בתוך Shadow Root, ה-document.querySelectorAll הרגיל שלך לא "רואה" אותו, ולכן לא יכול להזריק את הכפתור.

        3. מדיניות אבטחה (CORS & CSP)
          גם אם הצלחת להזריק את הכפתור, הפקודה fetch(url) כנראה תיחסם:

        CSP (Content Security Policy): גוגל מגבילה לעיתים קרובות מאיזה מקורות מותר להוריד נתונים בדף.

        CORS: השרת שמארח את קבצי השמע (לרוב googleusercontent.com) עשוי לא לאפשר בקשות Fetch ישירות מהסקריפט ללא הגדרות מתאימות.

        1. זיהוי האלמנט הלא נכון
          השתמשת ב-.closest('.DwygBd'). השם DwygBd הוא שם מחלקה מעורבל (obfuscated). שמות כאלו משתנים בכל עדכון גרסה של Google Chat. ברגע שהם מעדכנים גרסה, הסקריפט שלך הופך להיסטוריה.

        מה אפשר לעשות?
        כדי שזה יעבוד באמת, כדאי לשנות גישה:

        זיהוי גנרי יותר: במקום לחפש data-media-url, חפש אלמנטים של audio או source בתוך הודעות, או אלמנטים עם role="button" שיש להם טקסט או תיאור שקשור להשמעה.

        שימוש ב-GM_xmlhttpRequest: אם אתה משתמש ב-Tampermonkey, כדאי להשתמש ב-GM_xmlhttpRequest (במקום fetch) כדי לעקוף מגבלות CORS.

        בדיקת ה-Network: לפעמים ה-URL של השמע נוצר רק ברגע שלוחצים על Play. במקרה כזה, הסקריפט שלך שמחפש בטעינה ראשונית לא ימצא כלום.

        תרצה שאנסה לעזור לך למצוא סלקטור (Selector) יותר יציב או לכתוב פונקציה שתעקוף את בעיית ה-CORS?"

        ר תגובה 1 תגובה אחרונה
        0
        • בנימין מחשביםב בנימין מחשבים

          @רפי-סאם כתב בהמלצה | תוסף להורדת הודעות אודיו בגוגל צ'אט:

          קוד לטפרמונקי

          מישהו ניסה?
          כי ג'יימיני טוען שזה לא יעבוד (כאילו אפשר לסמוך עליו בזה... 🙄)

          "הקוד שכתבת נראה כמו ניסיון יפה "לדוג" את קבצי השמע מתוך הממשק של Google Chat, אבל ב-Google כמו ב-Google, העניינים קצת יותר מורכבים מסריקה פשוטה של ה-DOM. יש כמה סיבות טכניות למה הקוד הזה כנראה לא יספק את הסחורה:

          1. בעיית ה-Selector והמבנה הדינמי
            הסתמכת על ה-Attribute בשם data-media-url. גוגל משנה לעיתים קרובות את שמות המחלקות (Classes) והמאפיינים של האלמנטים שלהם. אם המאפיין הזה לא קיים בדיוק בשם הזה על האלמנט שחיפשת, ה-MutationObserver וה-querySelectorAll פשוט לא ימצאו כלום.

          2. הזרקה ל-Shadow DOM (אולי)
            חלק מהרכיבים החדשים ביישומי Google משתמשים ב-Shadow DOM. אם נגן השמע נמצא בתוך Shadow Root, ה-document.querySelectorAll הרגיל שלך לא "רואה" אותו, ולכן לא יכול להזריק את הכפתור.

          3. מדיניות אבטחה (CORS & CSP)
            גם אם הצלחת להזריק את הכפתור, הפקודה fetch(url) כנראה תיחסם:

          CSP (Content Security Policy): גוגל מגבילה לעיתים קרובות מאיזה מקורות מותר להוריד נתונים בדף.

          CORS: השרת שמארח את קבצי השמע (לרוב googleusercontent.com) עשוי לא לאפשר בקשות Fetch ישירות מהסקריפט ללא הגדרות מתאימות.

          1. זיהוי האלמנט הלא נכון
            השתמשת ב-.closest('.DwygBd'). השם DwygBd הוא שם מחלקה מעורבל (obfuscated). שמות כאלו משתנים בכל עדכון גרסה של Google Chat. ברגע שהם מעדכנים גרסה, הסקריפט שלך הופך להיסטוריה.

          מה אפשר לעשות?
          כדי שזה יעבוד באמת, כדאי לשנות גישה:

          זיהוי גנרי יותר: במקום לחפש data-media-url, חפש אלמנטים של audio או source בתוך הודעות, או אלמנטים עם role="button" שיש להם טקסט או תיאור שקשור להשמעה.

          שימוש ב-GM_xmlhttpRequest: אם אתה משתמש ב-Tampermonkey, כדאי להשתמש ב-GM_xmlhttpRequest (במקום fetch) כדי לעקוף מגבלות CORS.

          בדיקת ה-Network: לפעמים ה-URL של השמע נוצר רק ברגע שלוחצים על Play. במקרה כזה, הסקריפט שלך שמחפש בטעינה ראשונית לא ימצא כלום.

          תרצה שאנסה לעזור לך למצוא סלקטור (Selector) יותר יציב או לכתוב פונקציה שתעקוף את בעיית ה-CORS?"

          ר מחובר
          ר מחובר
          רפי סאם
          כתב נערך לאחרונה על ידי
          #4

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

          הטפרמונקי לא נוסה על ידי...

          מים אחרוניםמ תגובה 1 תגובה אחרונה
          0
          • יאיר דניאלי יאיר דניאל התייחס לנושא זה
          • יאיר דניאלי יאיר דניאל התייחס לנושא זה
          • ר רפי סאם

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

            הטפרמונקי לא נוסה על ידי...

            מים אחרוניםמ מנותק
            מים אחרוניםמ מנותק
            מים אחרונים
            כתב נערך לאחרונה על ידי
            #5

            @רפי-סאם והוא לא עובד באמת...

            ר תגובה 1 תגובה אחרונה
            0
            • מים אחרוניםמ מים אחרונים

              @רפי-סאם והוא לא עובד באמת...

              ר מחובר
              ר מחובר
              רפי סאם
              כתב נערך לאחרונה על ידי
              #6

              @מים-אחרונים הגיוני - לא ניסיתי את זה

              תגובה 1 תגובה אחרונה
              0
              • מים אחרוניםמ מנותק
                מים אחרוניםמ מנותק
                מים אחרונים
                כתב נערך לאחרונה על ידי
                #7

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

                // ==UserScript==
                // @name         Google Chat Audio Pro: Player & Downloader
                // @namespace    http://tampermonkey.net/
                // @version      2.0
                // @description  משדרג את חווית האודיו ב-Google Chat: נגן מוטמע וכפתור הורדה מהירה
                // @author       מים אחרונים - ג'מיני
                // @match        https://chat.google.com/*
                // @match        https://mail.google.com/*
                // @grant        none
                // ==/UserScript==
                
                (function() {
                    'use strict';
                
                    const PROCESSED_ATTR = 'data-gchat-audio-processed';
                
                    // --- עיצוב (CSS) ---
                    const style = document.createElement('style');
                    style.innerHTML = `
                        .custom-audio-container {
                            display: flex;
                            flex-direction: column;
                            gap: 8px;
                            background: #ffffff;
                            border: 1px solid #e0e3e7;
                            border-radius: 16px;
                            padding: 12px;
                            max-width: 350px;
                            margin: 8px 0;
                            box-shadow: 0 2px 5px rgba(0,0,0,0.05);
                            direction: rtl;
                            font-family: 'Google Sans', Roboto, Arial, sans-serif;
                        }
                
                        .audio-header {
                            display: flex;
                            align-items: center;
                            gap: 10px;
                        }
                
                        .audio-icon-wrapper {
                            width: 32px;
                            height: 32px;
                            background: #e8f0fe;
                            color: #1a73e8;
                            border-radius: 50%;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            flex-shrink: 0;
                        }
                
                        .audio-info {
                            flex-grow: 1;
                            overflow: hidden;
                        }
                
                        .audio-title {
                            font-size: 13px;
                            font-weight: 500;
                            color: #3c4043;
                            white-space: nowrap;
                            overflow: hidden;
                            text-overflow: ellipsis;
                        }
                
                        .audio-player-element {
                            width: 100%;
                            height: 32px;
                            margin-top: 4px;
                        }
                
                        .download-btn {
                            align-self: flex-start;
                            background: #1a73e8;
                            color: white;
                            border: none;
                            border-radius: 8px;
                            padding: 6px 14px;
                            font-size: 12px;
                            font-weight: 500;
                            cursor: pointer;
                            display: flex;
                            align-items: center;
                            gap: 6px;
                            transition: background 0.2s;
                        }
                
                        .download-btn:hover {
                            background: #1557b0;
                        }
                
                        /* הסתרת הצ'יפ המקורי של גוגל למניעת כפילות */
                        .original-audio-hidden {
                            display: none !important;
                        }
                    `;
                    document.head.appendChild(style);
                
                    // --- פונקציות עזר ---
                
                    function getAudioUrl(el) {
                        // מנסה לחלץ מ-data-media-url או מקישורי הורדה פנימיים
                        const mediaUrl = el.getAttribute('data-media-url');
                        if (mediaUrl && mediaUrl.includes('get_attachment_url')) return mediaUrl;
                
                        const link = el.querySelector('a[href*="DOWNLOAD_URL"], a[href*="attachment_token"]');
                        if (link) return link.href;
                
                        const img = el.querySelector('img[src*="attachment_token"]');
                        if (img) {
                            return img.src.replace('url_type=THUMBNAIL_URL', 'url_type=DOWNLOAD_URL').replace('&sz=w512', '');
                        }
                        return null;
                    }
                
                    function getFileName(el) {
                        const titleEl = el.querySelector('[title]');
                        if (titleEl) return titleEl.getAttribute('title');
                        const spanEl = el.querySelector('.RhNmFb');
                        return spanEl ? spanEl.textContent.trim() : 'קובץ שמע';
                    }
                
                    function isAudioElement(el) {
                        // בדיקת מחלקות מוכרות של גוגל לקובצי שמע
                        if (el.classList.contains('fgkZ3')) return true;
                        const title = el.querySelector('[title]');
                        if (title && /\.(mp3|wav|ogg|aac|m4a|flac|opus)$/i.test(title.getAttribute('title'))) return true;
                        return el.querySelector('img[src*="audio_x128"], img[src*="audio_x32"]') !== null;
                    }
                
                    function createPlayer(url, fileName) {
                        const container = document.createElement('div');
                        container.className = 'custom-audio-container';
                        container.innerHTML = `
                            <div class="audio-header">
                                <div class="audio-icon-wrapper">
                                    <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>
                                </div>
                                <div class="audio-info">
                                    <div class="audio-title" title="${fileName}">${fileName}</div>
                                </div>
                            </div>
                            <audio controls preload="none" class="audio-player-element">
                                <source src="${url}" type="audio/mpeg">
                            </audio>
                            <button class="download-btn">
                                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
                                הורדה
                            </button>
                        `;
                
                        container.querySelector('.download-btn').onclick = (e) => {
                            e.stopPropagation();
                            window.open(url, '_blank');
                        };
                
                        return container;
                    }
                
                    function process() {
                        // סלקטורים המכסים את רוב סוגי הבועות ב-Chat
                        const chips = document.querySelectorAll(`.fgkZ3:not([${PROCESSED_ATTR}]), .lRPruf[jsname="sBlcJe"]:not([${PROCESSED_ATTR}]), .V5MAMb.ykJ07e:not([${PROCESSED_ATTR}])`);
                
                        chips.forEach(chip => {
                            if (isAudioElement(chip)) {
                                const url = getAudioUrl(chip);
                                if (!url) return;
                
                                const fileName = getFileName(chip);
                                const player = createPlayer(url, fileName);
                
                                chip.setAttribute(PROCESSED_ATTR, 'true');
                
                                // הזרקה לדף: מחפשים את ההורה המתאים ביותר
                                const parent = chip.closest('.DwygBd') || chip.parentElement;
                                parent.appendChild(player);
                
                                // הסתרת האלמנט המקורי של גוגל
                                chip.classList.add('original-audio-hidden');
                            }
                        });
                    }
                
                    // הפעלה וניטור שינויים בדף (MutationObserver)
                    const observer = new MutationObserver(() => process());
                    observer.observe(document.body, { childList: true, subtree: true });
                
                    // הרצה ראשונית
                    process();
                
                })();
                
                מים אחרוניםמ תגובה 1 תגובה אחרונה
                0
                • מים אחרוניםמ מים אחרונים

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

                  // ==UserScript==
                  // @name         Google Chat Audio Pro: Player & Downloader
                  // @namespace    http://tampermonkey.net/
                  // @version      2.0
                  // @description  משדרג את חווית האודיו ב-Google Chat: נגן מוטמע וכפתור הורדה מהירה
                  // @author       מים אחרונים - ג'מיני
                  // @match        https://chat.google.com/*
                  // @match        https://mail.google.com/*
                  // @grant        none
                  // ==/UserScript==
                  
                  (function() {
                      'use strict';
                  
                      const PROCESSED_ATTR = 'data-gchat-audio-processed';
                  
                      // --- עיצוב (CSS) ---
                      const style = document.createElement('style');
                      style.innerHTML = `
                          .custom-audio-container {
                              display: flex;
                              flex-direction: column;
                              gap: 8px;
                              background: #ffffff;
                              border: 1px solid #e0e3e7;
                              border-radius: 16px;
                              padding: 12px;
                              max-width: 350px;
                              margin: 8px 0;
                              box-shadow: 0 2px 5px rgba(0,0,0,0.05);
                              direction: rtl;
                              font-family: 'Google Sans', Roboto, Arial, sans-serif;
                          }
                  
                          .audio-header {
                              display: flex;
                              align-items: center;
                              gap: 10px;
                          }
                  
                          .audio-icon-wrapper {
                              width: 32px;
                              height: 32px;
                              background: #e8f0fe;
                              color: #1a73e8;
                              border-radius: 50%;
                              display: flex;
                              align-items: center;
                              justify-content: center;
                              flex-shrink: 0;
                          }
                  
                          .audio-info {
                              flex-grow: 1;
                              overflow: hidden;
                          }
                  
                          .audio-title {
                              font-size: 13px;
                              font-weight: 500;
                              color: #3c4043;
                              white-space: nowrap;
                              overflow: hidden;
                              text-overflow: ellipsis;
                          }
                  
                          .audio-player-element {
                              width: 100%;
                              height: 32px;
                              margin-top: 4px;
                          }
                  
                          .download-btn {
                              align-self: flex-start;
                              background: #1a73e8;
                              color: white;
                              border: none;
                              border-radius: 8px;
                              padding: 6px 14px;
                              font-size: 12px;
                              font-weight: 500;
                              cursor: pointer;
                              display: flex;
                              align-items: center;
                              gap: 6px;
                              transition: background 0.2s;
                          }
                  
                          .download-btn:hover {
                              background: #1557b0;
                          }
                  
                          /* הסתרת הצ'יפ המקורי של גוגל למניעת כפילות */
                          .original-audio-hidden {
                              display: none !important;
                          }
                      `;
                      document.head.appendChild(style);
                  
                      // --- פונקציות עזר ---
                  
                      function getAudioUrl(el) {
                          // מנסה לחלץ מ-data-media-url או מקישורי הורדה פנימיים
                          const mediaUrl = el.getAttribute('data-media-url');
                          if (mediaUrl && mediaUrl.includes('get_attachment_url')) return mediaUrl;
                  
                          const link = el.querySelector('a[href*="DOWNLOAD_URL"], a[href*="attachment_token"]');
                          if (link) return link.href;
                  
                          const img = el.querySelector('img[src*="attachment_token"]');
                          if (img) {
                              return img.src.replace('url_type=THUMBNAIL_URL', 'url_type=DOWNLOAD_URL').replace('&sz=w512', '');
                          }
                          return null;
                      }
                  
                      function getFileName(el) {
                          const titleEl = el.querySelector('[title]');
                          if (titleEl) return titleEl.getAttribute('title');
                          const spanEl = el.querySelector('.RhNmFb');
                          return spanEl ? spanEl.textContent.trim() : 'קובץ שמע';
                      }
                  
                      function isAudioElement(el) {
                          // בדיקת מחלקות מוכרות של גוגל לקובצי שמע
                          if (el.classList.contains('fgkZ3')) return true;
                          const title = el.querySelector('[title]');
                          if (title && /\.(mp3|wav|ogg|aac|m4a|flac|opus)$/i.test(title.getAttribute('title'))) return true;
                          return el.querySelector('img[src*="audio_x128"], img[src*="audio_x32"]') !== null;
                      }
                  
                      function createPlayer(url, fileName) {
                          const container = document.createElement('div');
                          container.className = 'custom-audio-container';
                          container.innerHTML = `
                              <div class="audio-header">
                                  <div class="audio-icon-wrapper">
                                      <svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>
                                  </div>
                                  <div class="audio-info">
                                      <div class="audio-title" title="${fileName}">${fileName}</div>
                                  </div>
                              </div>
                              <audio controls preload="none" class="audio-player-element">
                                  <source src="${url}" type="audio/mpeg">
                              </audio>
                              <button class="download-btn">
                                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
                                  הורדה
                              </button>
                          `;
                  
                          container.querySelector('.download-btn').onclick = (e) => {
                              e.stopPropagation();
                              window.open(url, '_blank');
                          };
                  
                          return container;
                      }
                  
                      function process() {
                          // סלקטורים המכסים את רוב סוגי הבועות ב-Chat
                          const chips = document.querySelectorAll(`.fgkZ3:not([${PROCESSED_ATTR}]), .lRPruf[jsname="sBlcJe"]:not([${PROCESSED_ATTR}]), .V5MAMb.ykJ07e:not([${PROCESSED_ATTR}])`);
                  
                          chips.forEach(chip => {
                              if (isAudioElement(chip)) {
                                  const url = getAudioUrl(chip);
                                  if (!url) return;
                  
                                  const fileName = getFileName(chip);
                                  const player = createPlayer(url, fileName);
                  
                                  chip.setAttribute(PROCESSED_ATTR, 'true');
                  
                                  // הזרקה לדף: מחפשים את ההורה המתאים ביותר
                                  const parent = chip.closest('.DwygBd') || chip.parentElement;
                                  parent.appendChild(player);
                  
                                  // הסתרת האלמנט המקורי של גוגל
                                  chip.classList.add('original-audio-hidden');
                              }
                          });
                      }
                  
                      // הפעלה וניטור שינויים בדף (MutationObserver)
                      const observer = new MutationObserver(() => process());
                      observer.observe(document.body, { childList: true, subtree: true });
                  
                      // הרצה ראשונית
                      process();
                  
                  })();
                  
                  מים אחרוניםמ מנותק
                  מים אחרוניםמ מנותק
                  מים אחרונים
                  כתב נערך לאחרונה על ידי
                  #8

                  רק שיש אילו הם באגים 🙂
                  c352e2d9-9bf5-42dd-905f-cc3f991e906f-image.png

                  תגובה 1 תגובה אחרונה
                  0

                  • התחברות

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

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