Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Browser userscripts to delete all Google Voice history
// ==UserScript==
// @name Delete Google Voice (Legacy) History
// @description Deletes all Google Voice (Legacy) history
// @version 1.1.0
// @license MIT
// @namespace gavinhungry.io
// @author Gavin Lloyd <gavinhungry@gmail.com>
//
// @include https://www.google.tld/voice
// @include https://www.google.tld/voice/*
// @include https://www.google.tld/voice#*
// @include https://www.google.tld/voice?*
//
// @require https://cdn.jsdelivr.net/jquery/2/jquery.min.js
// @grant none
// ==/UserScript==
(function($) {
'use strict';
var voice = (function() {
var GV_KEY = '_rnr_se';
/**
* Remove a message id
*
* @param {String} url
* @param {String} message - message id
* @return {Promise}
*/
var remove = function(url, message) {
var d = $.Deferred();
var data = {
messages: message,
trash: 1
};
data[GV_KEY] = $('input[name="'+ GV_KEY +'"]').first().val();
$.ajax({
type: 'POST',
url: url,
data: data
}).always(d.resolve);
return d.promise();
};
/**
* Remove a collection of message ids
*
* @param {String} url
* @param {Array} messages - message ids
* @return {Promise}
*/
var batch = function(url, messages) {
var d = $.Deferred();
var complete = 0;
var pending = messages.map(function(message) {
return remove(url, message).then(function() {
d.notify(++complete);
});
});
$.when.apply(null, pending).then(d.resolve);
return d.promise();
};
return {
/**
* Get all message ids from a URL
*
* @param {String} url
* @return {Promise}
*/
get: function(url) {
var page = 1;
var messages = [];
return (function next() {
return $.ajax({
url: url,
data: { page: 'p' + page++ }
}).then(function(data) {
var json = $(data).find('json').text();
var results = Object.keys(JSON.parse(json).messages);
messages = messages.concat(results);
return results.length ? next() : messages;
}, function() {
return messages;
});
})();
},
/**
* Trash a collection of messages
*
* @param {Promise|Array} messages
* @return {Promise}
*/
trash: function(messages) {
return $.when(messages).then(function(messages) {
return batch('/voice/inbox/deleteMessages/', messages);
});
},
/**
* Delete a collection of messages forever
*
* @param {Promise|Array} messages
* @return {Promise}
*/
forever: function(messages) {
return $.when(messages).then(function(messages) {
return batch('/voice/inbox/deleteForeverMessages/', messages);
});
}
};
})();
var _handler = function(url, method) {
return function(e) {
if (!confirm('Are you sure?')) { return; }
$(this).addClass('jfk-button-disabled').off('click');
var $span = $(this).find('span').text('(...)');
voice.get(url).done(function(messages) {
method(messages).progress(function(complete) {
$span.text('(' + complete + '/' + messages.length + ')');
}).done(function() {
window.location.reload();
});
});
};
};
var $history = $('<div class="goog-inline-block jfk-button jfk-button-standard jfk-button-collapse-right" style="margin-left: 16px;">Delete ALL <span></span></div>');
var $empty = $('<div class="goog-inline-block jfk-button jfk-button-standard jfk-button-collapse-left">Empty Trash <span></span></div>');
$history.on('click', _handler('/voice/b/0/inbox/recent/all', voice.trash));
$empty.on('click', _handler('/voice/inbox/recent/trash/', voice.forever));
var i = setInterval(function() {
var $parent = $('.gc-appbar-buttons-left');
if ($parent.length) {
clearInterval(i);
$parent.append($history, $empty);
}
}, 5);
})(jQuery);
// ==UserScript==
// @name Delete Google Voice History (WORK IN PROGRESS)
// @description Deletes all Google Voice history
// @version 2.0.0
// @license MIT
// @namespace gavinhungry.io
// @author Gavin Lloyd <gavinhungry@gmail.com>
//
// @include https://voice.google.tld/*
//
// @require https://cdn.jsdelivr.net/jquery/2/jquery.min.js
// @grant none
// ==/UserScript==
(function($) {
'use strict';
// allow us to examine Angular scopes - will refresh the page
if (!angular.element(document.body).scope()) {
angular.reloadWithDebugInfo();
}
// Adds hidden "Delete" option for entire thread - does not seem to work yet
_gv.soyProto.ClientFlags[11].push('deleteThread');
var deleteMessage = function(message) {
console.log('Deleting message');
message.dispatchEvent(new Event('contextmenu'));
return new Promise(function(res, rej) {
setTimeout(function() {
// click the delete button
$('.md-open-menu-container button[aria-label=Delete]:visible').trigger('click');
setTimeout(function() {
// this probably is not necessary - we just need to click the damned button
var $dialogActions = $('button[gv-test-id="message-delete-ok"]').closest('md-dialog-actions');
angular.element($dialogActions).scope().ctrl.onConfirmClick();
setTimeout(res, 250);
}, 250);
}, 250); // FIXME: we are waiting for the context menu to open
});
};
var deleteMessages = function(messages) {
var message = messages.shift();
if (!message) {
return Promise.resolve();
}
deleteMessage(message).then(function() {
deleteMessages(messages);
});
};
$(function() {
var $voicemailButton = $('gv-mini-nav gv-nav-button[icon=voicemail]');
var $deleteButton = $('gv-mini-nav gv-nav-button [role=button][aria-selected!=true]').first().clone();
$deleteButton.find('md-icon').html('delete');
$deleteButton.css('user-select', 'none');
$deleteButton.insertAfter($voicemailButton);
// FIXME: This sucks. Uses the UI, is slow and unreliable and only works on the active thread.
$deleteButton.on('click', function() {
if (!confirm('Are you sure?')) {
return;
}
var messages = $('gv-message-item [gv-test-id]').toArray();
console.log('Deleting', messages.length, 'messages ...');
deleteMessages(messages).then(function() {
console.log('Done deleting messages!');
});
});
});
})(jQuery);
@rpgoldman

This comment has been minimized.

Copy link

commented Jan 14, 2015

For me this just hangs without actually deleting anything. I click on "Delete ALL", the button grays out, and then nothing happens.
When I refresh the page, nothing has been deleted.
Any chance Google changed the API?

@gavinhungry

This comment has been minimized.

Copy link
Owner Author

commented Jan 22, 2015

@rpgoldman - still seems to be working for me. Should look like this:
Google Voice Userscript

Are you using Firefox or Google Chrome (I think Tampermonkey is required for this script in Chrome, I can't remember). Anything of value in the console?

@poormansevo

This comment has been minimized.

Copy link

commented Jan 22, 2015

@rpgoldman - I am using Chrome, installed script via Tampermonkey and worked fine for me. It did take about 30 seconds upon clicking for the messages to start getting deleted, you will see the count increment.

@gavinhungry Thanks for this, very useful!

@thelaurence

This comment has been minimized.

Copy link

commented Mar 25, 2015

Two thousand thanks for this useful script!

alt text

I ran it using Tampermonkey in Chrome, too. Worked great.

@ghhtimsgh1970

This comment has been minimized.

Copy link

commented Jul 13, 2015

Is there something I can to "jostle" the extension into working again? I know how weird that sounds. Often when either Chrome or TamperMonkey updates, the script just stops working. No buttons show up at all. I reload the browser, I reload the extension, I disable/enable it in TamperMonkey - nothing. Then, later on in a few days, I see it showing up again. Any ideas? Thanks for such a great tool. Be good if this was an install-able Chrome extension, btw.

@zoom38

This comment has been minimized.

Copy link

commented Sep 20, 2015

@gavinhungry

I am using firefox with Greasemonkey and can't get this script to work correctly. The "Delete All" and "Empty Trash" buttons appear but no numbers next to the Delete All. When pressing the "Delete All" button while in the history folder, a pop up appears "Are You Sure"/OK/Cancel, I press ok but no messages are deleted. Also when I press the "Empty Trash" button a popup appears "Are Your Sure"/OK/Cancel, I press ok but nothing is deleted from trash.

I have no experience with scripts so I don't know whats wrong. Can you advise what I am doing wrong? Is the browser the issue?

thanks
gary

@sh78

This comment has been minimized.

Copy link

commented Oct 7, 2015

Success with latest build of Chrome on OS X.

Paste the script in to Tampermonkey, save.
Go directly to https://www.google.com/voice (not History or any other label.
Run the script from Tampermonkey.
Click the "DELETE ALL" button above conversations.

@gavinhungry thank you so much!

@chrisonline909

This comment has been minimized.

Copy link

commented Oct 26, 2015

Thanks! worked great
Xubuntu w/chrome

@cdloveless

This comment has been minimized.

Copy link

commented Nov 19, 2015

Worked exactly as advertised, awesome script. You saved me a lot of time!

Thanks!

@takealready

This comment has been minimized.

Copy link

commented Jan 1, 2016

My wife thanks you for this. It still works perfectly well.

@barron600

This comment has been minimized.

Copy link

commented Jan 13, 2016

Hi Guys, I'm a non programmer. Is there any way you guys could "dumb it" down on where to copy and paste the script to run it? Thank You

@stormraiderx

This comment has been minimized.

Copy link

commented Mar 11, 2016

ty

@xmaniic

This comment has been minimized.

Copy link

commented Apr 28, 2016

I can't get this to work either. I see the "Delete All" and "Empty Trash" buttons, but it does not have the number of messages inside the button like yours does.

@kajodowe

This comment has been minimized.

Copy link

commented May 7, 2016

This is great -- thanks so much for this. Worked well although I had to read your FAQ. I clicked 'view raw' and then tampermonkey jumped in and recognized it and installed it in google voice. Nice job!

@zoom38

This comment has been minimized.

Copy link

commented May 22, 2016

I have same issue as xmaniic. Using latest version of Firefox. Anybody know how to correct it?

@jeffreycentex

This comment has been minimized.

Copy link

commented May 31, 2016

Zoom38. Are you logged in with multiple google accounts? I found that the script only works properly on whatever primary account you are logged into. For instance, I was primarily logged in with an App account and my gv was a personal second account. The script kept deleting things from the App account, not the GV account.

@markhilton

This comment has been minimized.

Copy link

commented Jun 16, 2016

Worked great! Thanks for help with this impossible task - I had over 18,000 items to delete!
At first I thought it does not work, since it took like 15 min for it to start deleting items. This script is a live saver, but would be great it you would add a line of descirption of usage at the top. I read from the comments that it would require TamperMonkey to run from, which I was not familiar with.

@electronicsguy

This comment has been minimized.

Copy link

commented Sep 22, 2016

Kudos on the script..works great!

@asilverstein

This comment has been minimized.

Copy link

commented Dec 29, 2016

Awesome work, thanks a million!

@targunp

This comment has been minimized.

Copy link

commented Jan 10, 2017

Or you can just toss this in the console:

window.setInterval(function(){
  document.getElementsByClassName('jfk-checkbox-checkmark')[0].click();
  var e2 = new KeyboardEvent("keydown", {view: window, key: "#",keyIdentifier: "U+0023", code: 'Digit3', shiftKey: true, bubbles: true, cancelable: true});
  delete e2.which;
  delete e2.keyCode;
  Object.defineProperty(e2, "which", {"value" : 51});
  Object.defineProperty(e2, "keyCode", {"value" : 51});
  document.getElementsByClassName('gc')[0].dispatchEvent(e2);
},1000);
@krynetix

This comment has been minimized.

Copy link

commented Jan 12, 2017

How can I change this to Archive instead of Delete?

@backslash05

This comment has been minimized.

Copy link

commented Jan 24, 2017

Script works for me in Chrome... just took about 5 mins for the process to start and had to run multiple times... Stupid Captcha! Thanks

@calitrappedindc

This comment has been minimized.

Copy link

commented Jan 27, 2017

FYI, for newcomers (as I was), you must use Legacy Google Voice for this script to work. Otherwise, well done, sir.

@tree3luva

This comment has been minimized.

Copy link

commented Feb 17, 2017

Thanks gavinhungry for putting the work in to develop this script as a workaround to circumvent Google's data hungry mining operation within our Google Voice call logs.

I run WIN 10 and used Tapermonkey to install without major issue. Howevwr, even though I opted to run the legacy version of GV with this script, I can't get more than 20 or so records to delete at once and I end up having to run the scrip many times. With over 2000 log records, I'm getting no where fast. The Captcha forces me to respond and then I get the "Google automated script" NAG and must run the script all over again to delete another 25 log lines.

Did the recent GV update kill this scripts effectiveness? Has anyone tried targunp's script as an alternative?

Thanks

@gavinhungry

This comment has been minimized.

Copy link
Owner Author

commented Feb 21, 2017

@tree3luva,

I don't know. I saw something similar today when I ran the script (although I didn't get a CAPTCHA). It would only empty 20 at a time from the trash, at least the first time. When I deleted all of my phone calls and tried Empty Trash again, it removed them all in one go (about 40).

I looked at the new Google Voice page. It may be possible to modify this script to work there instead of relying on Legacy Google Voice (which I assume, along with its API, will go away one day), but I don't think it's very straightforward.

@gavinhungry

This comment has been minimized.

Copy link
Owner Author

commented Feb 22, 2017

I've added another file to this Gist, gv-delete-history.user.js, for exploratory work on making this work with the new Google Voice redesign. The old version for legacy Google Voice has been relegated to gv-delete-history-legacy.user.js.

@nmccready

This comment has been minimized.

Copy link

commented May 12, 2017

Anyone use this script with success lately? I've tried with no success. Disregard it is working fine.

@BossOfTheButtons

This comment has been minimized.

Copy link

commented Jul 14, 2017

I used targunp's script in Chrome. Worked like a charm. Better than hoped, in fact. I got it to delete only history before 2017 by searching for "before:2017-12-31", then using the script on the resulting page. The script apparently can be cancelled, but I don't know how. The reload button in Chrome did the job just fine though.

It appears that you can use Voice's search feature to customize exactly what you want deleted, then just let the script go to town. For instance you can have it delete only and exactly everything an ex-girlfriend ever sent to you without having to relive woeful texts. It does not, unfortunately, erase any unpleasant memories regarding ex-girlfriends.

Thanks targunp!

@akv12

This comment has been minimized.

Copy link

commented Oct 31, 2017

where do you add this?

window.setInterval(function(){
document.getElementsByClassName('jfk-checkbox-checkmark')[0].click();
var e2 = new KeyboardEvent("keydown", {view: window, key: "#",keyIdentifier: "U+0023", code: 'Digit3', shiftKey: true, bubbles: true, cancelable: true});
delete e2.which;
delete e2.keyCode;
Object.defineProperty(e2, "which", {"value" : 51});
Object.defineProperty(e2, "keyCode", {"value" : 51});
document.getElementsByClassName('gc')[0].dispatchEvent(e2);
},1000);

I been trying to get this to work. It moves everything to trash but when I click to delete all the trash it moves it to inbox. can someone please help me!

@akv12

This comment has been minimized.

Copy link

commented Oct 31, 2017

it works and deletes everything into the trash can but when I want to go to the trashcan to empty the items. the script with the add on of

window.setInterval(function(){
document.getElementsByClassName('jfk-checkbox-checkmark')[0].click();
var e2 = new KeyboardEvent("keydown", {view: window, key: "#",keyIdentifier: "U+0023", code: 'Digit3', shiftKey: true, bubbles: true, cancelable: true});
delete e2.which;
delete e2.keyCode;
Object.defineProperty(e2, "which", {"value" : 51});
Object.defineProperty(e2, "keyCode", {"value" : 51});
document.getElementsByClassName('gc')[0].dispatchEvent(e2);
},1000);

leads to the items being selected and moved back to inbox.. can someone please help! I have like 10,000 messages that i am trying to delete!

@mbierman

This comment has been minimized.

Copy link

commented Nov 15, 2017

I have the same question as @krynetix. How can I change this to Archive instead of Delete?

@mbierman

This comment has been minimized.

Copy link

commented Nov 15, 2017

@krynetix Since this request hasn't been answered, rather than figure out a user script solution I wrote an Apple Script. If it helps you... https://gist.github.com/mbierman/78baae8f1eeaa898d5ff527584e4cc79

@survsyn

This comment has been minimized.

Copy link

commented Dec 17, 2017

@mbierman

how do I add this script to browser?

Since this request hasn't been answered, rather than figure out a user script solution I wrote an Apple Script. If it helps you... https://gist.github.com/mbierman/78baae8f1eeaa898d5ff527584e4cc79

@paladinshiva

This comment has been minimized.

Copy link

commented Jun 22, 2018

@mbierman
@survsyn
@akv12

Run in Trash ONLY.

This will do it:

window.setInterval(function(){
document.getElementsByClassName('jfk-checkbox-checkmark')[0].click();
var e2 = new KeyboardEvent("keydown", {view: window, key: "#",keyIdentifier: "U+0023", code: 'Digit3', shiftKey: true, bubbles: true, cancelable: true});
delete e2.which;
delete e2.keyCode;
Object.defineProperty(e2, "which", {"value" : 49});
Object.defineProperty(e2, "keyCode", {"value" : 49});
document.getElementsByClassName('gc')[0].dispatchEvent(e2);
},1000);

@survsyn
Usually by pressing F12 you can access Developer Tools in your current browser.
Then choose the console tab, insert the script and press enter.
To stop it, just refresh the page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.