get user email
As of
// ==UserScript==
// @name Instagram Utils
// @namespace http://tampermonkey.net/
// @version 0.0.13
// @description get user email
// @author nibnil
// @match https://www.instagram.com/*
// @icon https://www.google.com/s2/favicons?sz=64&domain=google.com
// @grant GM_addStyle
// @grant GM_xmlhttpRequest
// @grant GM_download
// @license MIT
// ==/UserScript==
var zNode = document.createElement('div')
zNode.innerHTML = "<button id='myButton' type='button'>go</button>"
zNode.setAttribute('id', 'myContainer')
document.body.appendChild(zNode)
document.getElementById ("myButton").addEventListener (
"click", ButtonClickAction, false
)
var userId = ''
function getUserId (url) {
let m
let result = ''
let regex = /https:\/\/i\.instagram\.com\/api\/v1\/feed\/user\/([0-9]+)\/story\//gm
while ((m = regex.exec(url)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
// console.log(`Found match, group ${groupIndex}: ${match}`)
result = match
})
}
// console.log(url, result)
return result
}
function getEmail (url) {
let m
let result = ''
let regex = /"public_email":"((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\]))"/gm;
while ((m = regex.exec(url)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
// console.log(`Found match, group ${groupIndex}: ${match}`)
result = match
})
}
return result
}
function ButtonClickAction (zEvent) {
// alert(userId)
let email = ''
let url = 'https://i.instagram.com/api/v1/users/' + userId + '/info/?entry_point=profile&from_module=search_typeahead'
runAsync(url).then(
(result)=> {return result}).then(function(result){
// console.log(result)
email = getEmail(result)
alert('userId: ' + userId + '\neamil: ' + email)
})
}
function addXMLRequestCallback(callback){
var oldSend, i;
if( XMLHttpRequest.callbacks ) {
// we've already overridden send() so just add the callback
XMLHttpRequest.callbacks.push( callback )
} else {
// create a callback queue
XMLHttpRequest.callbacks = [callback]
// store the native send()
oldSend = XMLHttpRequest.prototype.send
// override the native send()
XMLHttpRequest.prototype.send = function(){
// process the callback queue
// the xhr instance is passed into each callback but seems pretty useless
// you can't tell what its destination is or call abort() without an error
// so only really good for logging that a request has happened
// I could be wrong, I hope so...
// EDIT: I suppose you could override the onreadystatechange handler though
for( i = 0; i < XMLHttpRequest.callbacks.length; i++ ) {
XMLHttpRequest.callbacks[i]( this )
}
// call the native send()
oldSend.apply(this, arguments)
}
}
}
addXMLRequestCallback( function( xhr ) {
xhr.addEventListener("load", function(){
if ( xhr.readyState == 4 && xhr.status == 200 ) {
// console.log( xhr.responseURL );
let res = getUserId(xhr.responseURL)
if ( res !== ''){
userId = res
}
}
})
})
function runAsync(url){
var p = new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'get',
url: url,
headers: {
'Host': 'i.instagram.com',
'x-ig-app-locale': 'zh_CN_#Hans',
'x-ig-device-locale': 'zh_CN_#Hans',
'x-ig-mapped-locale': 'zh_CN',
'x-pigeon-session-id': 'UFS-1a174a85-d05b-477a-9e37-381c350b66f0-5',
'x-pigeon-rawclienttime': '1652686856.896',
'x-ig-bandwidth-speed-kbps': '1152.000',
'x-ig-bandwidth-totalbytes-b': '2869560',
'x-ig-bandwidth-totaltime-ms': '2792',
'x-ig-app-startup-country': 'HK',
'x-bloks-version-id': 'fc65d7f6a5a70acb60167b3f4a75f3e1853d96e44d963c007f53312757e6088e',
'x-ig-www-claim': 'hmac.AR0GnKAGe_UjunEvodVu2UTXM1aV-XTeKeBylEpJrw4brf-K',
'x-bloks-is-layout-rtl': 'false',
'x-ig-device-id': 'c14a8211-b663-4017-950a-c9e2ba642342',
'x-ig-family-device-id': 'd0f4b9dc-9be3-4e79-ac80-4ba28cc2fd9d',
'x-ig-android-id': 'android-1b40cdcc9c9fd3ad',
'x-ig-timezone-offset': '28800',
'x-ig-nav-chain': 'ExploreFragment:explore_popular:5:main_search::,SingleSearchTypeaheadTabFragment:search_typeahead:6:button::',
'x-ig-connection-type': 'WIFI',
'x-ig-capabilities': '3brTv10=',
'x-ig-app-id': '567067343352427',
'priority': 'u=3',
'user-agent': 'Instagram 234.0.0.19.113 Android (29/10; 560dpi; 1440x2712; Google/google; Pixel 2 XL; taimen; taimen; zh_CN_#Hans; 368578771)',
'accept-language': 'zh-CN, en-US',
'authorization': 'Bearer IGT:2:eyJkc191c2VyX2lkIjoiNDc4ODA1MDA3MTQiLCJzZXNzaW9uaWQiOiI0Nzg4MDUwMDcxNCUzQU1HQlRsZUNvR2JQcHFWJTNBMTQifQ==',
'x-mid': 'YoHpsAABAAGtSYz5HU3sETwvWX-d',
'ig-u-ig-direct-region-hint': 'FRC,47880500714,1684222258:01f7682f789f65b0db246e8c84d63fcbdd6dd1c7ba2003133b074d706d6438e6720cbbcb',
'ig-u-ds-user-id': '47880500714',
'ig-u-rur': 'VLL,47880500714,1684222814:01f7ac871673b1911d5b7ddf3d7bcd492aa5d30ea92cc0006a713b1fec491482b7a68b3f',
'ig-intended-user-id': '47880500714',
'x-fb-http-engine': 'Liger',
'x-fb-client-ip': 'True',
'x-fb-server-cluster': 'True'
},
onload: function(response){
resolve(response.responseText)
},
onerror: function(response){
reject('request failed')
}
})
})
return p
}
GM_addStyle ( `
#myContainer {
position: absolute;
top: 0;
left: 0;
font-size: 10px;
background: orange;
border: 3px outset black;
margin: 5px;
opacity: 0.9;
z-index: 1100;
padding: 5px 20px;
}
#myButton {
cursor: pointer;
}
#myContainer p {
color: red;
background: white;
}
` )