Skip to content

Instantly share code, notes, and snippets.

@tukib
Last active October 13, 2019 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tukib/a897c38b8fcb4799b58eb65358179cce to your computer and use it in GitHub Desktop.
Save tukib/a897c38b8fcb4799b58eb65358179cce to your computer and use it in GitHub Desktop.
Hackmud Chat API for Node.js
"use strict"
const request = require("request")
const API = {
domain_root: "www.hackmud.com",
__promise_wrap: (endpoint, dat) => {
return new Promise((resolve, reject) => {
request({
method: "POST",
uri: "https://"+API.domain_root+"/mobile/"+endpoint+".json",
json: dat
}, (error, response, body) => {
if (!error && response.statusCode === 200) {
resolve(body)
} else {
reject({
error: error,
statusCode: response ? response.statusCode : null,
body: body
})
}
})
})
},
get_token: pass => API.__promise_wrap("get_token", {pass: pass}),
account_data: token => API.__promise_wrap("account_data", {chat_token: token}),
chats: (token, usernames, ext={}) => API.__promise_wrap("chats", Object.assign(ext, {chat_token: token, usernames: usernames})),
send: (token, username, channel, msg) => API.__promise_wrap("create_chat", {chat_token: token, username: username, channel: channel, msg: msg}),
tell: (token, username, user, msg) => API.__promise_wrap("create_chat", {chat_token: token, username: username, tell: user, msg: msg}),
}
class Channel {
constructor(user, name, users) {
this.user = user
this.name = name
this.users = users
}
send(msg) {
return API.send(this.user.account.token, this.user.name, this.name, msg)
}
print() {
console.log(" Channel:")
console.log(" name: "+this.name)
}
}
class User {
constructor(account, name, dat) {
this.account = account
this.name = name
this.channels = {}
for (var i in dat) {
this.channels[i] = new Channel(this, i, dat[i])
}
}
tell(to, msg) {
return API.tell(this.account.token, this.name, to, msg)
}
print() {
console.log(" User:")
console.log(" name: "+this.name)
console.log(" channels:")
for (var i in this.channels) {
this.channels[i].print()
}
}
}
class Account {
constructor(last=null) {
this.users = null
this.token = null
this.last = last
}
login(pass) {
if (pass.length > 10) return this.update(pass)
return API.get_token(pass).then(token => this.update(token.chat_token))
}
update(token) {
this.token = token
return API.account_data(this.token).then(dat => {
if (!dat.ok) return false
this.users = {}
for (var i in dat.users) {
const name = i
this.users[name] = new User(this, name, dat.users[i])
}
return this
})
}
poll(ext={}) {
const ar = []
const names = []
if (this.last) {
if (ext.before == "last") {
ext.before = this.last + 0.001
}
if (ext.after == "last") {
ext.after = this.last - 0.001
// next two lines were written by dtr
var five_min_ago = new Date() / 1000 - 300
if (ext.after < five_min_ago) ext.after = five_min_ago
}
}
return API.chats(this.token, Object.keys(this.users), ext).then(o => {
if (!o.ok) return o
let last = 0
for (var i in o.chats) {
o.chats[i].sort((a, b) => a.t - b.t)
const l = o.chats[i]
if (l.length && l[l.length-1].t > last) {
last = l[l.length-1].t
}
o.chats[i].filter(m => {
return typeof m.channel !== "undefined" && (m.is_join || m.is_leave)
}).forEach(m => {
const ch = this.users[i].channels[m.channel]
if (m.is_join) {
if (ch.users.indexOf(m.from_user) === -1) {
ch.users.push(m.from_user)
}
}
if (m.is_leave) {
for (var ind = ch.users.indexOf(m.from_user); ind !== -1; ind = ch.users.indexOf(m.froM_user)) {
ch.users.splice(ind, 1)
}
}
})
}
if (last) {
this.last = last
}
return o
})
}
print() {
console.log("Account:")
console.log(" token: "+this.token)
console.log(" users:")
for (var i in this.users) {
this.users[i].print()
}
}
}
module.exports = {
API: API,
Account: Account,
User: User,
Channel: Channel
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment