Skip to content

Instantly share code, notes, and snippets.

@TrevorBasinger
Created July 29, 2015 19:26
Show Gist options
  • Save TrevorBasinger/3d6c1712f41aafe5bf89 to your computer and use it in GitHub Desktop.
Save TrevorBasinger/3d6c1712f41aafe5bf89 to your computer and use it in GitHub Desktop.
var slackbot = require ('node-slackbot'),
/// winston = require ('winston'),
request = require ('request'),
sleep = require ('sleep').sleep,
Future = require ('data.future'),
Tuple2 = require ('fantasy-tuples').Tuple2,
M = require ('control.monads'),
State = require ('fantasy-states'),
Reader = require ('fantasy-readers'),
R = require ('ramda'),
weather = require ('./forecast'),
APP_NAME = 'TrevBot',
SF = State.StateT (Future);
SF.prototype.map = function (f) { return this.chain (compose (SF.of, f)); };
RSF = Reader.ReaderT (SF);
RSF.prototype.map = function (f) {
return this.chain (R.compose (RSF.of, f));
};
liftReader = RSF.lift;
RSF.lift = R.compose (liftReader, SF.lift);
var
TOKEN = 'TOKENGOESHERE',
add = R.add,
compose = R.compose,
curry = R.curry,
eq = R.eq,
filter = R.filter,
foldr = R.foldr,
get = R.get,
map = R.map,
// logger = winston,
log = function (x) { console.log (x); },//logger.info (x); },
logI = function (x) { log (x); return x; },
liftFuture = function (future) {
return SF (function (s) {
return f.chain (function (x) {
return new Future (function (reject, resolve) {
resolve (Tuple2 (x, s));
});
});
});
},
getParts = function getParts(str, len) {
var res = [];
while (str.length) {
res.push(str.substring(0, len));
str = str.substring(len);
}
return res;
},
// type Response = { channel: String, text: String }
mkResponse = curry (function (message, text) {
return {
channel: message.channel,
text: text
};
}),
getFiles = new Future (function (reject, resolve) {
request ('https://slack.com/api/files.list?token='+TOKEN, function (err, res, body) {
if (err) { return reject (err); }
resolve (JSON.parse (body));
});
}),
requestHandler = curry (function (reject, resolve, err, res, body){
if (err) { return reject (err); }
return resolve (body);
}),
reply = curry (function (text, message) {
return SF (function (s) {
s.responses.push (mkResponse (message, text));
return Future.of (Tuple2 (message, s));
});
}),
replyFuture = curry (function (future, message) {
return SF (function (s) {
return new Future (function (reject, resolve) {
future.fork (reject, function (x) {
s.responses.push (mkResponse (message, x.toString ()));
resolve (Tuple2 (message, s));
});
});
});
}),
sendResponse = curry (function (bot, response) {
if (!!! response.channel || !!! response.text) { console.log ('bugging out'); return; }
setTimeout (function () {
bot.sendMessage (response.channel, response.text);
}, 1000); // Need to keep this here to prevent from sending too fast.
}),
joinResponse = curry (function (r1, r2) {
return { text: R.trim (r1.text + "\n" + r2.text), channel: r1.channel || r2.channel };
}),
sendResponses = curry (function (bot, message) {
return SF (function (s) {
return new Future (function (reject, resolve) {
if (s.responses.length > 0) {
var x = foldr (joinResponse, {text: '', channel:''}, s.responses);
s.responses = [];
s.responses.push (x);
}
map (sendResponse (bot), s.responses); // Multiple async calls unsafe.
return resolve (Tuple2 (true, s));
});
});
}),
// match :: str ->
match = curry (function (str, f, message) {
return liftReader (function (message) {
if (!!message && message.hasOwnProperty ('text') && message.text.search (str) >= 0)
{ return f (message); }
else
{ return SF.of (message); }
});
}),
sequence = curry (function (m, ms) {
return R.reduce (perform, m.of([]), ms);
function perform (mr, mx) {
return mr.chain (function (xs) {
return mx.chain (function (x) {
xs.push (x);
return m.of (xs);
});
});
}
}),
nil = null;
(function () {
var
debug = false,
defaultState = {responses: []};
bot = new slackbot (TOKEN);
bot.use (function (message, cb) {
var modules = [weather.app];
var app = sequence (RSF, modules);
app.run (message)
.evalState (defaultState)
.fork (logI, compose (logI, JSON.stringify));
});
bot.connect ();
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment