Chromeブラウザの通知履歴を表示する方法はありますか?


56

複数のウェブサイトからChrome通知を受け取りますが、それらのサイトのタブを開いていない場合でも動作します。

しかし、デスクにいないときやノートパソコンを見ているときに、Chrome通知を受け取ることがあります。

これらの通知の一部は私にとって有用なので、見逃したものにアクセスできるようにしたいと思います。

通知履歴を表示する方法はありますか?


1
それのように見えません。この投稿(theverge.com/2015/10/14/9531133/…)を見て、彼らは通知ポリシーを再配置し、デスクトップから削除して個々のWebページに配置しました。新しい通知にアクセスする唯一の方法は、Googleページのベルをクリックすることです。
テリー

1
nope:productforums.google.com/forum / #!msg / chrome / xs9PflHTfho / …のようです -非常に残念です。
LB

リストとして通知を見つけた唯一の場所は、通知を送信するWebサイトにWebサイト経由で通知がある場合です。Chromeはそれらを収集するようchrome://notificationsには見えず、OSに到達しません。
ジェイソンライドン

有効な回答を受け入れます@paradroid
Satheesh

回答:


31

Macをお持ちの場合、方法があります!😄

通知リストは次のようになります。

通知リストは次のようになります。

あなたがしなければならないのは、次のとおり

です。

chrome://flags/

2.以下を探します:

Enable native notifications. Mac

3.有効にして、Chromeを再起動すると完了です。楽しい!

編集:

  • 上記を行う必要はもうありません。

Chrome 59以降、Notifications APIまたはchrome.notifications拡張APIを介して送信された通知は、Chrome独自のシステムではなくmacOSネイティブ通知システムによって直接表示されます。[ ソース ]


2
これは、通知履歴を表示するという質問には答えず、通知を表示するだけです。
ビヨン

6
@BjornTiplingそれは答えます。彼は外出中に見逃した通知を見ることができるかどうかを尋ねていますが、私の方法はまさにそれを行います。
エスドラスロペス

1
リンクをコメントとして追加する場合は、@ EsdrasLopez
user418150

1
@ user418150それはありがたいことですが、今では評判を得ました。:)編集内容を確認してください。
エスドラスロペス

2
ここでの主な問題は、クリックしないと通知が保存されないことです。数回、興味深い記事のタイトルをクリックしましたが、ロードに失敗するだけでしたが、それでも通知リストから削除されました。通常、記事はあまりにも新しいのでGoogle化できず、通知のタイトルが記事のタイトルと一致しないことが多いため、Webの腸で失われます。
iBorg

12

MacOSXでは、ライブラリ/アプリケーションサポートにChromeディレクトリがあります。ターミナルアプリケーションを開き、次のコマンドを実行します。

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

次のようなファイルが表示されます。

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項目が表示されます。その後、クロム設定を開き、そのWebサイト通知を無効にすることができます。

クロムに複数のプロファイルがある場合、次のようにパスが異なる可能性があることに注意してください(デフォルトではなくProfile1):

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

3
これは受け入れられた答えでなければなりません。:)
コーディA.レイ

1
2019年も引き続き機能しています(ただし、ログには少し解釈が必要です)。グレート答えのおかげで
carpii

12

に移動すると%LocalAppData%\Google\Chrome\User Data\Default\Platform Notifications、過去の通知のログファイルがあります。


4
ただし、ハードコードではなく「%LocalAppData%\ Google \ Chrome \ User Data \ Default \ Platform Notifications」としてパスを指定することを検討してください。どのPCでも完全に動作します。
ドミトリーグサロフ

UserData / -folderで、「C:\ Users \ username \ AppData \ Local \ Google \ Chrome \ UserData \ Profile 1 \ Platform Notifications」などのプロファイルフォルダーを最初に見つける必要がある場合があります
-Maffelu

1
このデータはバイナリです。読み方は?
ガイア

Chrome 71では、ログファイルは空です。これはある時点で無効になりましたか?
ジェームズ

3
@Gaia同じことを疑問に思い、そのほとんどを解読するのに受け入れられる仕事をするくだらないJavaコードをホイップしました。以下に投稿しました:superuser.com/a/1410742/778383
Dreamspace President

3

通知の記録を直接取得することは不可能と思われるため、同じ問題が発生した場合は、Pushbulletを推奨したユーザーとして、Android Phoneエミュレーターまたは電話を使用してごまかします。しかし、Pushbulletだけでなく、他にもたくさんのアプリがあります。別のスレッドで、通知を聞いて記録するためのAndroidのトリックについて話し合うことができます。

あなたがプログラマーなら、おそらく自家製の拡張機能で問題を解決できます:

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

「webkitNotifications.createNotification関数をフックして、通知が作成されるたびに特定のコードを実行できるようにすることができます。」


2

上記で少し触れたが、OSXの通知を見逃さないようにひねりを加えたものに触れます。

  1. メイントップバーの右側にある通知アイコンをクリックします。

  2. 歯車をクリックします(通知画面の右下)

  3. Chromeを選択して、通知の表示方法を設定します。

  4. デフォルトでは「バナー」が選択されており、自動的に消えます。代わりに、「アラート」タイプを選択すると、それらを確認しない限りそこにとどまります!

どういたしまして :)


2

プッシュ通知の履歴を確認できます。タスクバーのPC画面の右下隅には、吹き出しのように見えるものがあり、その上にカーソルを合わせると、実際には「通知」と呼ばれます。そのバブルをクリックすると、未読/新着メールと、削除していないプッシュ通知が表示されます。私はこの答えを求めてここに来て、それを見つけられませんでしたが、それをうまく処理することができました。Windows 10を使用しています。


はい、これはWin10の最近のものですが、Windowsの最終的な答えです。
パラドロイド

-1

Pushbulletが問題を解決する可能性があるようです。Chromeの拡張機能を使用して、見逃した通知を見ることができると主張しています。

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


お読みくださいソフトウェアをお勧めする方法のために最低限必要な情報や、スーパーユーザーにソフトウェアをお勧めする方法についての提案。提供されたリンクが壊れていても有用な回答を維持するには、これらの詳細を回答に編集する必要があります。
私は言う

ねえ、いい。やってみます。私は実際にPushbulletをすでに使用していますが、このChrome拡張機能を認識していませんでした。
パラドロイド

この機能が見つからないようです。通知がポップされ、通知の履歴にそのトレースがありません。
madprops

私は質問を再考しました、そして、キャッチはこれです。電話機が通知を受け取ると、プッシュブレットはそれをデスクトップに配信し、未読の通知を持っている可能性があることを通知します(電話機で通知を見たか、何を持っているか)。クロム通知を受け取るサイトは何ですか?アプリがあれば、いつでもインストールでき、プッシュブレットからデスクトップ/ラップトップ/何でも通知を受け取ることができます。
Socialorganix Contentbrandmgmt 16

1
Pushbulletの「通知」機能は、デスクトップでAndroidスマートフォンからの通知を表示するためだけであり、Macデスクトップを持っている場合はiPhoneでも同じです。Chrome通知とは関係ありません。
ボアズ

-1

上記のCorey回答と、あまりにも多くの時間を費やしている怠Saturdayな土曜日のおかげで、IDEのコンソールで最近のChrome通知のリストを確認できるようになりました。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
So bewegten sich die Einzelwerte des TecDAX in der zurückliegenden Handelswoche.*
KW 9: Tops und Flops der TecDAX-Aktien in der vergangenen Woche
So bewegten sich die Einzelwerte des TecDAX in der zurückliegenden Handelswoche.
HideOnTheseRoutes
Home/Index;Article/News/Index
tag-7195100
NotificationIdentifier
1061622960{


https://www.youtube.com/watch?v=W-mlD_bYKdU&feature=push-u-sub&attr_tag=0SL8UpnrTOnTECxr%3A6
https://lh5.googleusercontent.com/-raJM5SITO34/AAAAAAAAAAI/AAAAAAAAAAA/UtLljlL4Wpc/s96-c-mo/photo.jpg
New from Market Moves
Trade Recap: $1,500 in PROFITS*˜
COuAyJGY4uACEAY=
attributionTag
0SL8UpnrTOnTECxr:6{
 from Market MovesTrade Recap: $1,500 in PROFITS

はりつけに値する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);
                }
            }


            // Remove unimportant URLs.
            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);
                            //                            System.err.println("\nREMOVED: " + removed + "\nKEPT   : " + urlThis); // because was better or equal
                            break;
                        }
                    } else {
                        if (urlThat.startsWith(urlThis)) {
                            final String removed = urls.remove(i);
                            //                            System.err.println("\nREMOVED: " + removed + "\nKEPT   : " + urlThat); // because was better or equal
                            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) { // Newest (= last) notifications first, please.

            return Integer.compare(o.instanceCounter, instanceCounter);
        }
    }




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




    final private static class DumbTokenList {


        final private static int MIN_LENGTH = 10; //6;
        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-._~:/?#[]@!$&'()*+,;="; // https://stackoverflow.com/a/1547940/3500521

        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) {
                            // OK. Shorten this bitch.
                            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 == '"') {
                        // Skip this and the next. (thus "i < len +1")
                        i++;
                    }
                } else {
                    sb.append(c);
                }
            }


            // Remove quasi-duplicates. Sue me.
            //            System.err.println("\n*** STARTING DEDUPLICATION ***");
            final int lSize = tokens.size();
            for (int i = lSize - 1; i > 0; i--) { // (not 0 itself, wouldn't make sense)

                if (i < tokens.size()) {

                    final String entry = tokens.get(i);

                    for (int ii = i - 1; ii >= 0; ii--) { // (incl. 0)

                        final String otherEntry = tokens.get(ii);

                        final Boolean removeNoneOrFirstOrSecond = areLinesTooSimilar(entry, otherEntry);
                        if (removeNoneOrFirstOrSecond != null) {

                            if (!removeNoneOrFirstOrSecond) {
                                final String removed = tokens.remove(i);
                                //                                System.err.println("\nREMOVED: " + removed + "\nKEPT   : " + otherEntry); // because was better or equal
                            } else {
                                final String removed = tokens.remove(ii);
                                //                                System.err.println("\nREMOVED: " + removed + "\nKEPT   : " + entry); // because was better or equal
                            }
                            break; // IMPORTANT!
                        }

                    }
                }
            }


            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();
        }


    }


    /**
     * Do NOT call with NULL/EMPTY arguments.
     *
     * @return NULL if not too similar. False if the FIRST seems superfluous. True if the SECOND seems superfluous.
     */
    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); // Results in 1 or less.

        if (lenDiffRatio >= MIN_LENGTH_DIFFERENCE_RATIO) {

            if (l2 < l1) {
                // Compare the other way round.
                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"); // =ansi

            final int[] buf = new int[bufMinus1 + 1]; // "DATA"
            //            while ((buf[buf.length - 1] = is.read()) >= 0) {
            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));
                    //                    sb.append((char) buf[bufMinus1]);
                }


                // Shift minibuffer to front.
                for (int i = 0; i < bufMinus1; i++) {
                    buf[i] = buf[i + 1];
                }
            }


        } catch (IOException e) {
            e.printStackTrace();
        }


        // DEDUPLICATE DTLs
        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);
                            //                            System.err.println("\nREMOVED:\n" + removed + "\nKEPT   :\n" + dtlThat);
                            break; // IMPORTANT.
                        }
                    } else {
                        if (scoreActual_that < MIN_REMAININGLINES_PERCENTAGEOF_ALLLINES) {
                            final DumbTokenList removed = ret.remove(ii);
                            //                            System.err.println("\nREMOVED:\n" + removed + "\nKEPT   :\n" + dtlThis);
                            break; // IMPORTANT.
                        }
                    }


                }

            }
        }

        return ret;
    }


}

1
これを実行するには、次のコマンドを使用しましたjavac "C:\Users\MLM\Downloads\CrappyChromeNotificationHistoryReader.java"(コンパイルする)、 java -cp C:\Users\MLM\Downloads CrappyChromeNotificationHistoryReader(実行する)スクリプトが失敗したif (scoreViaRemainingLines_this < 0 || scoreViaRemainingLines_that < 0) {ため、すべての解析をコメントアウトし、トークンがリストに追加されたときにdoTheInsaneParsingThingすべてを印刷しましSystem.out.println(sb.toString());た。「プラットフォーム通知」はサーバーワーカーのプッシュ通知のみを処理するようです。
MLM

@MLM:javac情報をありがとう。問題に関しては、ソースを開いているJava 8 IntelliJプロジェクトに貼り付け、ユーザー名(「ファイル」変数)を入力して、コードを実行すればうまくいきます。
ドリームスペースプレジデント
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.