Skip to content

Instantly share code, notes, and snippets.

@Swizec
Created August 3, 2017 15:49
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Swizec/de31ad9f995b0ad6bfe84dafd92e1e53 to your computer and use it in GitHub Desktop.
Save Swizec/de31ad9f995b0ad6bfe84dafd92e1e53 to your computer and use it in GitHub Desktop.
Unofficial HackerNews write API wrapper
import cheerio from 'cheerio-without-node-native';
const convertRequestBodyToFormUrlEncoded = (data) => {
const bodyKeys = Object.keys(data);
const str = [];
for (let i = 0; i < bodyKeys.length; i += 1) {
const thisKey = bodyKeys[i];
const thisValue = data[thisKey];
str.push(`${encodeURIComponent(thisKey)}=${encodeURIComponent(thisValue)}`);
}
return str.join('&');
};
class HN {
BaseURL = 'https://news.ycombinator.com';
login(username, password) {
let headers = new Headers({
"Content-Type": "application/x-www-form-urlencoded",
"Access-Control-Allow-Origin": "*"
});
return fetch(`${this.BaseURL}/login`,
{
method: "POST",
headers: headers,
body: convertRequestBodyToFormUrlEncoded({
acct: username,
pw: password,
goto: 'news'
}),
mode: 'no-cors',
credentials: 'include'
}).then(res => res.text())
.then(body => {
if (body.match(/Bad Login/i)) {
return false;
}else{
return true;
}
});
}
getUpvoteURL(id) {
return fetch(`${this.BaseURL}/item?id=${id}`,
{
mode: 'no-cors',
credentials: 'include'
}).then(res => res.text())
.then(body => {
const doc = cheerio.load(body);
return doc(`#up_${id}`).attr('href');
});
}
getHmac(id) {
return fetch(`${this.BaseURL}/item?id=${id}`,
{
mode: 'no-cors',
credentials: 'include'
}).then(res => res.text())
.then(body => {
const doc = cheerio.load(body);
return doc('input[name=hmac]').attr('value');
});
}
upvote(id) {
return this.getUpvoteURL(id)
.then(url => fetch(`${this.BaseURL}/${url}`, {
mode: 'no-cors',
credentials: 'include'
}))
.then(res => res.text())
.then(body => {
return true;
})
.catch(error => {
console.log(error);
return false;
});
}
reply(id, text) {
return this.getHmac(id)
.then(hmac => {
let headers = new Headers({
"Content-Type": "application/x-www-form-urlencoded",
"Access-Control-Allow-Origin": "*"
});
return fetch(`${this.BaseURL}/comment`,
{
method: "POST",
headers: headers,
body: convertRequestBodyToFormUrlEncoded({
parent: id,
goto: `item?id=${id}`,
hmac: hmac,
text: text
}),
mode: 'no-cors',
credentials: 'include'
})
}).then(res => res.text())
.then(body => {
return {
success: true,
error: null
}
});
}
}
export default new HN();
@rayray
Copy link

rayray commented Oct 2, 2018

Great job!

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