SHARE
TWEET

Untitled

a guest Dec 13th, 2016 66 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. */
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top