Skip to content

Instantly share code, notes, and snippets.

@adriancuadrado
Last active February 23, 2023 08:52
Show Gist options
  • Save adriancuadrado/84408b9b6d53e41858a2f1b9f20090d6 to your computer and use it in GitHub Desktop.
Save adriancuadrado/84408b9b6d53e41858a2f1b9f20090d6 to your computer and use it in GitHub Desktop.
Scripts to import/export Postman's history
(async function() {
const filename = 'postman-history-export.json';
const download = (function() {
const element = document.createElement('a');
return function(filename, contents) {
element.setAttribute('href', URL.createObjectURL(new Blob([contents])));
element.setAttribute('download', filename);
element.click();
}
}());
let transaction = await new Promise(
resolve =>
indexedDB
.open('postman-app')
.onsuccess =
event =>
resolve(
event
.target
.result
.transaction(['history', 'history_responses'])
)
);
function getAll(transaction, objectStore) {
return new Promise(
resolve =>
transaction
.objectStore(objectStore)
.getAll()
.onsuccess =
event =>
resolve(event.target.result)
);
}
const data = {
requests: await getAll(transaction, 'history'),
responses: await getAll(transaction, 'history_responses')
};
download(filename, JSON.stringify(data));
})();
(async function() {
function selectFile () {
let resolveFile = null;
const inputElement = document.createElement('input');
inputElement.setAttribute('type', 'file');
inputElement.addEventListener('change', event => resolveFile(event.target.files[0]));
inputElement.click();
return new Promise(r => resolveFile = r);
}
const getFileContents = (function () {
let resolveContents = null;
const reader = new FileReader();
reader.addEventListener('load', event => resolveContents(event.target.result));
return function (file) {
reader.readAsText(file);
return new Promise(r => resolveContents = r);
}
})();
async function importData(data) {
let transaction = await new Promise(
resolve =>
indexedDB
.open('postman-app')
.onsuccess =
event =>
resolve(
event
.target
.result
.transaction(
[
'history',
'history_responses'
], 'readwrite'
)
)
);
function addAll(objectStore, data) {
objectStore.clear().onsuccess = () => data.forEach(e => objectStore.add(e));
}
addAll(transaction.objectStore('history'), data.requests);
addAll(transaction.objectStore('history_responses'), data.responses);
}
importData(JSON.parse(await getFileContents(await selectFile())));
})();
await (async function() {
// These are the properties to keep for each request and response. The database returns more properties that are not
// interesting. If you remove all items from the `request` and `response` arrays in the `propertiesToKeep` object, the
// request and response objects returned will contain all properties from the database instead of just these.
let propertiesToKeep = {
request: [
'createdAt',
'headerData',
'method',
'data',
'response',
'url'
],
response: [
'cookies',
'headers',
'responseCode',
'text'
]
}
let transaction = await new Promise(
resolve =>
indexedDB
.open('postman-app')
.onsuccess =
event =>
resolve(
event
.target
.result
.transaction(['history', 'history_responses'])
)
);
function getAll(transaction, objectStore) {
return new Promise(
resolve =>
transaction
.objectStore(objectStore)
.getAll()
.onsuccess =
event =>
resolve(event.target.result)
);
}
let requests = (await getAll(transaction, 'history'))
.sort((r1, r2) => r1.createdAt.localeCompare(r2.createdAt));
let responses = await getAll(transaction, 'history_responses');
requests.forEach(req => {
let res = responses.find(r => r.history == req.id);
req.response = res;
if(propertiesToKeep.request.length > 0) {
Object.keys(req).filter(k => !propertiesToKeep.request .includes(k)).forEach(k => delete req[k]);
}
if(propertiesToKeep.response.length > 0){
Object.keys(res).filter(k => !propertiesToKeep.response.includes(k)).forEach(k => delete res[k]);
}
});
return requests;
})();
.[] as $req |
"curl \\\n"
+ "--location \\\n"
+ "--request " + $req.method + " \\\n"
+ if
$req.method != "GET"
and $req.method != "HEAD"
and $req.method != "DELETE"
then "--data-raw '" + $req.data + "' \\\n"
else ""
end
+ if $req.headerData
then
reduce (
$req.headerData[]
| "--header '" + .key + ": " + .value + "' \\\n"
) as $line (""; . + $line)
else ""
end
+ "'" + $req.url + "'" + "\n"
@adriancuadrado
Copy link
Author

I logged in with my account and can confirm the version is now v9.24.1. However I am not sure how to use the proxy to record requests because I don't see the antenna icon there:

image

@adriancuadrado
Copy link
Author

Oh fuck, they changed the location and is now in the footer:

image

@adriancuadrado
Copy link
Author

@mrjoesm I can reproduce the error. I think the problem is that the History is not saved locally when you log in into Postman. I'd bet it is saved in your Postman account instead. I'll have to study this a little more, but I think I'll have to see which requests Postman does to retrieve the History and make them.

@adriancuadrado
Copy link
Author

adriancuadrado commented Jul 19, 2022

TLDR: This shit is too hard and I think I won't keep working on your issue. Read the comment below to understand why and/or if you want to try fixing it yourself.

@mrjoesm I've been working on your issue for a while and I think I won't be able to make the import/export of history work in postman when you are logged in. I tried opening postman without my account in in one pc, and logging in with my postman account in another. Then, in the computer without my account, I set up the postman's proxy to view all requests and responses. In the computer where I logged in, I connected to the proxy. Then I restarted Postman to force it reload the requests from History so that I could find the request that gave me the History form my postman account. Finally, once the history is loaded, I disconnected the proxy and exported the requests that were made by postman itself to load the history from my account and tried to reproduce the requests. This last step is where I struggle, because no matter what I always get an error saying something like "Invalid Session ID". I think I have to replace the "sid" from the request with another value, but it doesn't work. I found the first request where the session id's value appears in the response and tried using that value, but I still get the same error.

Interestingly, when I use postman from the web browser (https://web.postman.co/), I get some differences in the way some requests are made. When I use the "Copy all as HAR" option in the Chrome devtools to see the requests being made by Chrome, it seems like the request that returns the History is actually a web socket. No idea why Postman doesn't show this in the History when I use the proxy. But it doesn't really matter because I couldn't reproduce the web socket response anyways.

If you ever try and find a solution to your issue, let me know and I'll update the Javascript code snippets accordingly.

@mrjoesm
Copy link

mrjoesm commented Jul 19, 2022

thanks @adriancuadrado - I appreciate the effort

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