Panel Narzędziowy: Wyciągajka Tipply

Instrukcja instalacji rozszerzenia Tampermonkey oraz skrypt automatyzujący pobieranie wspierających

🔒 Informacja o bezpieczeństwie: Prezentowane rozwiązanie działa w 100% lokalnie w Twojej przeglądarce. Skrypt Tampermonkey uruchamia się wyłącznie na oficjalnej stronie Tipply, pobiera dane bezpośrednio z aktywnej sesji i nie wysyła ich na żadne zewnętrzne serwery.

1. Opis rozwiązania

Ponieważ Tipply nie udostępnia stałych kluczy API, a sesje w przeglądarce wygasają, optymalnym rozwiązaniem jest użycie skryptu użytkownika (UserScript). Skrypt ten dodaje dedykowany przycisk bezpośrednio w Twoim panelu Tipply, który automatycznie pobiera unikalne nicki darczyńców z ostatnich 30 dni.

2. Instrukcja instalacji krok po kroku

  1. Instalacja Tampermonkey: Zainstaluj oficjalne i bezpieczne rozszerzenie Tampermonkey w swojej przeglądarce internetowej (dostępne w Chrome Web Store, Firefox Add-ons itp.).
  2. Tworzenie nowego skryptu: Kliknij ikonę Tampermonkey na pasku rozszerzeń i wybierz opcję "Utwórz nowy skrypt..." (Create a new script...).
  3. Wklejenie kodu: Usuń całą domyślną zawartość edytora, skopiuj w całości poniższy kod skryptu i wklej go do edytora Tampermonkey.
  4. Zapisanie: W menu edytora Tampermonkey kliknij Plik -> Zapisz (lub użyj skrótu Ctrl+S).

3. Instrukcja użycia

  1. Zaloguj się na swoje konto na stronie https://app.tipply.pl lub przejdź na podstronę z listą wpłat.
  2. W prawym górnym rogu ekranu (obok Twojego profilu) pojawi się wyraźny, czerwony przycisk "Wyciągnij Nicki (30 dni)".
  3. Kliknij przycisk. Skrypt automatycznie pobierze listę ostatnich 300 wpłat, przefiltruje je według daty z ostatnich 30 dni, odrzuci duplikaty i posortuje alfabetycznie.
  4. Wynik wyświetli się w eleganckim oknie nakładki na środku ekranu. Możesz zaznaczyć tekst i skopiować go jednym kliknięciem.

4. Kod źródłowy skryptu (Tampermonkey)

Skopiuj poniższy kod i wklej go do rozszerzenia Tampermonkey:

tipply_wyciagajka.user.js
// ==UserScript==
// @name         Tipply - Wyciągajka Wspierających (30 dni)
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Dodaje przycisk do pobierania unikalnych nicków darczyńców z ostatnich 30 dni bezpośrednio z API Tipply
// @author       Streamer Tool
// @match        https://app.tipply.pl/*
// @grant        GM_xmlhttpRequest
// @connect      proxy.tipply.pl
// ==/UserScript==

(function() {
    'use strict';
    function init() {
        if (document.getElementById('btn-tipply-extractor')) return;
        const nav = document.querySelector('nav') || document.body;
        const btn = document.createElement('button');
        btn.id = 'btn-tipply-extractor';
        btn.innerHTML = '⚙️ Wyciągnij Nicki (30 dni)';
        btn.style.cssText = 'position: fixed; top: 15px; right: 80px; z-index: 99999; background-color: #cc0000; color: white; border: none; padding: 10px 15px; font-weight: bold; border-radius: 4px; cursor: pointer; box-shadow: 0 2px 5px rgba(0,0,0,0.2); font-family: Arial, sans-serif;';
        btn.addEventListener('mouseover', () => btn.style.backgroundColor = '#b30000');
        btn.addEventListener('mouseout', () => btn.style.backgroundColor = '#cc0000');
        btn.addEventListener('click', fetchData);
        document.body.appendChild(btn);
    }
    function fetchData() {
        const btn = document.getElementById('btn-tipply-extractor');
        btn.innerHTML = '⏳ Pobieranie...';
        btn.disabled = true;
        GM_xmlhttpRequest({
            method: "GET",
            url: "https://proxy.tipply.pl/user/tips?limit=300&offset=0",
            withCredentials: true,
            onload: function(response) {
                btn.innerHTML = '⚙️ Wyciągnij Nicki (30 dni)';
                btn.disabled = false;
                if (response.status === 200) {
                    try {
                        const tips = JSON.parse(response.responseText);
                        processTips(tips);
                    } catch(e) {
                        alert('Błąd parsowania danych JSON.');
                    }
                } else {
                    alert('Błąd pobierania danych! Upewnij się, że jesteś zalogowany. Kod błędu: ' + response.status);
                }
            },
            onerror: function() {
                btn.innerHTML = '⚙️ Wyciągnij Nicki (30 dni)';
                btn.disabled = false;
                alert('Wystąpił błąd sieciowy podczas komunikacji z API Tipply.');
            }
        });
    }
    function processTips(tips) {
        const unikalneNicki = new Set();
        const granicaCzasowa = new Date();
        granicaCzasowa.setDate(granicaCzasowa.getDate() - 30);
        tips.forEach(wplata => {
            const nick = wplata.nickname;
            const dataStr = wplata.created_at;
            if (nick && dataStr) {
                const dataWplaty = new Date(dataStr);
                if (dataWplaty > granicaCzasowa) {
                    unikalneNicki.add(nick.trim());
                }
            }
        });
        const posortowaneNicki = Array.from(unikalneNicki).sort((a, b) => 
            a.toLowerCase().localeCompare(b.toLowerCase(), 'pl')
        );
        showModal(posortowaneNicki);
    }
    function showModal(nicki) {
        const existing = document.getElementById('tipply-modal-overlay');
        if (existing) existing.remove();
        const overlay = document.createElement('div');
        overlay.id = 'tipply-modal-overlay';
        overlay.style.cssText = 'position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 100000; display: flex; align-items: center; justify-content: center; font-family: Arial, sans-serif;';
        const modal = document.createElement('div');
        modal.style.cssText = 'background: white; padding: 25px; border-radius: 8px; width: 500px; max-width: 90%; box-shadow: 0 4px 15px rgba(0,0,0,0.3); position: relative;';
        const title = document.createElement('h3');
        title.innerHTML = `--- UNIKALNE NICKI Z OSTATNICH 30 DNI (${nicki.length}) ---`;
        title.style.cssText = 'margin-top: 0; color: #333; border-bottom: 2px solid #eee; padding-bottom: 10px; font-size: 14px;';
        const textarea = document.createElement('textarea');
        textarea.value = nicki.join('\n');
        textarea.style.cssText = 'width: 100%; height: 250px; margin-top: 15px; font-family: monospace; padding: 10px; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; resize: none; background: #fafafa;';
        textarea.readOnly = true;
        const closeBtn = document.createElement('button');
        closeBtn.innerHTML = 'Zamknij';
        closeBtn.style.cssText = 'margin-top: 15px; background: #333; color: white; border: none; padding: 8px 16px; border-radius: 4px; cursor: pointer; float: right; font-weight: bold;';
        closeBtn.onclick = () => overlay.remove();
        modal.appendChild(title);
        modal.appendChild(textarea);
        modal.appendChild(closeBtn);
        overlay.appendChild(modal);
        document.body.appendChild(overlay);
    }
    init();
    const observer = new MutationObserver(init);
    observer.observe(document.body, { childList: true, subtree: true });
})();