Advertisement
Guest User

Untitled

a guest
Dec 13th, 2016
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.53 KB | None | 0 0
  1. /// node -i -e "$(cat Dillabot2.js)"
  2. // mysql.server start # for local
  3. var _ = require('minimist')(process.argv);
  4. var _V = _._.includes('verbose');
  5. // var chokidar = require('chokidar');
  6.  
  7. // var DubAPI = require('./DubAPI/index.js');
  8. var DubAPI = require('dubapi');
  9. var M = require('moment');
  10. var mysql = require('mysql');
  11. var Q = require('q');
  12. var R = require('request');
  13. var Moment = M;
  14.  
  15. var D = {
  16. scClientId: '02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea',
  17. botname: 'Dillabot',
  18. botlogin: 'bar',
  19. room: 'beats',
  20. dbLogin: {host: 'localhost', user: 'root', password: 'bar', database: 'dillabot'},
  21.  
  22. // === END OF CREDENTIALS === //
  23.  
  24. _getTrig: /(!.+?(\s|$))/uigm,
  25. _newTrig: /^!(\+|trigger)\s(.+?)\s(.+?)$/ui,
  26. _echo: /^!(-|echo)\s(.+?)$/ui,
  27. _delTrig: /^!(\+|trigger)\s(\S+)$/ui,
  28. _eval: /({\w+?})/g,
  29. _preEval: /{-(\w+?)-}/g,
  30.  
  31. API: null, DB: null,
  32.  
  33. __manpage: 'http://www.kaagaz.io/8cdcc43d',
  34. init(bot) {
  35. this.API = bot;
  36. this.DB = new DB(this.dbLogin)
  37. _V && console.log(`this.API.version : ${this.API.version}`);
  38. this.bindEvents();
  39.  
  40. this.API.connect(this.room);
  41. },
  42. bindEvents() {
  43. this.API.on('error', (err) => console.error('error: ', err));
  44. this.API.on('connected', (room) => {
  45. console.log(`@@${M()._d}connected to ${room} as ${this.__manpage}`)
  46. // this.API.sendChat('im in, whattyall playin?');
  47. // this.API.sendChat('!theme');
  48. // this.API.sendChat('uhh..');
  49. });
  50. this.API.on('disconnected', (room) => console.log(`disconnected from ${room}`));
  51.  
  52. this.API.on(this.API.events.userKick, () => this.API.sendChat('https://media0.giphy.com/media/60DO6stFOSFIA/200_s.gif'));
  53. this.API.on(this.API.events.roomPlaylistUpdate, (e) => {
  54. if (!e.media) return
  55. this._link(this.Play.media.type, this.Play.media.fkid).done((url) => {
  56. this.link = url;
  57. });
  58. this._link(e.media.type, e.media.fkid).done((link) => {
  59. let data = [
  60. e.user.id,
  61. e.media.id,
  62. e.media.name,
  63. e.user.username,
  64. link,
  65. e.score && e.score.grbs || 0
  66. ]; //dj_id, song_id, song_name, dj_name, song_link, grabs
  67. this.DB.addPlaysHistory(data)
  68. })
  69. });
  70.  
  71. this.API.on(this.API.events.chatMessage, (d) => {
  72. if (!d.user) return
  73. _V && console.log(d.user.username + ': ' + d.message)
  74. if (d.user.id == this.API._.self.id) {
  75. return
  76. }
  77. this.triggerMsg = d.message
  78. this.processMessage(d)
  79. });
  80. },
  81. processMessage(d) {
  82. // store raw in datamining table
  83. this.asker = d.user
  84. var msg = d.message.trim();
  85. if (match = msg.match(this._echo)) {
  86. this.processTrig(match[2])
  87. .then((msg) => this.API.sendChat(msg))
  88. } else if (match = msg.match(this._newTrig)) {
  89. _V && console.log('_newTrig')
  90. newTrig = match.splice(2); // [trigger, echo]
  91. this.DB.getTrig(newTrig[0])
  92. .then((r) => {
  93. if (!r.er && r.res && !r.res[0]) {
  94. this.preProcess(newTrig[1]).then((parsedEcho) => {
  95. newTrig[1] = parsedEcho;
  96. this.DB.newTrig(newTrig, d).then(() => this._msg('trigCreated', newTrig[0]))
  97. })
  98. } else if (!r.er && r.res && r.res[0]) {
  99. this._msg('trigExists', r.res[0], d)
  100. }
  101. })
  102.  
  103. } else if (match = msg.match(this._delTrig)) {
  104. _V && console.log('_delTrig')
  105. var delTrig = match.pop(); // [trigger]
  106. this.DB.delTrig(delTrig)
  107. .done(() => this._msg('trigDeleted', delTrig, d))
  108.  
  109. } else if (match = msg.match(this._getTrig)) {
  110. _V && console.log('_getTrig')
  111. allUnique = [...new Set(match.filter((l) => (l + '').trim() != ''))];
  112. allUnique.forEach((trig) => this.callTrig(trig.substr(1)));
  113. }
  114. },
  115. callTrig(trig) {
  116. _V && console.log('getting trig => ' + trig)
  117. // lookup trig
  118. this.DB.getTrig(trig)
  119. .then((r) => {
  120. if(!r.er && r.res && r.res[0]) {
  121. this.processTrig(r.res[0]['echo'])
  122. .then((msg) => this.API.sendChat(msg))
  123. }
  124. })
  125. },
  126. preProcess(txt) {
  127. _V && console.log('pre-processTrig')
  128. var d = Q.defer()
  129.  
  130. if (evals = txt.match(this._preEval)) {
  131. evalsUnique = [...new Set(evals)].map((e) => e.replace(/-/g, '')); // emulate
  132. promises = evalsUnique.map((e) => this[e]).filter((e) => !!e) // evaluate
  133. } else {
  134. promises = [];
  135. }
  136.  
  137. function newRegex(rgx) {
  138. var a = new RegExp(rgx.source.replace(/({(\w+?)})/, '{-$2-}'), rgx.flags)
  139. return a;
  140. }
  141.  
  142. Q.allSettled(promises).then((arg) => {
  143. arg.forEach((r) => {
  144. if (r.state === 'fulfilled') {
  145. txt = txt.replace(newRegex(r.value.regex), r.value.v);
  146. } else {
  147. txt = txt.replace(newRegex(r.reason.regex), r.reason.v);
  148. }
  149. })
  150. d.resolve(txt);
  151. });
  152. return d.promise;
  153. },
  154. processTrig(txt) {
  155. var d = Q.defer()
  156. // find evaluateables
  157. _V && console.log('processTrig')
  158. if (evals = txt.match(this._eval)) {
  159. evalsUnique = [...new Set(evals)];
  160. promises = evalsUnique.map((e) => this[e]).filter((e) => !!e)
  161. } else {
  162. promises = [];
  163. }
  164. Q.allSettled(promises).then((arg) => {
  165. arg.forEach((r) => {
  166. if (r.state === 'fulfilled') {
  167. txt = txt.replace(r.value.regex, r.value.v);
  168. } else {
  169. txt = txt.replace(r.reason.regex, r.reason.v);
  170. }
  171. })
  172. d.resolve(txt);
  173. });
  174. return d.promise;
  175. },
  176. _msg(type, a, b) {
  177. this.API.sendChat({
  178. trigExists(a, b) {
  179. return `"${a.trig}" exists, created by ${a.author} :clock1: ${M(a.created_at).calendar()}`;
  180. },
  181. trigDeleted(a, b) {
  182. return `trigger "${a}" deleted`;
  183. },
  184. trigCreated(a, b) {
  185. return `trigger "${a}" created`;
  186. },
  187. }[type](a, b))
  188. },
  189. _link(type, fkid) {
  190. var d = Q.defer();
  191. if(type == 'youtube') {
  192. var url = 'youtu.be/' + fkid // var link = 'https://www.youtube.com/watch?v=' + fkid
  193. d.resolve(url);
  194. }else if(type == 'soundcloud') {
  195. var url = `http://api.soundcloud.com/tracks/${fkid}.json?client_id=${this.scClientId}`
  196. R.get({json: true, uri: url}, function (er, re, songData) {
  197. d.resolve(songData.permalink_url);
  198. });
  199. }
  200. return d.promise;
  201. },
  202. // facedes
  203. get Play() {
  204. return this.API._.room.play
  205. },
  206. // EVALUATEABLES -- return promise pattern
  207. get '{link}'() {
  208. var regex = new RegExp('{link}', 'gm')
  209. var d = Q.defer();
  210. if (this.Play) {
  211. d.resolve({regex, v: this.link});
  212. } else {
  213. d.reject({regex, v: '{there is no link}'});
  214. // take link from history
  215. }
  216. return d.promise;
  217. },
  218. get '{dj}'() {
  219. var regex = new RegExp('{dj}', 'gm')
  220. var d = Q.defer();
  221. if (this.Play) {
  222. d.resolve({regex, v: this.API.getDJ().username})
  223. } else {
  224. d.reject({regex, v: this.API.getDJ().username})
  225. var dj = '{there is no dj}';
  226. }
  227. return d.promise;
  228. },
  229. get '{thumb}'() {
  230. var regex = new RegExp('{thumb}', 'gm');
  231. var d = Q.defer();
  232. if (this.Play) {
  233. d.resolve({regex, v: this.Play.media.images.thumbnail})
  234. } else {
  235. d.reject({regex, v: '{no thumb}'})
  236. }
  237. return d.promise;
  238. },
  239. get '{djThumb}'() {
  240. var regex = new RegExp('{djThumb}', 'gm');
  241. var d = Q.defer();
  242. if (this.Play) {
  243. d.resolve({regex, v: this.API.getDJ().profileImage.url})
  244. } else {
  245. d.reject({regex, v: '{no dj}'})
  246. }
  247. return d.promise;
  248. },
  249. get '{myThumb}'() {
  250. var regex = new RegExp('{myThumb}', 'gm');
  251. var d = Q.defer();
  252. d.resolve({regex, v: this.asker.profileImage.url})
  253. return d.promise;
  254. },
  255. get '{lastMsg}'() {
  256. var regex = new RegExp('{lastMsg}', 'gm');
  257. var d = Q.defer();
  258. var v = this.API.getChatHistory()
  259. .reverse().find((msg) => {
  260. return (msg.message != this.triggerMsg) &&
  261. (msg.user.username != this.botname);
  262. }).message
  263. d.resolve({regex, v})
  264. return d.promise;
  265. },
  266. get '{manPage}'() {
  267. var regex = new RegExp('{manPage}', 'gm');
  268. var d = Q.defer();
  269. d.resolve({regex, v: this.__manpage})
  270. return d.promise;
  271. },
  272. // update 19th july OLD:'http://www.kaagaz.io/d125496e'
  273. get '{forget}'() {
  274. var regex = new RegExp('{plays}', 'gm');
  275. var d = Q.defer();
  276. // if bot is above or match a moderator
  277. this.API.moderateDeleteChat('chat id..');
  278. d.resolve({regex, v: 'removed n chat'});
  279. return d.promise;
  280. },
  281. get '{plays}'() {
  282. var regex = new RegExp('{plays}', 'gm');
  283. var d = Q.defer();
  284. var M = this.API.getMedia();
  285. if (M && M.id) {
  286. this.DB.getPlaysById(M.id).done((res) => {
  287. var arr = res.res;
  288. console.log(arr, 'arr');
  289. var last = arr[0];
  290. console.log(last, 'last')
  291. var total = arr.length;
  292. var newMsg = last.song_name + ' Plays: ' + total;
  293. if (total > 1) {
  294. var lastReal = arr[1];
  295. newMsg += ' Last spin by: *' + lastReal.dj_name + '* :clock: ' + Moment(lastReal.timestamp).calendar();
  296.  
  297. }
  298. d.resolve({regex, v: newMsg});
  299. //this.API.sendChat(''+res.res.length);
  300. });
  301. }
  302. return d.promise;
  303. },
  304. get '{updub}'() {
  305. this.API.updub();
  306. var regex = new RegExp('{updub}', 'gm');
  307. var d = Q.defer();
  308. d.resolve({regex, v: ''})
  309. return d.promise;
  310. },
  311. get '{triggersCount}'() {
  312. // select count(*) from triggers
  313. },
  314. get '{triggersRecent}'() {
  315. // select count(*) from triggers
  316. },
  317. get '{triggersSpreadsheet}'() {
  318. // echo link
  319. },
  320. }
  321.  
  322. function DB(login) {
  323. this._c = mysql.createConnection(login);
  324. this._getTrig = 'select * from triggers where trig = ? limit 1';
  325. this._newTrig = 'insert into triggers (trig, echo, author, author_id) values (?,?,?,?)';
  326. this._delTrig = 'delete from triggers where trig = ?';
  327. this._addPlaysHistory = 'insert into playhistory (dj_id, song_id, song_name, dj_name, song_link, grabs) values (?,?,?,?,?,?)';
  328. this._getPlaysById = "select * from playhistory where song_id=? order by timestamp desc";
  329. }
  330.  
  331. DB.prototype.getPlaysById = function(id) {
  332. var d = Q.defer()
  333. this._c.query(this._getPlaysById, [id], (er, res) => {
  334. d.resolve({er, res});
  335. })
  336. return d.promise;
  337. }
  338.  
  339. DB.prototype.newTrig = function(newTrig, data) {
  340. var d = Q.defer()
  341. this._c.query(this._newTrig, [
  342. newTrig[0],
  343. newTrig[1],
  344. data.user.username,
  345. data.user.id
  346. ], (er, res) => {
  347. d.resolve({er, res});
  348. })
  349. return d.promise;
  350. }
  351.  
  352. DB.prototype.delTrig = function(trig) {
  353. var d = Q.defer()
  354. this._c.query(this._delTrig, [trig], (er, res) => {
  355. d.resolve({er, res});
  356. })
  357. return d.promise;
  358. }
  359.  
  360. DB.prototype.getTrig = function(trig) {
  361. var d = Q.defer()
  362. this._c.query(this._getTrig, [trig], (er, res) => {
  363. d.resolve({er, res});
  364. })
  365. return d.promise;
  366. }
  367.  
  368. DB.prototype.addPlaysHistory = function(data) {
  369. var d = Q.defer()
  370. this._c.query(this._addPlaysHistory, data, (er, res) => {
  371. d.resolve({er, res});
  372. })
  373. return d.promise;
  374. }
  375.  
  376. // var EXPOSED = {
  377. // sendChat: D.API.sendChat
  378. // }
  379.  
  380. // chokidar.watch('./cli').on('change', (path) => {
  381. // fs.readFile(path, 'utf8', function(err, data) {
  382. // if(data) {
  383. // if (socket) {
  384. // socket.write(data)
  385. // logfile(data)
  386. // }
  387. // }
  388. // });
  389. // });
  390.  
  391. new DubAPI({username: D.botname, password: D.botlogin}, function(err, bot) {
  392. if (err) return console.error('ERROR: ', err);
  393. D.init(bot);
  394. });
  395. /* ALL EVENTS
  396.  
  397. chatMessage: 'chat-message',
  398. chatSkip: 'chat-skip',
  399. deleteChatMessage: 'delete-chat-message',
  400. roomPlaylistDub: 'room_playlist-dub',
  401. roomPlaylistGrab: 'room_playlist-queue-update-grabs',
  402. roomPlaylistQueueUpdate: 'room_playlist-queue-update-dub',
  403. roomPlaylistUpdate: 'room_playlist-update',
  404. roomUpdate: 'room-update',
  405. userBan: 'user-ban',
  406. userImageUpdate: 'user-update',
  407. userJoin: 'user-join',
  408. userKick: 'user-kick',
  409. userLeave: 'user-leave',
  410. userMute: 'user-mute',
  411. userSetRole: 'user-setrole',
  412. userUnban: 'user-unban',
  413. userUnmute: 'user-unmute',
  414. userUnsetRole: 'user-unsetrole',
  415. userUpdate: 'user_update' }
  416.  
  417.  
  418. for !plays .... this.API.getPlayID() and lookup dataMine =/
  419.  
  420.  
  421.  
  422. V-0.0.2 Manpage
  423.  
  424. * Bot listens room user messages
  425. * Bot would echo all matched triggers
  426. * Create new trigger by syntax ✎!trigger triggerName .. and rest will echo, including these two dots
  427. * !+ is an alias of !trigger (In creating/removing trigger, line must start with one of these)
  428. * !- is an alias of !echo (just evaluates and returns)
  429. * An echoed text may contain {expressions} that will evaluate into:
  430.  
  431. ** {dj} - current DJ's name
  432. ** {link} - currently played link
  433. ** {thumb} - current song thumbnail
  434. ** {djThumb} - profile image of current DJ
  435. ** {myThumb} - profile image of the one currently triggering bot
  436. ** {lastMsg} - most recent (non bot, non current trigger) message in this chat
  437. ** {manPage} - this man-page url
  438. *** one might type-out feature-requests in triggers: requests1, requests2 ... , i'll look them up.
  439. * if you want you can evaluate them before new trigger is saved, refer them by using {-expressions-} syntax,
  440. * just use brace+dash instead of simple brace
  441. *
  442. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement