Bitcoin Forum

Other => Meta => Topic started by: BitcoinLucky on September 23, 2015, 02:59:38 PM



Title: Free BitcoinTalk notification extension for Chrome & Opera
Post by: BitcoinLucky on September 23, 2015, 02:59:38 PM
Hello everyone!
 
Few weeks ago I decided to create an extension to make our life easier at Bitcointalk. This sends you a notification when you receive a PM, even when you're not on the site. You won't miss a single message anymore!

https://lh3.googleusercontent.com/wKZ2v_Znhp3ClduPU4_IufJzVSGrak9bNr7jJaCGP3b8TtcJl_aqogDGVKRydikt3wGZnc6hVtY=s640-h400-e365
 
If there are any bugs don't be scared and just post a comment or PM me. Also, if you want a new feature I would love to get in touch with you.
 
At the moment the extension is only available for Google Chrome and Opera in the Google Chrome Webstore. It is free to download:
https://chrome.google.com/webstore/detail/bitcointalk/cmjgajfcdgnahghegnegjiapoclkfcpp
 
IMPORTANT INSTRUCTIONS: You don't have to log in in the extension. The extension automatically checks the PM-page every 2 minutes so you have to be logged in to receive notifications.
 
Greetings


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: achow101 on September 23, 2015, 03:05:56 PM
Can you post the source code so that people can examine it?


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: OmegaStarScream on September 23, 2015, 03:12:56 PM
Can you post the source code so that people can examine it?

I'am not sure if this is the full code because I got other files but I guess this is the part that gets the PMs etc .. you could use an extention on google chrome that allow you to see source codes of extensions .

Code:
(function(window) {
    var BTC = {
        appversion: "1.0.1",
        pms: [],
        Init: function() {
            BTC.OPT.Check();
            BTC.bg.Init();
            chrome.notifications.onButtonClicked.addListener(BTC.handlers.notificationButtonClicked);
        },
        handlers: {
            notificationButtonClicked: function(notificationId, buttonIndex) {
                if (notificationId.substr(0, 5) == 'BTCPM' && !isNaN(parseInt(notificationId.substr(5)))) {
                    var pm = BTC.pms[parseInt(notificationId.substr(5))];
                    if (buttonIndex == 0) {
                        chrome.tabs.create({
                            url: 'https://bitcointalk.org/index.php?action=pm#msg' + pm.id
                        });
                    } else {
                        chrome.tabs.create({
                            url: 'https://bitcointalk.org/index.php?action=profile;u=' + pm.sender.id
                        });
                    }
                }
            }
        },
        OPT: {
            Get: function(c) {
                return localStorage.getItem(c)
            },
            Set: function(c, d) {
                return localStorage.setItem(c, d)
            },
            Remove: function(c) {
                return localStorage.removeItem(c)
            },
            Reset: function() {
                localStorage.clear();
                BTC.OPT.Check();
            },
            Check: function() {
                if (BTC.OPT.Get("APILastPM") == null) {
                    BTC.OPT.Set("APILastPM", 0)
                }
                if (BTC.OPT.Get("PMCheckDelay") == null || parseInt(BTC.OPT.Get("PMCheckDelay")) != BTC.OPT.Get("PMCheckDelay") || BTC.OPT.Get("PMCheckDelay") < 20 * 1000) {
                    BTC.OPT.Set("PMCheckDelay", 100000)
                }
            }
        },
        API: {
            getPMS: function(callback) {
                $.get('https://bitcointalk.org/index.php?action=pm')
                    .always(function(data) {
                        var pms = $($(data)[42])
                            .find('table > tbody > tr > td > form > table > tbody > tr[class^="windowbg"]');
                        if (pms.length > 0) {
                            var cleanpms = {};
                            pms.each(function() {
                                var pmdata = $(this)
                                    .find('td');
                                var status = pmdata.eq(0)
                                    .find('img')
                                    .attr('alt');
                                var pminfo = {
                                    subject: pmdata.eq(2)
                                        .find('a')
                                        .text(),
                                    id: parseInt(pmdata.eq(2)
                                        .find('a')
                                        .attr('href')
                                        .replace('#msg', '')),
                                    readed: (status == 'Read' || status == 'Replied To'),
                                    replied: (status == 'Replied To'),
                                    date: pmdata.eq(1)
                                        .text(),
                                    sender: {
                                        username: pmdata.eq(3)
                                            .find('a')
                                            .text(),
                                        id: parseInt(pmdata.eq(3)
                                            .find('a')
                                            .attr('href')
                                            .split(';u=')[1])
                                    }
                                };
                                cleanpms[pminfo.id] = pminfo;
                            });
                            callback(cleanpms);
                        } else {
                            callback(false);
                        }
                    });
            },
            getAvatar: function(user, callback) {
                $.get('https://bitcointalk.org/useravatars/avatar_' + user + '.png')
                    .always(function(plain, success, raw) {
                        callback((raw.status == 200) ? 'https://bitcointalk.org/useravatars/avatar_' + user + '.png' : '/assets/icon_128.png');
                    });
            }
        },
        bg: {
            timer: null,
            Init: function(c) {
                if (c != false) {
                    BTC.bg.tick();
                }
            },
            tick: function() {
                var delay = BTC.OPT.Get("PMCheckDelay") || 100000;
                BTC.bg.timer = setTimeout(function() {
                    BTC.bg.tick()
                }, delay);
                BTC.API.getPMS(BTC.bg.handlePMS);
            },
            handlePMS: function(pms) {
                BTC.pms = pms;
                if (Object.keys(pms)
                    .length > 0) {
                    // More than 1 PM
                    var highestPM = BTC.OPT.Get("APILastPM");
                    $.each(pms, function() {
                        var pm = this;
                        if (pm.id > BTC.OPT.Get("APILastPM")) {
                            highestPM = Math.max(highestPM, pm.id);
                            BTC.API.getAvatar(pm.sender.id, function(avatar) {
                                chrome.notifications.create('BTCPM' + pm.id, {
                                    type: 'basic',
                                    iconUrl: avatar,
                                    title: 'Private message from ' + pm.sender.username,
                                    message: pm.subject,
                                    buttons: [{
                                        title: 'View PM'
                                    }, {
                                        title: 'View sender profile'
                                    }],
                                    isClickable: false
                                });
                            });
                        }
                    });
                    BTC.OPT.Set("APILastPM", highestPM);
                }
            }
        }
    };
    window.BTC = BTC
})(window);
$(document)
    .ready(window.BTC.Init);


Code:
{
    "update_url": "https://clients2.google.com/service/update2/crx",
    "name": "BitcoinTalk",
    "description": "This application will give you a notification when you receive a private message on BitcoinTalk",
    "version": "1.0.1",
    "manifest_version": 2,
    "icons": {
        "32": "/assets/icon_32.png",
        "57": "/assets/icon_57.png",
        "64": "/assets/icon_64.png",
        "128": "/assets/icon_128.png",
        "256": "/assets/icon_256.png",
        "512": "/assets/icon_512.png"
    },
    "homepage_url": "https://bitcointalk.org/",
    "offline_enabled": false,
    "background": {
        "page": "/background.html"
    },
    "permissions": [
        "notifications",
        "tabs",
        "webRequest",
        "<all_urls>"
    ],
    "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}


@OP , could you please consider making an extension that checks and watch sections then notify us when a new thread it's made ? that would be awesome ! It's boring to click "Watchlist" each time and you don't know when there is one .


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: BitcoinLucky on September 23, 2015, 05:15:14 PM
Can you post the source code so that people can examine it?

Mitchell did it already as you can see on this thread: https://bitcointalk.org/index.php?topic=1169316.0 (https://bitcointalk.org/index.php?topic=1169316.0)


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: BitcoinLucky on September 23, 2015, 05:17:51 PM
Can you post the source code so that people can examine it?

I'am not sure if this is the full code because I got other files but I guess this is the part that gets the PMs etc .. you could use an extention on google chrome that allow you to see source codes of extensions .

Code:
(function(window) {
    var BTC = {
        appversion: "1.0.1",
        pms: [],
        Init: function() {
            BTC.OPT.Check();
            BTC.bg.Init();
            chrome.notifications.onButtonClicked.addListener(BTC.handlers.notificationButtonClicked);
        },
        handlers: {
            notificationButtonClicked: function(notificationId, buttonIndex) {
                if (notificationId.substr(0, 5) == 'BTCPM' && !isNaN(parseInt(notificationId.substr(5)))) {
                    var pm = BTC.pms[parseInt(notificationId.substr(5))];
                    if (buttonIndex == 0) {
                        chrome.tabs.create({
                            url: 'https://bitcointalk.org/index.php?action=pm#msg' + pm.id
                        });
                    } else {
                        chrome.tabs.create({
                            url: 'https://bitcointalk.org/index.php?action=profile;u=' + pm.sender.id
                        });
                    }
                }
            }
        },
        OPT: {
            Get: function(c) {
                return localStorage.getItem(c)
            },
            Set: function(c, d) {
                return localStorage.setItem(c, d)
            },
            Remove: function(c) {
                return localStorage.removeItem(c)
            },
            Reset: function() {
                localStorage.clear();
                BTC.OPT.Check();
            },
            Check: function() {
                if (BTC.OPT.Get("APILastPM") == null) {
                    BTC.OPT.Set("APILastPM", 0)
                }
                if (BTC.OPT.Get("PMCheckDelay") == null || parseInt(BTC.OPT.Get("PMCheckDelay")) != BTC.OPT.Get("PMCheckDelay") || BTC.OPT.Get("PMCheckDelay") < 20 * 1000) {
                    BTC.OPT.Set("PMCheckDelay", 100000)
                }
            }
        },
        API: {
            getPMS: function(callback) {
                $.get('https://bitcointalk.org/index.php?action=pm')
                    .always(function(data) {
                        var pms = $($(data)[42])
                            .find('table > tbody > tr > td > form > table > tbody > tr[class^="windowbg"]');
                        if (pms.length > 0) {
                            var cleanpms = {};
                            pms.each(function() {
                                var pmdata = $(this)
                                    .find('td');
                                var status = pmdata.eq(0)
                                    .find('img')
                                    .attr('alt');
                                var pminfo = {
                                    subject: pmdata.eq(2)
                                        .find('a')
                                        .text(),
                                    id: parseInt(pmdata.eq(2)
                                        .find('a')
                                        .attr('href')
                                        .replace('#msg', '')),
                                    readed: (status == 'Read' || status == 'Replied To'),
                                    replied: (status == 'Replied To'),
                                    date: pmdata.eq(1)
                                        .text(),
                                    sender: {
                                        username: pmdata.eq(3)
                                            .find('a')
                                            .text(),
                                        id: parseInt(pmdata.eq(3)
                                            .find('a')
                                            .attr('href')
                                            .split(';u=')[1])
                                    }
                                };
                                cleanpms[pminfo.id] = pminfo;
                            });
                            callback(cleanpms);
                        } else {
                            callback(false);
                        }
                    });
            },
            getAvatar: function(user, callback) {
                $.get('https://bitcointalk.org/useravatars/avatar_' + user + '.png')
                    .always(function(plain, success, raw) {
                        callback((raw.status == 200) ? 'https://bitcointalk.org/useravatars/avatar_' + user + '.png' : '/assets/icon_128.png');
                    });
            }
        },
        bg: {
            timer: null,
            Init: function(c) {
                if (c != false) {
                    BTC.bg.tick();
                }
            },
            tick: function() {
                var delay = BTC.OPT.Get("PMCheckDelay") || 100000;
                BTC.bg.timer = setTimeout(function() {
                    BTC.bg.tick()
                }, delay);
                BTC.API.getPMS(BTC.bg.handlePMS);
            },
            handlePMS: function(pms) {
                BTC.pms = pms;
                if (Object.keys(pms)
                    .length > 0) {
                    // More than 1 PM
                    var highestPM = BTC.OPT.Get("APILastPM");
                    $.each(pms, function() {
                        var pm = this;
                        if (pm.id > BTC.OPT.Get("APILastPM")) {
                            highestPM = Math.max(highestPM, pm.id);
                            BTC.API.getAvatar(pm.sender.id, function(avatar) {
                                chrome.notifications.create('BTCPM' + pm.id, {
                                    type: 'basic',
                                    iconUrl: avatar,
                                    title: 'Private message from ' + pm.sender.username,
                                    message: pm.subject,
                                    buttons: [{
                                        title: 'View PM'
                                    }, {
                                        title: 'View sender profile'
                                    }],
                                    isClickable: false
                                });
                            });
                        }
                    });
                    BTC.OPT.Set("APILastPM", highestPM);
                }
            }
        }
    };
    window.BTC = BTC
})(window);
$(document)
    .ready(window.BTC.Init);


Code:
{
    "update_url": "https://clients2.google.com/service/update2/crx",
    "name": "BitcoinTalk",
    "description": "This application will give you a notification when you receive a private message on BitcoinTalk",
    "version": "1.0.1",
    "manifest_version": 2,
    "icons": {
        "32": "/assets/icon_32.png",
        "57": "/assets/icon_57.png",
        "64": "/assets/icon_64.png",
        "128": "/assets/icon_128.png",
        "256": "/assets/icon_256.png",
        "512": "/assets/icon_512.png"
    },
    "homepage_url": "https://bitcointalk.org/",
    "offline_enabled": false,
    "background": {
        "page": "/background.html"
    },
    "permissions": [
        "notifications",
        "tabs",
        "webRequest",
        "<all_urls>"
    ],
    "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}


@OP , could you please consider making an extension that checks and watch sections then notify us when a new thread it's made ? that would be awesome ! It's boring to click "Watchlist" each time and you don't know when there is one .

I can't alert ppl when there is a thread. I should check all the sections then every minute, and I don't think the BT staff would like that. This would also take up a lot of bandwidth. If they would make a feature/API theirself it would be possible.


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: shorena on September 23, 2015, 05:38:11 PM
-snip-
I can't alert ppl when there is a thread. I should check all the sections then every minute, and I don't think the BT staff would like that. This would also take up a lot of bandwidth. If they would make a feature/API theirself it would be possible.

Could you request the watchlist page and modify the link from Watchlist to Watchlist[#unread threads]?

That way you only request a single page every e.g. 10-30 seconds (should be enough) and the user only gets a message for a board they actually watch and not for boards they dont care about.


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: achow101 on September 23, 2015, 05:39:37 PM
Can you post the source code so that people can examine it?

Mitchell did it already as you can see on this thread: https://bitcointalk.org/index.php?topic=1169316.0 (https://bitcointalk.org/index.php?topic=1169316.0)
Thanks.

I can't alert ppl when there is a thread. I should check all the sections then every minute, and I don't think the BT staff would like that. This would also take up a lot of bandwidth. If they would make a feature/API theirself it would be possible.
You could have it check the recents page here https://bitcointalk.org/index.php?action=recent and notify when a post is made that doesn't have "Re:" in the title.

Can you also have it check the watchlist and notify us when a new reply was posted to a topic we are watching?


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: Sir_lagsalot on September 24, 2015, 10:10:40 AM
Is there a way to check whether this extension is safe? Beside that, this is the extension I've been waiting for.


Title: Re: Free BitcoinTalk notification extension for Chrome & Opera
Post by: Mitchell on September 24, 2015, 10:12:46 AM
Is there a way to check whether this extension is safe? Beside that, this is the extension I've been waiting for.
I know you like to post crap to get more BTC, but at least try to read the thread. I've already examined the code and marked it as safe.

Can you post the source code so that people can examine it?

Mitchell did it already as you can see on this thread: https://bitcointalk.org/index.php?topic=1169316.0 (https://bitcointalk.org/index.php?topic=1169316.0)
Link to the post itself: click (https://bitcointalk.org/index.php?topic=1169316.msg12312180#msg12312180)