Gmail Sender Icons

Quickly identify the sender of email messages in Gmail without opening the message. Now marks emails in red if the domain is not allowed.

Устаревшая версия за 04.09.2024. Перейдите к последней версии.

// ==UserScript==
// @name           Gmail Sender Icons
// @name:es        Gmail Iconos de Remitente
// @namespace      http://tampermonkey.net/
// @version        1.3
// @description    Quickly identify the sender of email messages in Gmail without opening the message. Now marks emails in red if the domain is not allowed.
// @description:es Identifica rápidamente al remitente de los mensajes de correo en Gmail sin abrir el mensaje. Ahora marca los correos en rojo si el dominio no está permitido.
// @author         IgnaV
// @match          https://mail.google.com/*
// @icon           https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico
// @license        MIT
// @grant          GM_setValue
// @grant          GM_getValue
// ==/UserScript==

(function() {
    'use strict';

    if (window.self !== window.top) return;

    const userId = window.location.href.match(/\/u\/(\d+)\//)[1];

    const addIcon = GM_getValue('addIcon', true);
    const addDomain = GM_getValue('addDomain', true);
    const allowedCommonDomains = GM_getValue('allowedDomains', []);
    const allowedUserDomains = GM_getValue('allowedUserDomains', {});

    const userDomains = allowedUserDomains[userId] || [];
    allowedUserDomains[userId] = userDomains;

    GM_setValue('addIcon', addIcon);
    GM_setValue('addDomain', addDomain);
    GM_setValue('allowedUserDomains', allowedUserDomains);


    const allowedDomains = allowedCommonDomains.concat(userDomains);
    const hasDomains = allowedDomains.length !== 0;


    if (!addIcon && !addDomain && !hasDomains) return;

    const processedElements = new Set();

    function addDomainContainer(element, domain) {
        const domainContainer = document.createElement('div');
        domainContainer.className = 'domain-container';

        addIconToContainer(domainContainer, domain);
        addDomainToContainer(domainContainer, domain);
        element.appendChild(domainContainer);
        return domainContainer;
    }

    function addIconToContainer(domainContainer, domain) {
        const icon = document.createElement('img');
        icon.src = `https://www.google.com/s2/favicons?domain=${domain}`;
        icon.className = 'domain-icon';
        domainContainer.appendChild(icon);
    }

    function addDomainToContainer(domainContainer, domain) {
        const domainSpan = document.createElement('span');
        domainSpan.className = 'domain-text';
        domainSpan.textContent = domain;
        domainContainer.appendChild(domainSpan);
    }

    function markUnknownDomain(domainElement, domain) {
        if (!allowedDomains.includes(domain)) {
            domainElement.classList.add('not-allowed-domain');
        }
    }

    function markUnknownEmail(emailElement, email) {
        const domain = email.split('@')[1].split('.').slice(-2).join('.');
        if (!allowedDomains.includes(domain)) {
            emailElement.classList.add('not-allowed-domain');
        }
    }

    if (!addIcon && !addDomain) {
        addDomainContainer = function() {};
    }

    if (!addIcon) {
        addIconToContainer = function() {};
    }

    if (!addDomain) {
        addDomainToContainer = function() {};
    }

    if (!hasDomains) {
        markUnknownDomain = function() {};
        markUnknownEmail = function() {};
    }

    function addStyles(addIcon, addDomain, hasDomains) {
        const style = document.createElement('style');
        style.type = 'text/css';
        let css = ``;
        if (addIcon || addDomain) {
            css += `
                .bA4 {
                    padding-top: 9px;
                }
                .domain-container {
                    display: flex;
                    align-items: center;
                    margin-top: -4px;
                    font-size: 10px;
                    color: #888;
                    width: fit-content;
                    height: 11px;
                    padding: 1px 2px;
                }
            `;
        }
        if (addIcon) {
            css += `
                .domain-icon {
                    width: 10px;
                    height: 10px;
                    margin-right: 3px;
                }
            `;
        }
        if (addDomain) {
            css += `
                .domain-text {
                    white-space: nowrap;
                    overflow: hidden;
                    text-overflow: ellipsis;
                    font-size: 10px;
                    color: #888;
                }
            `;
        }
        if (hasDomains) {
            css += `
                .not-allowed-domain {
                    background-color: #f8d7da;
                    color: #721c24;
                    border-radius: 3px;
                }
            `;
        }
        style.appendChild(document.createTextNode(css));
        document.head.appendChild(style);
    }

    function addDomainBelowName() {
        const nameElements = document.querySelectorAll('.bA4');

        nameElements.forEach((element) => {
            if (processedElements.has(element)) return;

            const emailElement = element.querySelector('[email]');
            if (!emailElement) return;

            const email = emailElement.getAttribute('email');
            const domain = email.split('@')[1].split('.').slice(-2).join('.');

            const domainElement = addDomainContainer(element, domain);

            markUnknownDomain(domainElement, domain);

            processedElements.add(element);
        });
    }

    function markEmailInOpenedMessage() {
        const containerElement = document.querySelector('h3:has(> span > .gD[email])');
        const emailElement = containerElement ? containerElement.querySelector('.gD[email]') : null;

        if (emailElement) {
            const email = emailElement.getAttribute('email');
            markUnknownEmail(containerElement, email);
        }
    }

    addStyles(addIcon, addDomain, hasDomains);

    const observer = new MutationObserver((mutations) => {
        mutations.forEach(() => {
            addDomainBelowName();
            markEmailInOpenedMessage();
        });
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });

    window.addEventListener('load', () => {
        addDomainBelowName();
        markEmailInOpenedMessage();
    });
})();