Есть ли способ просмотреть историю уведомлений браузера Chrome?

Вопрос или проблема

Я получаю уведомления от Chrome с нескольких веб-сайтов, и они работают даже когда у меня нет открытых вкладок для этих сайтов.

Но иногда я получаю эти уведомления от Chrome, когда я не сижу за своим столом или не смотрю на свой ноутбук.

Поскольку некоторые из этих уведомлений полезны для меня, я хотел бы иметь возможность получить доступ к тем, которые я пропустил.

Есть ли способ просмотреть историю уведомлений?

Если у вас Mac, это возможно! 😄

Вот как будет выглядеть список уведомлений:

Вот как будет выглядеть список уведомлений.

Вам нужно сделать следующее:

1. В Chrome перейдите по адресу:

chrome://flags/

2. Найдите:

Enable native notifications. Mac

3. Включите его, перезапустите Chrome, и все готово. Наслаждайтесь!

ИЗМЕНЕНИЕ:

  • Возможно, вам больше не нужно делать вышеуказанное.

Начиная с Chrome 59, уведомления, отправленные через API уведомлений или API расширений chrome.notifications, будут отображаться непосредственно системой уведомлений macOS, а не собственной системой Chrome. [источник]

На MacOSX у вас будет каталог Chrome в Library/Application Support.
Откройте терминал и выполните следующие команды:

cd ~/Library/Application\ Support/Google/Chrome/Default/Platform\ Notifications/
ls -la

На Gnu/Linux (по крайней мере на Linux Mint) вы можете найти файл(ы) журнала по адресу /home/user/.config/google-chrome/Profile 1/Platform Notifications/ – jdmayfield

Теперь вы увидите файлы, подобные этим:

drwx------@  7 visi  staff   224 Jul 13 18:16 .
drwx------  75 visi  staff  2400 Jul 15 11:05 ..
-rw-------@  1 visi  staff   759 Jul 15 10:57 000003.log
-rw-------@  1 visi  staff    16 Jul 13 18:16 CURRENT
-rw-------@  1 visi  staff     0 Jul 13 18:16 LOCK
-rw-------@  1 visi  staff   147 Jul 13 18:16 LOG
-rw-------@  1 visi  staff    41 Jul 13 18:16 MANIFEST-000001

Вы можете увидеть, что самый последний файл – 000003.log, так что проверьте его с помощью следующей команды:

tail -n 100 000003.log

И вы увидите последние 100 элементов из этого журнала.
Затем вы можете открыть настройки Chrome и отключить уведомление с сайта.

Обратите внимание, что если у вас несколько профилей в Chrome, ваш путь может быть другим, как этот (Profile1 вместо Default):

cd ~/Library/Application\ Support/Google/Chrome/Profile\ 1/Platform\ Notifications/

Если вы используете MS-Windows,
то перейдите по адресу %LocalAppData%\Google\Chrome\User Data\Default\Platform Notifications, там есть файл журнала прошлых уведомлений.

Краткое резюме

Для Ubuntu переходите к разделу Финальная "однострочная" внизу.

Детали

Это основано на @ответе Андрея Безпаленко, но протестировано на Ubuntu 18.04.

Как и в его ответе, вывод довольно ужасен, так как это двоичный вывод с читаемыми строками ASCII, перемешанными с двоичными данными. Вот шаги:

  1. Найдите последний файл журнала (*.log) в каталоге “Platform Notifications” для вашей установки Chrome:

    find ~/.config/google-chrome | grep --extended-regexp \
        "google-chrome.{0,30}Platform Notifications.*\.log$" | tail -n 1
    

    Пример вывода:

    $ find ~/.config/google-chrome | grep --extended-regexp "google-chrome.{0,30}Platform Notifications.*\.log$" | tail -n 1
    /home/gabriel/.config/google-chrome/Default/Platform Notifications/000003.log
    

    Мы можем видеть, что мы нашли файл журнала здесь: /home/gabriel/.config/google-chrome/Default/Platform Notifications/000003.log.

  2. Просмотрите последние, скажем, 10 строк или записей журнала из этого файла журнала:

    tail -n 10 "/home/gabriel/.config/google-chrome/Default/Platform Notifications/000003.log"
    

    Пример вывода трех последних элементов (tail -n 3 "/home/gabriel/.config/google-chrome/Default/Platform Notifications/000003.log"). Обратите внимание, как это ужасно читать и интерпретировать!

    $ tail -n 3 "/home/gabriel/.config/google-chrome/Default/Platform Notifications/000003.log"
    o"link"dhttps://www.reddit.com/r/AskReddit/comments/est2b4/what_would_be_the_worst_thing_to_put_in_a_pi�ата/"correlation_id"$1b7b2ef8-3ebb-4532-81ec-f896e58edaff"
                                                                                                                                                                           message_type"lifecycle_post_suggestions" device_id"@a5df86650804f98993acc43b31efa4ec0c733485b8cef4d8fe64a01ad07e9e09"auto_dismiss_optionsobehavior"timed"dismiss_time_msI��{{X`�������hrz* p#https://www.reddit.com/#01019308@H����P�-X�-`�-hp���-��<DATA:https_www.reddit.com_0p#https://www.reddit.com/#01019308RESOURCES:https_www.reddit.com_0p#https://www.reddit.com/#010193"???
    ... (урезанный вывод)...

Или просто выполните все вышеуказанное в одном шаге

tail -n 10 "$( find ~/.config/google-chrome | grep --extended-regexp "google-chrome.{0,30}Platform Notifications.*\.log$" | tail -n 1 )"

Или еще лучше, также выведите путь к файлу журнала:

Финальная “однострочная”

Последнее обновление 16 сентября 2024 года.

LOG_FILE="$( find ~/.config/google-chrome | grep --extended-regexp \
"google-chrome.{0,30}Platform Notifications.*\.log$" | tail -n 1 )"; \
echo -e "LOG_FILE=\"$LOG_FILE\"\n---------\n"; \
tail -n 10 "$LOG_FILE" | strings | sed 's/sessionIndexI/&\n/g'

Дальнейшая работа

Может ли кто-либо сделать этот вывод менее ужасным? Я хотел бы видеть предыдущие уведомления в более читаемом формате!

Обновление 25 мая 2020 года:

Вот еще один шаг к чему-то полезному: после выполнения “финальной однострочной” выше, сделайте это, чтобы извлечь только ASCII символы из двоичных данных и удалить лишние пробелы.

strings "$LOG_FILE" | sed -E 's/[ ]{8,}/\n/g'

Сначала strings извлекает строки ASCII из двоичного файла. Затем “редактор строк” sed глобально заменяет все вхождения 8 и более пробелов в строке на символ новой строки \n, так как я заметил, что иногда было десятки, если не сотни пробелов подряд, что значительно снижало читаемость. -E в sed нужен для расширенных регулярных выражений.

Обратите внимание, что команда однострочника выше уже сохранила путь к файлу в переменной LOG_FILE, поэтому мы просто собираемся повторно использовать эту переменную здесь. Посмотрите echo "$LOG_FILE", если вам нужно увидеть, что хранит эта переменная.

После выполнения вышеуказанного, вы получите что-то вроде этого:

$ strings temp.txt | sed -E 's/[ ]{8,}/\n/g'
o"link"dhttps://www.reddit.com/r/AskReddit/comments/est2b4/what_would_be_the_worst_thing_to_put_in_a_pi
ата/"correlation_id"$1b7b2ef8-3ebb-4532-81ec-f896e58edaff"

message_type"lifecycle_post_suggestions" device_id"@a5df86650804f98993acc43b31efa4ec0c733485b8cef4d8fe64a01ad07e9e09"auto_dismiss_optionsobehavior"timed"dismiss_time_msI
{{X`
hrz* p#https://www.reddit.com/#01019308@H
<DATA:https_www.reddit.com_0p#https://www.reddit.com/#010193ARESOURCES:https_www.reddit.com_0p#https://www.reddit.com/#010193
<DATA:https_www.reddit.com_0p#https://www.reddit.com/#010193ARESOURCES:https_www.reddit.com_0p#https://www.reddit.com/#010193

<DATA:https_www.reddit.com_0p#https://www.reddit.com/#010193ARESOURCES:https_www.reddit.com_0p#https://www.reddit.com/#010193
DATA:https_www.youtube.com_0p#https://www.youtube.com/#1SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAAAAA/kiuOchD_wtI/s96-mo/photo.jpg
https://www.youtube.com/"

SpaceX In-Flight Abort Test"Recommended: NASA Video*
SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAo"nav"B/watch?v=mu5Ydz34oVc&feature=push-fr&attr_tag=WQZST9cYBH8yY01w%3A6"id"COvK+bnsmucCEJQB"attributionTag"WQZST9cYBH8yY01w:6{X`
hrz*
p#https://www.youtube.com/#1SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAAAAA/kiuOchD_wtI/s96-mo/photo.jpg08@H
DATA:https_www.youtube.com_0p#https://www.youtube.com/#1SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAAAAA/kiuOchD_wtI/s96-mo/photo.jpg
https://www.youtube.com/"

SpaceX In-Flight Abort Test"Recommended: NASA Video*
SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAo"nav"B/watch?v=mu5Ydz34oVc&feature=push-fr&attr_tag=WQZST9cYBH8yY01w%3A6"id"COvK+bnsmucCEJQB"attributionTag"WQZST9cYBH8yY01w:6{X`
hrz*
p#https://www.youtube.com/#1SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAAAAA/kiuOchD_wtI/s96-mo/photo.jpg08@H
DATA:https_www.youtube.com_0p#https://www.youtube.com/#1SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAAAAA/kiuOchD_wtI/s96-mo/photo.jpg
RESOURCES:https_www.youtube.com_0p#https://www.youtube.com/#1SpaceX In-Flight Abort TestRecommended: NASA Videohttps://lh4.googleusercontent.com/-yGgyfF0s0tA/AAAAAAAAAAI/AAAAAAAAAAA/kiuOchD_wtI/s96-mo/photo.jpg

Ссылки

  1. sed:
    1. объясняет, как использовать группы regex () и \1 \2 \3 и т.д. для ссылки на эти группы! – Unix & Linux: Использование sed для поиска и замены сложных строк (предпочтительно с regex)
    2. Как использовать sed для поиска и замены текста в файлах в шелле Linux/Unix – https://www.cyberciti.biz/faq/how-to-use-sed-to-find-and-replace-text-in-files-in-linux-unix-shell/

Поскольку, похоже, невозможно получить запись уведомлений напрямую, если бы у меня была такая же проблема, я бы обманул, используя эмулятор Android или телефон, как пользователь, который рекомендовал Pushbullet. Но есть не только Pushbullet, есть много других приложений, мы могли бы обсудить трюки Android для прослушивания и записи уведомлений в отдельной теме.

Если вы программист, возможно, вы сможете решить свою проблему с помощью самодельного расширения:

https://stackoverflow.com/questions/15949606/how-can-i-listen-to-notifications

“Вы можете перехватить функцию webkitNotifications.createNotification, чтобы при создании уведомления вы выполняли какой-то определенный код.”

Касаясь того, что было упомянуто немного выше, но с поворотом, который обеспечивает, что вы не пропустите уведомление на OSX:

  1. С правой стороны основной верхней панели нажмите на
    иконку уведомлений.

  2. Нажмите на шестеренку (в нижнем правом углу дисплея уведомлений)

  3. Выберите Chrome, чтобы настроить, как отображаются уведомления.

  4. По умолчанию выбраны “Баннеры”, и они могут исчезать автоматически.
    Вместо этого выберите тип “Оповещение”, и они останутся там, пока вы не признаете их!

Пожалуйста! 🙂

Если вы используете MS-Windows 10. Вы можете увидеть историю Push-уведомлений. В самом нижнем правом углу вашего экрана на панели задач есть то, что выглядит как пузырь речи, и если вы наведете на него курсор, вы увидите, что это на самом деле называется “уведомления”. Если вы нажмете на этот пузырь, он покажет ваши непрочитанные/новые электронные письма и любые push-уведомления, которые вы не отклонили. Я пришел сюда в поисках этого ответа и не нашел его, но потом смог разобраться с этим. Я использую Windows 10.

Благодаря ответу Кори выше, и ленивой субботе с слишком большим количеством свободного времени, теперь я могу видеть список недавних уведомлений Chrome в консоли моего IDE, где я даже могу нажимать на URL-адреса.

Код ужасен и использует грубые эвристики, так как я не имею понятия о правильном способе интерпретации двоичных данных.

Но это намного лучше, чем ничего. Пример вывода (извлечение):

https://www.finanzen.net/nachricht/aktien/kw-9-tops-und-flops-der-tecdax-aktien-in-der-vergangenen-woche-7195100
https://images.finanzen.net/mediacenter/unsortiert/TecDAX_boerse_frankfurt0016_kl.jpg
Так изменялись отдельные акции TecDAX за прошлую торговую неделю.*
KW 9: Tops und Flops der TecDAX-Aktien в прошедшей неделе
Так изменялись отдельные акции TecDAX за прошлую торговую неделю.
HideOnTheseRoutes
Home/Index;Article/News/Index
tag-7195100
NotificationIdentifier
1061622960{


https://lh5.googleusercontent.com/-raJM5SITO34/AAAAAAAAAAI/AAAAAAAAAAA/UtLljlL4Wpc/s96-c-mo/photo.jpg
Новое от Market Moves
Trade Recap: $1,500 в ПРИБЫЛЕ*˜
COuAyJGY4uACEAY=
атрибуция
0SL8UpnrTOnTECxr:6{
 от Market MovesTrade Recap: $1,500 в ПРИБЫЛЕ

Java код, за который действительно стоит распять:

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * v[1, 2019-03-02 13:00 UTC]
 *
 * by dreamspace-president.com
 */
final public class CrappyChromeNotificationHistoryReader {

    public static void main(final String[] args) {

        final File file = new File(
                "C:\\Users\\[YOUR_NAME_HERE]\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Platform Notifications\\000003.log");

        final List<ChromeNotificationStuff> notifications = obtainChromeNotificationStuff(file);
        for (ChromeNotificationStuff notification : notifications) {
            System.err.println();
            System.err.println(notification);
        }
        System.exit(0);
    }

    public static List<ChromeNotificationStuff> obtainChromeNotificationStuff(final File file) {
        final List<ChromeNotificationStuff> ret = new ArrayList<>();
        final List<DumbTokenList> listOfDumbTokenLists = doTheInsaneParsingThing(file);
        int instanceCounter = 0;
        for (DumbTokenList dtl : listOfDumbTokenLists) {
            final List<String> urls = new ArrayList<>();
            final List<String> texts = new ArrayList<>();
            for (String token : dtl.tokens) {
                if (token.startsWith("https://") || token.startsWith("http://")) {
                    urls.add(token);
                } else {
                    texts.add(token);
                }
            }

            // Удалить неважные URL-адреса.
            for (int i = urls.size() - 1; i > 0; i--) {
                final String urlThis = urls.get(i);
                final int lenThis = urlThis.length();
                for (int ii = i - 1; ii >= 0; ii--) {
                    final String urlThat = urls.get(ii);
                    final int lenThat = urlThat.length();

                    if (lenThis > lenThat) {
                        if (urlThis.startsWith(urlThat)) {
                            final String removed = urls.remove(ii);
                            break;
                        }
                    } else {
                        if (urlThat.startsWith(urlThis)) {
                            final String removed = urls.remove(i);
                            break;
                        }
                    }
                }
            }

            ret.add(new ChromeNotificationStuff(instanceCounter, urls, texts));
            instanceCounter++;
        }

        ret.sort(null);
        return ret;
    }

    final public static class ChromeNotificationStuff implements Comparable<ChromeNotificationStuff> {
        private final int instanceCounter;
        final public List<String> urls;
        final public List<String> texts;

        private ChromeNotificationStuff(final int instanceCounter,
                                        final List<String> urls,
                                        final List<String> texts) {
            this.instanceCounter = instanceCounter;
            this.urls = Collections.unmodifiableList(urls);
            this.texts = Collections.unmodifiableList(texts);
        }

        public String toString() {
            final StringBuilder sb = new StringBuilder();
            for (String url : urls) {
                sb.append(url).append('\n');
            }
            for (String text : texts) {
                sb.append(text).append('\n');
            }
            return sb.toString();
        }

        @Override
        public int compareTo(final ChromeNotificationStuff o) { 
            return Integer.compare(o.instanceCounter, instanceCounter);
        }
    }

    final private static double MIN_LENGTH_DIFFERENCE_RATIO = 0.7;
    final private static double MIN_REMAININGLINES_PERCENTAGEOF_ALLLINES = 0.2;

    final private static class DumbTokenList {
        final private static int MIN_LENGTH = 10;
        final private static String[] EXTENSIONS = new String[] { ".jpg", ".jpeg", ".png", ".gif", ".html", ".htm", ".php" };
        final private static int MAX_EXTRA_CRAP_AFTER_EXTENSIONS = 3;
        final private static String SAFE_URL_CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;="; 

        final private String originalText;
        final private List<String> tokens;

        private DumbTokenList(final String textWithBinaryCrap) {
            originalText = textWithBinaryCrap;
            final List<String> tokens = new ArrayList<>();

            final Consumer<String> addTokenButTryToDecrappifyExtensionsFirstAnTing = token -> {
                if (token.startsWith("ttps://") || token.startsWith("ttp://")) {
                    token = "h" + token;
                }

                final List<String> newTokens = new ArrayList<>();

                if (token.startsWith("http")) {
                    final int tokenLength = token.length();
                    boolean found = false;
                    for (int i = 0; i < tokenLength; i++) {
                        final char c = token.charAt(i);
                        if (SAFE_URL_CHARACTERS.indexOf(c) < 0) {
                            newTokens.add(token.substring(0, i));
                            newTokens.add(token.substring(i));
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        newTokens.add(token);
                    }
                } else {
                    newTokens.add(token);
                }

                for (String newToken : newTokens) {
                    String foundExt = null;
                    int foundExtLen = 0;
                    int foundExtAt = -1;
                    for (String extension : EXTENSIONS) {
                        final int idx = newToken.indexOf(extension);
                        if (idx >= 0) {
                            final int extLen = extension.length();
                            if (idx > foundExtAt || (idx == foundExtAt && extLen > foundExtLen)) {
                                foundExt = extension;
                                foundExtLen = extLen;
                                foundExtAt = idx;
                            }
                        }
                    }
                    if (foundExt != null) {
                        final int amountOfCharactersAfterThisFind = newToken.length() - foundExtAt - foundExtLen;
                        if (amountOfCharactersAfterThisFind <= MAX_EXTRA_CRAP_AFTER_EXTENSIONS) {
                            newToken = newToken.substring(0, foundExtAt + foundExtLen);
                        }
                    }
                    if (newToken.startsWith("http")) {
                        if (!newToken.startsWith("http://") && !newToken.startsWith("https://")) {
                            continue;
                        }
                    }
                    if (newToken.startsWith("/watch?v=")) {
                        newToken = "https://www.youtube.com" + newToken;
                    }
                    if (newToken.length() >= MIN_LENGTH) {
                        tokens.add(newToken);
                    }
                }
            };

            final StringBuilder sb = new StringBuilder();
            final int len = textWithBinaryCrap.length();
            for (int i = 0; i <= len + 1; i++) {
                final char c = i < len ? textWithBinaryCrap.charAt(i) : 0;
                if (c < ' ' || c == '"') {
                    String potentialText = sb.toString();
                    while (true) {
                        final int httpIDX = potentialText.indexOf("http", 1);
                        if (httpIDX < 0) {
                            addTokenButTryToDecrappifyExtensionsFirstAnTing.accept(potentialText);
                            break;
                        } else {
                            final String snippet = potentialText.substring(0, httpIDX);
                            potentialText = potentialText.substring(httpIDX);
                            addTokenButTryToDecrappifyExtensionsFirstAnTing.accept(snippet);
                        }
                    }
                    sb.setLength(0);
                    if (c == '"') {
                        i++;
                    }
                } else {
                    sb.append(c);
                }
            }

            final int lSize = tokens.size();
            for (int i = lSize - 1; i > 0; i--) {
                if (i < tokens.size()) {
                    final String entry = tokens.get(i);
                    for (int ii = i - 1; ii >= 0; ii--) {
                        final String otherEntry = tokens.get(ii);
                        final Boolean removeNoneOrFirstOrSecond = areLinesTooSimilar(entry, otherEntry);
                        if (removeNoneOrFirstOrSecond != null) {
                            if (!removeNoneOrFirstOrSecond) {
                                final String removed = tokens.remove(i);
                                break;
                            } else {
                                final String removed = tokens.remove(ii);
                                break;
                            }
                            break; 
                        }
                    }
                }
            }

            this.tokens = Collections.unmodifiableList(tokens);
        }

        public String toString() {
            final StringBuilder sb = new StringBuilder();
            for (String token : tokens) {
                sb.append(token).append('\n');
            }
            return sb.toString();
        }
    }

    private static Boolean areLinesTooSimilar(final String line1,
                                              final String line2) {
        final int l1 = line1.length();
        final int l2 = line2.length();
        final double lenDiffRatio = Math.min(l1, l2) / (double) Math.max(l1, l2); 

        if (lenDiffRatio >= MIN_LENGTH_DIFFERENCE_RATIO) {
            if (l2 < l1) {
                if (line1.contains(line2)) {
                    return false;
                }
            } else {
                if (line2.contains(line1)) {
                    return true;
                }
            }
        }
        return null;
    }

    private static List<DumbTokenList> doTheInsaneParsingThing(final File file) {
        final List<DumbTokenList> ret = new ArrayList<>();
        final StringBuilder sb = new StringBuilder();
        try (final InputStream is = new BufferedInputStream(new FileInputStream(file))) {
            final int bufMinus1 = 4;
            final Charset charset = Charset.forName("Cp1252");

            final int[] buf = new int[bufMinus1 + 1]; 
            while (true) {
                buf[bufMinus1] = is.read();
                if (buf[bufMinus1] < 0 || (
                        buf[0] == 'D' &&
                                buf[1] == 'A' &&
                                buf[2] == 'T' &&
                                buf[3] == 'A' &&
                                buf[4] == ':')) {
                    if (sb.length() > 0) {
                        ret.add(new DumbTokenList(sb.toString()));
                        sb.setLength(0);
                    }
                    if (buf[bufMinus1] < 0) {
                        break;
                    }
                } else {
                    sb.append(new String(new byte[] { (byte) buf[bufMinus1] }, charset));
                }

                for (int i = 0; i < bufMinus1; i++) {
                    buf[i] = buf[i + 1];
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        for (int i = ret.size() - 1; i > 0; i--) {
            if (i < ret.size()) {
                final DumbTokenList dtlThis = ret.get(i);
                final int dtlThisTokenCount = dtlThis.tokens.size();
                for (int ii = i - 1; ii >= 0; ii--) {
                    final DumbTokenList dtlThat = ret.get(ii);
                    final int dtlThatTokenCount = dtlThat.tokens.size();
                    int scoreViaRemainingLines_this = dtlThisTokenCount;
                    int scoreViaRemainingLines_that = dtlThatTokenCount;
                    for (int o = 0; o < dtlThisTokenCount; o++) {
                        final String tokenThis = dtlThis.tokens.get(o);
                        for (int oo = 0; oo < dtlThatTokenCount; oo++) {
                            final String tokenThat = dtlThat.tokens.get(oo);
                            final Boolean tooSimilar = areLinesTooSimilar(tokenThis, tokenThat);
                            if (tooSimilar != null) {
                                scoreViaRemainingLines_this--;
                                scoreViaRemainingLines_that--;
                                break;
                            }
                        }
                    }

                    if (scoreViaRemainingLines_this < 0 || scoreViaRemainingLines_that < 0) {
                        throw new Error();
                    }

                    final double scoreActual_this = scoreViaRemainingLines_this / (double) dtlThisTokenCount;
                    final double scoreActual_that = scoreViaRemainingLines_that / (double) dtlThatTokenCount;

                    if (scoreViaRemainingLines_this < scoreViaRemainingLines_that) {
                        if (scoreActual_this < MIN_REMAININGLINES_PERCENTAGEOF_ALLLINES) {
                            final DumbTokenList removed = ret.remove(i);
                            break; 
                        }
                    } else {
                        if (scoreActual_that < MIN_REMAININGLINES_PERCENTAGEOF_ALLLINES) {
                            final DumbTokenList removed = ret.remove(ii);
                            break;
                        }
                    }
                }
            }
        }

        return ret;
    }
}

Существует расширение Chrome под названием NOTYFY, которое агрегирует уведомления с многих сайтов, на которые вы вошли (gmail, facebook, stackoverflow, twitter и т.д.).

NOTYFY по сути создает текущий журнал уведомлений с этих сайтов, чтобы вы могли получать к ним доступ в одном месте.

Таким образом, ответ да, вы можете получить доступ к истории уведомлений, но в очень ограниченном виде.

NOTYFY не агрегирует все уведомления сайта, только те, для которых он запрограммирован и в которые вы вошли. Даже эти требуют патчей, так как сайты меняют свои API уведомлений.

вставьте описание изображения здесь

Это хранится в базе данных LevelDB в папке Platform Notifications, как упомянули другие комментаторы.

Формат БД был задокументирован здесь –
https://www.giac.org/paper/gcih/20579/google-chrome-notification-analysis-in-depth/128522

Если вы используете LevelDBDumper или аналогичные инструменты, вы можете легко увидеть все данные:

LevelDBDumper.exe -d “C:\Users\User\AppData\Local\Google\Chrome\User Data\Default\Platform Notifications” -o “c:\temp” -t csv

Кроме того, воспользуйтесь SQLiteHunter + Velociraptor, как задокументировано ниже:
https://blog.nviso.eu/2024/09/06/hunting-chromium-notifications/
https://github.com/Velocidex/SQLiteHunter

Похоже, что Pushbullet может решить вашу проблему. Они утверждают, что вы можете видеть свои пропущенные уведомления, используя их расширение для Chrome.

https://blog.pushbullet.com/2014/10/23/easily-access-your-recent-notifications-in-chrome/

Ответ или решение

К сожалению, в браузере Google Chrome нет прямого и простого способа просматривать историю уведомлений, так как они не сохраняются в удобном для пользователя месте. Тем не менее, у пользователей есть несколько обходных путей, позволяющих получить доступ к недавним уведомлениям. Давайте рассмотрим эти способы более подробно.

Способы просмотра истории уведомлений Chrome

  1. Использование системных настроек уведомлений на macOS:

    • Если вы используете macOS, уведомления Chrome отображаются в системе. Вы можете зайти в Центр уведомлений, щелкнув по значку в верхнем правом углу экрана. Это даст вам доступ ко всем уведомлениям, которые вы могли пропустить.
  2. Поиск в Platform Notifications:

    • Все уведомления сохраняются в папке Platform Notifications. Путь к этой папке зависит от вашей операционной системы:
      • Для macOS: ~/Library/Application Support/Google/Chrome/Default/Platform Notifications/
      • Для Windows: %LocalAppData%\Google\Chrome\User Data\Default\Platform Notifications\
      • Для Linux: /home/[username]/.config/google-chrome/Default/Platform Notifications/
    • В этой папке вы найдете файлы, такие как 000003.log, которые содержат информацию о ваших уведомлениях.
  3. Чтение логов уведомлений:

    • Вы можете использовать командную строку или терминал, чтобы просмотреть последние 100 строк из этого файла:
      tail -n 100 000003.log
    • Это даст вам представление о последних уведомлениях, которые были отправлены, однако учтите, что данные могут отображаться в неструктурированном виде.
  4. Использование сторонних расширений:

    • Некоторые расширения, такие как NOTYFY, предназначены для агрегирования уведомлений различных сайтов. Хотя это расширение не сохраняет все уведомления Chrome, оно может помочь вам управлять уведомлениями, приходящими от популярных сервисов, таких как Gmail и Facebook.
    • Аналогичные расширения могут помочь увидеть недавние уведомления и упомянули в различных источниках.
  5. Создание собственного скрипта:

    • Если вы знакомы с программированием, вы можете рассмотреть возможность создания собственного расширения для отслеживания уведомлений. Существуют открытые схемы, которые позволяют перехватывать уведомления и сохранять их в формате, пригодном для последующего анализа.
  6. Использование Pushbullet:

    • Альтернативно, можно использовать такие сервисы, как Pushbullet, которые позволяют агрегировать уведомления и дают возможность просматривать историю пропущенных уведомлений с помощью их расширений для Chrome.

Итоги

Несмотря на ограничения самого Google Chrome в плане хранения истории уведомлений, существует несколько способов, позволяющих получить доступ к недавним уведомлениям. Независимо от того, используете ли вы системные функции или сторонние расширения, вы можете улучшить управление уведомлениями, чтобы не пропустить важные сообщения. С учетом вашего рабочего процесса и предпочтений, вы сможете выбрать наиболее подходящий вариант для себя.

Существует вероятность, что в будущем Google может интегрировать более удобные средства для управления уведомлениями, но на данный момент описанные методы остаются наиболее актуальными.

Оцените материал
Добавить комментарий

Капча загружается...