Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
iRemember
// How to:
// 1) Login into https://icloud.com
// 2) Open the developer tools and execute this code in the console
// See more @ https://medium.com/bugbountywriteup/how-apple-stored-all-your-email-metadata-for-years-on-their-servers-2a61b1a3232d
const _API_URL='https://p18-mailws.icloud.com/wm/recents';
const _requestContacts = () => {
console.warn('Requesting your contacts...');
return fetch(_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'same-origin',
credentials: 'include',
body: JSON.stringify({
jsonrpc: '2.0',
method: 'list',
}),
}).catch(error => {
console.error('An error happened while trying to list your contacts:', error);
});
}, _deleteContacts = (contacts) => {
console.warn('Asking the backend to delete data it should not have...');
return fetch(_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
credentials: 'same-origin',
credentials: 'include',
body: JSON.stringify({
jsonrpc: '2.0',
method: 'delete',
params: {
guids: contacts
},
}),
}).catch(error => {
console.error('An error happened while trying to delete your contacts:', error);
});
}, listAllContactsDetainedByApple = async () => {
const contacts = await (await _requestContacts()).json();
console.warn(`Here is the raw list of the contacts (${contacts.result.length}):`);
console.warn(JSON.stringify(contacts));
},
deleteEverythingForever = async () => {
const guids = [];
const contacts = (await (await _requestContacts()).json()).result;
for (const contact of contacts) {
if (contact.guid) {
console.warn(`Added address ${contact.address} to the deletion list`);
guids.push(contact.guid);
}
// Cover groups as well
if (contact.isMemberOf) {
for (const group of contact.isMemberOf) {
if (group.guid) {
console.warn(`Added ${contact.address} (group) to the deletion list`);
guids.push(group.guid);
}
}
}
}
if (guids === undefined || guids.length == 0) {
return console.error('No contact to delete');
}
const response = await _deleteContacts(guids);
console.warn('Done! All your recents contact has been deleted from iCloud Mail.');
console.log(response);
};
console.warn(window.atob("DQogXyBfX19fXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfICAgICAgICAgICAgICAgDQooXykgIF9fIFwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgfCAgICAgICAgICAgICAgDQogX3wgfF9fKSB8X19fIF8gX18gX19fICAgX19fIF8gX18gX19fIHwgfF9fICAgX19fIF8gX18gDQp8IHwgIF8gIC8vIF8gXCAnXyBgIF8gXCAvIF8gXCAnXyBgIF8gXHwgJ18gXCAvIF8gXCAnX198DQp8IHwgfCBcIFwgIF9fLyB8IHwgfCB8IHwgIF9fLyB8IHwgfCB8IHwgfF8pIHwgIF9fLyB8ICAgDQp8X3xffCAgXF9cX19ffF98IHxffCB8X3xcX19ffF98IHxffCB8X3xfLl9fLyBcX19ffF98ICAgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg")),console.warn("To see all the email addresses you ever contacted using Apple Mail since the launch of iCloud, run listAllContactsDetainedByApple()"),console.warn("Since Apple does not provide a way to delete everything at once, or even see the full list, you can easily delete everything forever by running deleteEverythingForever()");
@sqers
Copy link

sqers commented Jun 1, 2018

<script src="https://gist.github.com/pwnsdx/9a8092604363bbaf5560f1d68171ccd9.js"></script>

@PowerPress
Copy link

PowerPress commented Aug 14, 2018

Just tried it and got the following errors:


() __ \ | |
| |) | _ __ ___ ___ _ __ ___ | |__ ___ _ __
| | _ // _ \ '
_ \ / _ \ '_ _ | '_ \ / _ \ '|
| | | \ \ / | | | | | / | | | | | |) | __/ |
|
|_| __
|| || |_|_
|| || ||.
/ ___|_|

(anonymous) @ VM79:71
VM79:71 To see all the email addresses you ever contacted using Apple Mail since the launch of iCloud, run listAllContactsDetainedByApple()
(anonymous) @ VM79:71
VM79:71 Since Apple does not provide a way to delete everything at once, or even see the full list, you can easily delete everything forever by running deleteEverythingForever()
(anonymous) @ VM79:71
undefined
listAllContactsDetainedByApple()
VM79:7 Requesting your contacts...
_requestContacts @ VM79:7
listAllContactsDetainedByApple @ VM79:42
(anonymous) @ VM81:1
Promise {}proto: Promise[[PromiseStatus]]: "rejected"[[PromiseValue]]: SyntaxError: Unexpected end of JSON input
at listAllContactsDetainedByApple (:42:59)
recents:1 POST https://p18-mailws.icloud.com/wm/recents 500 (Internal Server Error)
VM79:42 Uncaught (in promise) SyntaxError: Unexpected end of JSON input
at listAllContactsDetainedByApple (:42:59)
listAllContactsDetainedByApple @ VM79:42
async function (async)
listAllContactsDetainedByApple @ VM79:41
(anonymous) @ VM81:1
listAllContactsDetainedByApple()
VM79:7 Requesting your contacts...
_requestContacts @ VM79:7
listAllContactsDetainedByApple @ VM79:42
(anonymous) @ VM84:1
Promise {}
VM34:1 POST https://p18-mailws.icloud.com/wm/recents 500 (Internal Server Error)
(anonymous) @ VM34:1
_requestContacts @ VM79:8
listAllContactsDetainedByApple @ VM79:42
(anonymous) @ VM84:1
VM79:42 Uncaught (in promise) SyntaxError: Unexpected end of JSON input
at listAllContactsDetainedByApple (:42:59)
listAllContactsDetainedByApple @ VM79:42
async function (async)
listAllContactsDetainedByApple @ VM79:41
(anonymous) @ VM84:1

@DaanQ
Copy link

DaanQ commented Dec 22, 2021

Hey @pwnsdx I'm grateful you managed to create and share this code! It works well, although there does seem to be problem I can't get rid of. Even though "Groups" are part of the code, these groups are the only things that still show up when I compose an email in iCloud Mail (web interface). This happens even when all the contacts were deleted successfully using your code. I'm not as tech savvy as you are, so I was wondering if you are able to look into this and perhaps find a solution? :)

@DaanQ
Copy link

DaanQ commented Dec 23, 2021

In addition to my comment, I’ll share some extra context. Using the Developer menu in Safari I was able to find the source in which the recipients that are part of a “group” are located (see attached). In my case there are two groups, both consisting of two recipients. This matches the XML format which is located under Other data > Apple Features Using iCloud > Mail > Recents.xml following a GDPR request I submitted to Apple for access to my data. As I noted, all individual recipients have been succesfully deleted using iRemember, but these groups (i.e. a combination of recipients) seem to require a slightly different approach. At this point I’m lacking the technical skills to adjust your code and make it work. I did try tweaking some things but being a layperson in coding I have no idea what I’m doing. Help from this community is much appreciated! :)
Recent Groups iCloud Mail

@rummtron
Copy link

rummtron commented Jan 2, 2022

TLDR; I too could use what @DaanQ is requesting.

The iRemember tool worked very well for removing single recipient suggested contacts, but after 10 years of working for a CSP, there are many hundreds of "suggested contacts" that contain multiple recipients. Now that I have taken a new position with a different company, these contacts are still showing up even though all email and unnecessary contacts have been removed from my iPhone/iCloud accounts. Any help would be greatly appreciated to help clean this up.

@toomanyquestions1
Copy link

toomanyquestions1 commented Jan 12, 2022

Hi @pwnsdx, I registered here only because I wanted to delete my data using this script, but unfortunately I get error 500 with both commands. I tried it with both Firefox and Ungoogled Chromium, disabled my add-ons, created a new Firefox profile and ran the commands again to no avail. I don't know what I am doing wrong. Any help would be greatly appreciated.

500

@ink-splatters
Copy link

ink-splatters commented Mar 6, 2022

Holy. Shit.

@gordonwang0
Copy link

gordonwang0 commented Jun 2, 2022

@DaanQ, @rummtron

To remove the groups, edit line 47 so that the guids array contains the recentId of the group to delete too.

So in the screenshot @DaanQ posted, take the recentId of each group. It should begin with GP_.

Then change line 47 to const guids = ["recents:GP_ABC", "recents:GP_XYZ];, replacing GP_ABC/GP_XYZ with your recentId (keep the recents: prefix). Run deleteEverythingForever(), which will remove the groups listed.

I only had one group to remove, so this was fine for me. But if you have a lot of groups, then it might be annoying to list all of them.

@DaanQ
Copy link

DaanQ commented Jun 3, 2022

@gordonwang0 Thanks a lot for your help, your instructions worked flawlessly in my case! All recent recipients and groups are deleted now. Really happy with it :)

@rummtron I hope it will work for you as well!

@AkeemMP
Copy link

AkeemMP commented Jun 22, 2022

Thanks also from my side, I could finally get rid of all those dead entries always showing up in icloud.
However there is one record in my case remaining, i cant get it deleted with directly adding to the guids.
Using the p18-mailws doesnt show it at all, but in the dev console, i see it in the recents at p120-mcc.
The only difference to all others is
reciepientEmail has no maildomain, so just user, i.e. from local mails and senderApp is also not set at all and recipientName is emptyString.
Any chance to get rid of that one? I hope Apple does not check field validity on deletion ...
Screenshot 2022-06-22 at 22 04 46
n

@huabin
Copy link

huabin commented Jul 23, 2022

Hello @pwnsdx , thank you for sharing this scripts, and I meet an issue. I ran this scripts, and got tips No contact to delete, please check this picture.

Screen Shot 2022-07-23 at 5 49 45 PM

But the suggestion still remains when i compose a new mail. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment