Mydealz Nachrichten-Exporter

Exportiert alle Nachrichten aller Kontakte als mbox-Datei

// ==UserScript==
// @name         Mydealz Nachrichten-Exporter
// @namespace    https://www.mydealz.de/
// @version      1.0
// @description  Exportiert alle Nachrichten aller Kontakte als mbox-Datei
// @author       MD928835
// @match        https://www.mydealz.de/profile/messages*
// @match        https://www.mydealz.de/profile/*/settings*
// @license MIT 
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Stil für das Popup
    const style = document.createElement('style');
    style.textContent = `
        #export-popup {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 0 20px rgba(0,0,0,0.3);
            z-index: 10000;
            max-width: 80%;
            max-height: 80vh;
            overflow-y: auto;
            color: #333;
        }
        #export-popup h2 {
            margin-top: 0;
            border-bottom: 1px solid #ddd;
            padding-bottom: 10px;
        }
        #export-popup .buttons {
            margin-top: 15px;
            text-align: right;
        }
        #export-popup button {
            padding: 8px 15px;
            margin-left: 10px;
            border-radius: 4px;
            cursor: pointer;
        }
        #export-popup .status {
            margin-top: 10px;
            padding: 10px;
            background-color: #f5f5f5;
            border-radius: 4px;
        }
        #export-popup .progress {
            margin-top: 10px;
            height: 20px;
            background-color: #eee;
            border-radius: 4px;
            overflow: hidden;
        }
        #export-popup .progress-bar {
            height: 100%;
            background-color: #4CAF50;
            width: 0%;
            transition: width 0.3s;
        }
        #export-popup .log {
            margin-top: 10px;
            max-height: 200px;
            overflow-y: auto;
            font-family: monospace;
            font-size: 12px;
            background-color: #f8f8f8;
            padding: 10px;
            border-radius: 4px;
            white-space: pre-wrap;
            word-break: break-all;
        }
    `;
    document.head.appendChild(style);

    // Prüfen, ob wir auf der Einstellungsseite sind
    if (window.location.href.includes('/settings')) {
        // Button zum Exportieren der Nachrichten auf der Einstellungsseite hinzufügen
        const nutzerdatenContainer = document.querySelector('.formList-row .formList-content .iGrid-item');

        if (nutzerdatenContainer) {
            const exportButton = document.createElement('button');
            exportButton.type = 'button';
            exportButton.className = 'width--all-12 hAlign--all-c button button--shape-circle button--type-secondary button--mode-default';
            exportButton.style.marginTop = '10px';
            exportButton.innerHTML = '<span class="flex--inline boxAlign-ai--all-c">Nachrichten exportieren</span>';

            exportButton.addEventListener('click', function() {
                window.location.href = 'https://www.mydealz.de/profile/messages';
            });

            nutzerdatenContainer.appendChild(exportButton);
        }
    }
    // Wenn wir auf der Nachrichtenseite sind, starte den Export
    else if (window.location.href.includes('/messages')) {
        // Prüfen, ob wir von der Einstellungsseite kommen
        if (document.referrer.includes('/settings')) {
            // Starte den Export automatisch
            setTimeout(exportAllMessages, 1000);
        }
    }

    async function exportAllMessages() {
        // Abbruch-Controller für Fetch-Anfragen
        const controller = new AbortController();
        let continueLoading = true;

        // Popup erstellen
        const popup = document.createElement('div');
        popup.id = 'export-popup';
        popup.innerHTML = `
            <h2>Alle Nachrichten exportieren</h2>
            <div class="status">Kontakte werden geladen...</div>
            <div class="progress">
                <div class="progress-bar"></div>
            </div>
            <div class="log"></div>
            <div class="buttons">
                <button id="schliessen-button">Schließen</button>
                <button id="export-button" disabled>Als mbox exportieren</button>
            </div>
        `;
        document.body.appendChild(popup);

        document.getElementById('schliessen-button').addEventListener('click', () => {
            popup.remove();
            continueLoading = false;
            controller.abort();
        });

        const statusElement = popup.querySelector('.status');
        const progressBar = popup.querySelector('.progress-bar');
        const logElement = popup.querySelector('.log');
        const exportButton = document.getElementById('export-button');

        // Aktuellen Benutzernamen ermitteln
        const currentUser = document.querySelector('.navDropDown-avatar').alt.replace("'s Profilbild", "");

        // Alle Kontakte laden
        const contacts = await loadAllContacts(statusElement, progressBar, logElement, controller, continueLoading);

        if (!continueLoading || contacts.length === 0) {
            statusElement.textContent = 'Keine Kontakte gefunden oder Export abgebrochen.';
            return;
        }

        statusElement.textContent = `${contacts.length} Kontakte gefunden. Nachrichten werden geladen...`;

        // Alle Nachrichten laden
        const allMessages = [];
        let processedContacts = 0;

        for (const contact of contacts) {
            if (!continueLoading) break;

            statusElement.textContent = `Lade Nachrichten von ${contact.username} (${processedContacts + 1}/${contacts.length})...`;
            progressBar.style.width = `${(processedContacts / contacts.length) * 100}%`;

            logElement.textContent += `Lade Nachrichten von ${contact.username} (ID: ${contact.userId})...\n`;

            const messages = await loadMessagesForUser(contact.userId, contact.username, currentUser, logElement, controller, continueLoading);
            allMessages.push(...messages);

            processedContacts++;

            // Kurze Pause, um den Server nicht zu überlasten
            await new Promise(resolve => setTimeout(resolve, 500));
        }

        if (!continueLoading) {
            statusElement.textContent = 'Export wurde abgebrochen.';
            return;
        }

        // Export vorbereiten
        statusElement.textContent = `${allMessages.length} Nachrichten von ${contacts.length} Kontakten geladen. Bereit zum Export.`;
        progressBar.style.width = '100%';
        exportButton.disabled = false;

        // Export-Funktion
        exportButton.addEventListener('click', () => {
            // mbox-Format erstellen
            const mboxContent = allMessages.map(msg => {
                return `From ${msg.from} ${msg.date}
From: ${msg.from}
To: ${msg.to}
Date: ${msg.date}
Subject: ${msg.subject}

${msg.content}

`;
            }).join('\n');

            const blob = new Blob([mboxContent], { type: 'text/plain' });
            const url = URL.createObjectURL(blob);

            const a = document.createElement('a');
            a.href = url;
            a.download = `mydealz_alle_nachrichten_${new Date().toISOString().slice(0,10)}.mbox`;
            a.click();

            URL.revokeObjectURL(url);
        });
    }

    async function loadAllContacts(statusElement, progressBar, logElement, controller, continueLoading) {
        const contacts = [];
        let page = 1;
        let hasMore = true;

        while (hasMore && continueLoading) {
            try {
                statusElement.textContent = `Lade Kontakte Seite ${page}...`;

                const response = await fetch(`https://www.mydealz.de/conversation/recent/20/${page}`, {
                    headers: {
                        'Accept': 'application/json',
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    signal: controller.signal
                });

                const data = await response.json();

                if (data && data.data && data.data.content) {
                    const tempDiv = document.createElement('div');
                    tempDiv.innerHTML = data.data.content;

                    // Prüfen, ob "Weitere Nachrichten laden" Button vorhanden ist
                    const loadMoreButton = tempDiv.querySelector('.moreConversations button');
                    hasMore = loadMoreButton !== null;

                    // Kontakte aus der Antwort extrahieren
                    const items = tempDiv.querySelectorAll('li[id^="conversation-"]');
                    items.forEach(item => {
                        const usernameElement = item.querySelector('.conversationList-senderLine');
                        if (usernameElement) {
                            const username = usernameElement.textContent.trim();
                            const userId = item.getAttribute('data-replace')?.match(/\/user\/(\d+)\//)?.[1];

                            if (username && userId && !contacts.some(c => c.userId === userId)) {
                                contacts.push({ userId, username });
                                logElement.textContent += `Kontakt gefunden: ${username} (ID: ${userId})\n`;
                            }
                        }
                    });
                } else {
                    hasMore = false;
                }

                page++;

                // Kurze Pause, um den Server nicht zu überlasten
                await new Promise(resolve => setTimeout(resolve, 300));

            } catch (error) {
                if (error.name === 'AbortError') {
                    logElement.textContent += `Export abgebrochen.\n`;
                    return contacts;
                }
                console.error('Fehler beim Laden der Kontakte:', error);
                logElement.textContent += `FEHLER: ${error.message}\n`;
                hasMore = false;
            }
        }

        return contacts;
    }

    async function loadMessagesForUser(userId, username, currentUser, logElement, controller, continueLoading) {
        const messages = [];
        let page = 1;
        let hasMoreMessages = true;

        while (hasMoreMessages && continueLoading) {
            try {
                const url = `https://www.mydealz.de/conversation/user/${userId}/0/${page}`;
                logElement.textContent += `  Lade Seite ${page}: ${url}\n`;

                const response = await fetch(url, {
                    headers: {
                        'Accept': 'application/json',
                        'X-Requested-With': 'XMLHttpRequest'
                    },
                    signal: controller.signal
                });

                const data = await response.json();

                if (data && data.data && data.data.content) {
                    const tempDiv = document.createElement('div');
                    tempDiv.innerHTML = data.data.content;

                    // Nachrichten aus der Antwort extrahieren
                    const messageElements = tempDiv.querySelectorAll('.cept-message');

                    if (messageElements.length === 0) {
                        // Keine Nachrichten mehr, Ende erreicht
                        hasMoreMessages = false;
                    } else {
                        // Nachrichten verarbeiten
                        messageElements.forEach(messageElement => {
                            const senderElement = messageElement.querySelector('.button--type-text');
                            const dateElement = messageElement.querySelector('.mute--text');
                            const contentElement = messageElement.querySelector('.conversation-content');

                            if (senderElement && dateElement && contentElement) {
                                const sender = senderElement.textContent.trim();
                                const dateText = dateElement.textContent.trim();
                                const content = contentElement.textContent.trim().replace(/\s+/g, ' ');

                                // Datum in mbox-Format konvertieren
                                const dateParts = dateText.match(/(\d{2})\.(\d{2})\.(\d{4})\s+(\d{2}):(\d{2})/);
                                let mboxDate = '';
                                if (dateParts) {
                                    const [_, day, month, year, hours, minutes] = dateParts;
                                    const dateObj = new Date(year, month-1, day, hours, minutes);
                                    mboxDate = dateObj.toUTCString();
                                } else {
                                    mboxDate = new Date().toUTCString(); // Fallback
                                }

                                // Bestimmen, wer Sender und Empfänger ist
                                const from = sender === currentUser ?
                                    `${currentUser}@mydealz.de` :
                                    `${sender}@mydealz.de`;
                                const to = sender === currentUser ?
                                    `${username}@mydealz.de` :
                                    `${currentUser}@mydealz.de`;

                                // Betreff aus den ersten 40 Zeichen der Nachricht
                                const subject = content.substring(0, 40).replace(/\n/g, ' ');

                                messages.push({
                                    from,
                                    to,
                                    date: mboxDate,
                                    subject,
                                    content
                                });
                            }
                        });

                        // Wenn weniger als 10 Nachrichten zurückkommen, haben wir das Ende erreicht
                        if (messageElements.length < 10) {
                            hasMoreMessages = false;
                        }
                    }
                } else {
                    // Keine Daten mehr oder Fehler in der Antwort
                    hasMoreMessages = false;
                }

                page++;

                // Kurze Pause, um den Server nicht zu überlasten
                await new Promise(resolve => setTimeout(resolve, 300));

            } catch (error) {
                if (error.name === 'AbortError') {
                    logElement.textContent += `  Export abgebrochen.\n`;
                    return messages;
                }
                console.error('Fehler beim Laden der Nachrichten:', error);
                logElement.textContent += `  FEHLER: ${error.message}\n`;
                hasMoreMessages = false;
            }
        }

        logElement.textContent += `  ${messages.length} Nachrichten von ${username} geladen\n`;
        return messages;
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址