UNPKG

node-dweetio

Version:

A node.js client for dweet.io

470 lines (397 loc) 10.6 kB
(function () { var isNode = true; // Is this loading into node.js? try { isNode = (require); } catch (e) { isNode = false; } var io; var request; var LAST_THING_NAME = "last-thing.dat"; var DWEET_SERVER = "https://dweet.io:443"; var STRICT_SSL = true; var REQUEST_TIMEOUT = 5000; var lastThing; if (isNode) { io = require("socket.io-client"); request = require("request"); if (require("fs").existsSync(LAST_THING_NAME)) { try { lastThing = require("fs").readFileSync(LAST_THING_NAME).toString(); } catch (e) { } } } else { request = function (options, callback) { var self = this; var src = options.url + (options.url.indexOf("?") + 1 ? "&" : "?"); var params = []; var param_name = ""; for (param_name in options.json) { params.push(param_name + "=" + encodeURIComponent(options.json[param_name])); } // Generate a unique callbackname var callbackName = "callback"; var index = 0; while (window.dweetCallback[callbackName + index]) { index++; } callbackName = callbackName + index; window.dweetCallback[callbackName] = function (data) { callback(null, data, data); }; // We're going to load everything with JSONP. params.push("callback=dweetCallback." + callbackName); params.push("_" + "=" + Date.now()); src += params.join("&"); dweet_script_loader(src, function (script) { script.parentNode.removeChild(script); window.dweetCallback[callbackName] = undefined; delete window.dweetCallback[callbackName]; }); }; window.dweetCallback = {}; (function () { var re = /ded|co/; var onload = 'onload'; var onreadystatechange = 'onreadystatechange'; var readyState = 'readyState'; var load = function (src, fn) { var script = document.createElement('script'); script[onload] = script[onreadystatechange] = function () { if (!this[readyState] || re.test(this[readyState])) { script[onload] = script[onreadystatechange] = null; fn && fn(script); script = null; } }; script.async = true; script.src = src; document.body.appendChild(script); }; window.dweet_script_loader = function (srces, fn) { if (typeof srces == 'string') { load(srces, fn); return; } var src = srces.shift(); load(src, function (script) { if (srces.length) { window.dweet_script_loader(srces, fn); } else { fn && fn(script); } }); }; })(); } function isArray(obj) { return Object.prototype.toString.call( obj ) === '[object Array]' } function isFunction(obj) { return typeof obj === 'function'; } var dweetioClient = function () { var self = this; var socket; var listenCallbacks = {}; var currentThing = lastThing; function normalizeDweet(dweet) { if (dweet.created) { dweet.created = new Date(dweet.created); } return dweet; } function normalizeDweets(dweets) { if (dweets instanceof Array) { for (var index = 0; index < dweets.length; index++) { var dweet = dweets[index]; normalizeDweet(dweet); } } else { normalizeDweet(dweets); } return dweets; } function parseBody(body) { var responseData; try { if (typeof body == 'string' || body instanceof String) { responseData = JSON.parse(body); } else { responseData = body; } } catch (e) { } return responseData; } function processResponse(body) { var err; var responseData = parseBody(body); if (!responseData) { err = new Error("server returned an invalid response"); } else if (responseData["this"] == "failed") { err = new Error(responseData["because"]); } return err; } function createKeyedURL(url, key) { if (key) { return url + (url.indexOf("?") + 1 ? "&" : "?") + "key=" + encodeURIComponent(key); } return url; } function processDweetResponse(err, callback, body) { var responseData = parseBody(body); if (!err) { err = processResponse(responseData); } if (responseData && responseData["with"]) { if (callback) callback(err, normalizeDweets(responseData["with"])); } else { if (callback) callback("no response from server", undefined); } } self.set_server = function (server, strictSSL) { DWEET_SERVER = server; STRICT_SSL = strictSSL; if (isNode) { if (strictSSL) require('https').globalAgent.options.rejectUnauthorized = true; else require('https').globalAgent.options.rejectUnauthorized = false; } } self.dweet = function (data, callback) { if (currentThing) { self.dweet_for(currentThing, data, callback); } else { request({ url: DWEET_SERVER + "/dweet", jar: true, method: "POST", followAllRedirects: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL, json: data }, function (err, response, body) { var responseData = parseBody(body); if (responseData["with"] && responseData["with"].thing != currentThing) { currentThing = responseData["with"].thing; if (isNode) { require("fs").writeFile(LAST_THING_NAME, currentThing); } } processDweetResponse(err, callback, responseData); }); } }; self.dweet_for = function (thing, data, key, callback) { if (isFunction(key)) { callback = key; key = null; } request({ url: createKeyedURL(DWEET_SERVER + "/dweet/for/" + thing, key), jar: true, method: "POST", followAllRedirects: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL, json: data }, function (err, response, body) { processDweetResponse(err, callback, body); }); } self.get_latest_dweet_for = function (thing, key, callback) { if (isFunction(key)) { callback = key; key = null; } request({ url: createKeyedURL(DWEET_SERVER + "/get/latest/dweet/for/" + thing, key), jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { processDweetResponse(err, callback, body); }); } self.get_all_dweets_for = function (thing, key, callback) { if (isFunction(key)) { callback = key; key = null; } request({ url: createKeyedURL(DWEET_SERVER + "/get/dweets/for/" + thing, key), jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { processDweetResponse(err, callback, body); }); } self.listen_for = function (thing, key, callback) { if (isFunction(key)) { callback = key; key = null; } // Initialize our callback list if (!listenCallbacks[thing]) { listenCallbacks[thing] = []; } // Add this to our callbacks if (listenCallbacks[thing].indexOf(callback) == -1) { listenCallbacks[thing].push(callback); } function createSocket() { socket = io.connect(DWEET_SERVER + "/stream"); socket.on("connect", function () { // Subscribe to all of the things that we might have asked for before connecting for (var id in listenCallbacks) { socket.emit("subscribe", {thing: id, key: key}); } }); socket.on("new_dweet", function (msg) { if (listenCallbacks[msg.thing]) { normalizeDweets(msg); var callbacks = listenCallbacks[msg.thing]; for (var index = 0; index < callbacks.length; index++) { callbacks[index](msg); } } }); } if (!socket) { if (isNode) { createSocket(); } else { dweet_script_loader([DWEET_SERVER + "/socket.io/socket.io.js"], function () { createSocket(); }); } } else if (socket && socket.socket.connected) { socket.emit("subscribe", {thing: thing}); } } self.stop_listening = function () { listenCallbacks = {}; if (socket) { socket.disconnect(); socket = undefined; } } self.stop_listening_for = function (thing) { listenCallbacks[thing] = undefined; delete listenCallbacks[thing]; if (socket) { socket.emit("unsubscribe", {thing: thing}); } } self.lock = function (thing, lock, key, callback) { request({ url: DWEET_SERVER + "/lock/" + thing + "?lock=" + lock + "&key=" + key, jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { if (!err) { err = processResponse(body); } if (callback) callback(err); }); } self.unlock = function (thing, key, callback) { request({ url: createKeyedURL(DWEET_SERVER + "/unlock/" + thing, key), jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { if (!err) { err = processResponse(body); } if (callback) callback(err); }); } self.remove_lock = function (lock, key, callback) { request({ url: DWEET_SERVER + "/remove/lock/" + lock + "?key=" + key, jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { if (!err) { err = processResponse(body); } if (callback) callback(err); }); } self.set_alert = function(thing, recipients, condition, key, callback) { if(isArray(recipients)) { recipients = recipients.join(); } request({ url: createKeyedURL(DWEET_SERVER + "/alert/" + encodeURIComponent(recipients) + "/when/" + thing + "/" + encodeURIComponent(condition), key), jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { if (!err) { err = processResponse(body); } if (callback) callback(err); }); } self.get_alert = function(thing, key, callback) { request({ url: createKeyedURL(DWEET_SERVER + "/get/alert/for/" + thing, key), jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { if (!err) { err = processResponse(body); } var responseData = parseBody(body); if (callback) callback(err, responseData["with"]); }); } self.remove_alert = function(thing, key, callback) { request({ url: DWEET_SERVER + "/remove/alert/for/" + thing + "?key=" + key, jar: true, timeout: REQUEST_TIMEOUT, strictSSL: STRICT_SSL }, function (err, response, body) { if (!err) { err = processResponse(body); } if (callback) callback(err); }); } }; if (isNode) { module.exports = dweetioClient; } else { window.dweetio = new dweetioClient(); } })();