<commit_before>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
          \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
           \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/

This is a sample Slack bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Slack using the real time API
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# RUN THE BOT:

  Get a Bot token from Slack:

    -> http://my.slack.com/services/new/bot

  Run your bot from the command line:

    token=<MY TOKEN> node bot.js

# USE THE BOT:

  Find your bot inside Slack to send it a direct message.

  Say: "Hello"

  The bot will reply "Hello!"

  Say: "who are you?"

  The bot will tell you its name, where it running, and for how long.

  Say: "Call me <nickname>"

  Tell the bot your nickname. Now you are friends.

  Say: "who am I?"

  The bot will tell you your nickname, if it knows one for you.

  Say: "shutdown"

  The bot will ask if you are sure, and then shut itself down.

  Make sure to invite your bot into other channels using /invite @<my bot>!

# EXTEND THE BOT:

  Botkit is has many features for building cool and useful bots!

  Read all about it here:

    -> http://howdy.ai/botkit

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//AVOID HEROKU BINDING ERROR
var Botkit = require('./lib/Botkit.js')
var os = require('os');
var http = require('follow-redirects').http;
var cheerio = require('cheerio');
var request = require('request');
var StringDecoder = require('string_decoder').StringDecoder;
var url = require('url');
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
http.createServer(function (req, res) {
  if (req.method == 'POST') {
        console.log("POST");
        var body = '';
        console.log(JSON.stringify(req.headers));
        req.on('data', function (data) {
            body += data;
            console.log("Partial body: " + body);
        });
        req.on('end', function () {
            console.log("Body: " + body);
            body_dict = url.parse('http://www.foo.com/?'+body,true);
            channel_id = body_dict.query.channel_id;
            channel_name = body_dict.query.channel_name;
            text = body_dict.query.text;
            new_channel_name = text + '-' + channel_name;
            slack_token = process.env.slack_token;
            //url_change_name = '?token=&channel='+channel_id+'&name='+new_channel_name+'&pretty=1'
            request.post(
                'https://slack.com/api/channels.rename?token='+slack_token+'&channel='+ channel_id +'&name='+new_channel_name+'&pretty=1',
                {},
                function (error, response, body) {
                    if (!error && response.statusCode == 200) {
                        console.log(body)
                    }
                }
            );

        });
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end('post received');
    }
    else
    {
        console.log("GET");
        console.log(JSON.stringify(req.headers));
        var query_data = url.parse(req.url, true).query;
        var channel_id = query_data.channel_id;
        var channel_name = query_data.channel_name;
        var text = query_data.text;
        var new_channel_name = text + '-' + channel_name;
        var slack_token = process.env.slack_token;
        var excluded_channels = ['C0J3T86TY','C0J3T1ZMY', 'C0J6A8PF1','C0J44SUJD']
        var mutable = true
        for (var i = 0; i < excluded_channels.length; i++) {
          if (excluded_channels[i] === channel_id) {
            mutable = false;
          }
        }
        if (mutable){
          //url_change_name = '?token=&channel='+channel_id+'&name='+new_channel_name+'&pretty=1'
          request.post(
              'https://slack.com/api/chat.postMessage?token='+slack_token+'&channel='+ channel_id +'&text=http://45.media.tumblr.com/tumblr_m5br53wRjA1rpugqso1_250.gif&pretty=1',
              {},
              function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                      console.log("Success!")
                  }
              }
          );
          sleep(1000);
          request.post(
              'https://slack.com/api/channels.rename?token='+slack_token+'&channel='+ channel_id +'&name='+new_channel_name+'&pretty=1',
              {},
              function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                      console.log("Success!")
                  }
              }
          );
          request.post(
              'https://slack.com/api/channels.archive?token='+slack_token+'&channel='+ channel_id +'&pretty=1',
              {},
              function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                      console.log("Success!")
                  }
              }
          );
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end('post received');
        }
        else {
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end("You can't solve this channel");
        }

    }
}).listen(process.env.PORT || 5000);
//END AVOIDANCE

function getOneAcross(def,cons, cb){
  var options = {
    host: 'www3.oneacross.com',
    path: '/cgi-bin/search_banner.cgi?c0='+encodeURIComponent(def)+'&p0='+ encodeURIComponent(cons)+'&s=+Go%21+'
  };
  console.log(def);
  console.log(cons);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    // Buffer the body entirely for processing as a whole.
    var bodyChunks = [];
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      bodyChunks.push(chunk);
    });
    res.on('end', function() {
      var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      var words = [];
      $('tt').each(function(i, elem) {
        // var thisWord = $(this).text();
        var starEmoji = ":star:";
        var stars = 0;
        $(this).parent().siblings().first().children().each(function(i, elem) {
          if ($(this).attr('src')=="/images/smallstarblack.gif"){
            stars++;
          }
        });
        // console.log(thisWord + ' ' + stars);

        words.push(starEmoji.repeat(stars) + $(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

function getNutrimatic(query, cb){
  var options = {
    host: 'www.nutrimatic.org',
    path: '/?q='+query
  };
  console.log(query);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    //console.log('Body: ' + res.body);
    // Buffer the body entirely for processing as a whole.
    var body ='';
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      //var textChunk = decoder.write(chunk);
      body = body.concat(chunk);
      //console.log(chunk);
    });
    res.on('end', function() {
      //console.log(body);
      // var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      //console.log(body);
      var words = [];
      $('span').each(function(i, elem) {
        words.push($(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

var controller = Botkit.slackbot({
  debug: false,
});

var bot = controller.spawn(
  {
    token:process.env.token
  }
).startRTM();

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

controller.hears(['call me (.*)'],'direct_message,direct_mention,mention',function(bot,message) {
  var matches = message.text.match(/call me (.*)/i);
  var output = '';
  for (var i = 0; i < matches.length; i++) {
    output = output.concat(i, matches[i]);
  }
  var name = matches[1];
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    user.name = name;
    controller.storage.users.save(user,function(err,id) {
      bot.reply(message,"Got it. I will call you " + output + " from now on.");
    })
  })
});

controller.hears(['what is my name','who am i'],'direct_message,direct_mention,mention',function(bot,message) {

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Your name is " + user.name);
    } else {
      bot.reply(message,"I don't know yet!");
    }
  })
});

controller.hears(['shutdown'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.startConversation(message,function(err,convo) {
    convo.ask("Are you sure you want me to shutdown?",[
      {
        pattern: bot.utterances.yes,
        callback: function(response,convo) {
          convo.say("Bye!");
          convo.next();
          setTimeout(function() {
            process.exit();
          },3000);
        }
      },
      {
        pattern: bot.utterances.no,
        default:true,
        callback: function(response,convo) {
          convo.say("*Phew!*");
          convo.next();
        }
      }
    ])
  })
})

controller.hears(['uptime','identify yourself','who are you','what is your name'],'direct_message,direct_mention,mention',function(bot,message) {

  var hostname = os.hostname();
  var uptime = formatUptime(process.uptime());

  bot.reply(message,':robot_face: I am a bot named <@' + bot.identity.name +'>. I have been running for ' + uptime + ' on ' + hostname + ".");

})

function formatUptime(uptime) {
  var unit = 'second';
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'minute';
  }
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'hour';
  }
  if (uptime != 1) {
    unit = unit +'s';
  }

  uptime = uptime + ' ' + unit;
  return uptime;
}

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

//ONE ACROSS
controller.hears(['!OA (.*) ([a-zA-Z0-9?]*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!OA (.*) ([a-zA-Z0-9?]*)/i);

  var definition = matches[1];
  var constraint = matches[2];

  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processWords(words){
        if (words[words.length-1]=='B???'){
          words.pop();
          words.pop();
        }
        bot.reply(message,"Results: " + words.join(', '));
      }
      getOneAcross(definition, constraint, processWords);
    })
  })
});

//NUTRIMATIC
controller.hears(['!NM (.*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!NM (.*)/i);
  //console.log(matches);
  var query = matches[1];
  //console.log(query);
  query = query.replace(/</g,"<");
  query = query.replace(/>/g,">");
  query = query.replace(/ /g,"%20");
  query = query.replace(/\*/g,"%2A");
  //query = query.replace(/"/g,"%22");
  //query = encodeURI(query);
  query = query.replace(/&/g,"%26");
  query = query.replace(/&/g,"%26");
  query = query.replace(/#/g,"%23");
  query = query.replace(/“/g,'"');
  query = query.replace(/”/g,'"');
  console.log(query);
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processQuery(query){
        numResults = 5;
        random_num = Math.random();
        if (random_num < 0.01) {
          bot.reply(message,"All your base are belong to us.");
        } else if (random_num < 0.02) {
          bot.reply(message,"Please welcome your new bot masters.");
        }

        if (query.length < numResults){
          numResults = query.length;
        }
        if (numResults > 0) {
          bot.reply(message,"Top five results: " + query.slice(0,numResults).join(', '));
        }
        else {
          bot.reply(message,"No good results. Ask Ricky.");
        }
      }
      getNutrimatic(query, processQuery);
    })
  })
});

<commit_msg>lengthen sleep<commit_after>/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          ______     ______     ______   __  __     __     ______
          /\  == \   /\  __ \   /\__  _\ /\ \/ /    /\ \   /\__  _\
          \ \  __<   \ \ \/\ \  \/_/\ \/ \ \  _"-.  \ \ \  \/_/\ \/
          \ \_____\  \ \_____\    \ \_\  \ \_\ \_\  \ \_\    \ \_\
           \/_____/   \/_____/     \/_/   \/_/\/_/   \/_/     \/_/

This is a sample Slack bot built with Botkit.

This bot demonstrates many of the core features of Botkit:

* Connect to Slack using the real time API
* Receive messages based on "spoken" patterns
* Reply to messages
* Use the conversation system to ask questions
* Use the built in storage system to store and retrieve information
  for a user.

# RUN THE BOT:

  Get a Bot token from Slack:

    -> http://my.slack.com/services/new/bot

  Run your bot from the command line:

    token=<MY TOKEN> node bot.js

# USE THE BOT:

  Find your bot inside Slack to send it a direct message.

  Say: "Hello"

  The bot will reply "Hello!"

  Say: "who are you?"

  The bot will tell you its name, where it running, and for how long.

  Say: "Call me <nickname>"

  Tell the bot your nickname. Now you are friends.

  Say: "who am I?"

  The bot will tell you your nickname, if it knows one for you.

  Say: "shutdown"

  The bot will ask if you are sure, and then shut itself down.

  Make sure to invite your bot into other channels using /invite @<my bot>!

# EXTEND THE BOT:

  Botkit is has many features for building cool and useful bots!

  Read all about it here:

    -> http://howdy.ai/botkit

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
//AVOID HEROKU BINDING ERROR
var Botkit = require('./lib/Botkit.js')
var os = require('os');
var http = require('follow-redirects').http;
var cheerio = require('cheerio');
var request = require('request');
var StringDecoder = require('string_decoder').StringDecoder;
var url = require('url');
function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}
http.createServer(function (req, res) {
  if (req.method == 'POST') {
        console.log("POST");
        var body = '';
        console.log(JSON.stringify(req.headers));
        req.on('data', function (data) {
            body += data;
            console.log("Partial body: " + body);
        });
        req.on('end', function () {
            console.log("Body: " + body);
            body_dict = url.parse('http://www.foo.com/?'+body,true);
            channel_id = body_dict.query.channel_id;
            channel_name = body_dict.query.channel_name;
            text = body_dict.query.text;
            new_channel_name = text + '-' + channel_name;
            slack_token = process.env.slack_token;
            //url_change_name = '?token=&channel='+channel_id+'&name='+new_channel_name+'&pretty=1'
            request.post(
                'https://slack.com/api/channels.rename?token='+slack_token+'&channel='+ channel_id +'&name='+new_channel_name+'&pretty=1',
                {},
                function (error, response, body) {
                    if (!error && response.statusCode == 200) {
                        console.log(body)
                    }
                }
            );

        });
        res.writeHead(200, {'Content-Type': 'text/html'});
        res.end('post received');
    }
    else
    {
        console.log("GET");
        console.log(JSON.stringify(req.headers));
        var query_data = url.parse(req.url, true).query;
        var channel_id = query_data.channel_id;
        var channel_name = query_data.channel_name;
        var text = query_data.text;
        var new_channel_name = text + '-' + channel_name;
        var slack_token = process.env.slack_token;
        var excluded_channels = ['C0J3T86TY','C0J3T1ZMY', 'C0J6A8PF1','C0J44SUJD']
        var mutable = true
        for (var i = 0; i < excluded_channels.length; i++) {
          if (excluded_channels[i] === channel_id) {
            mutable = false;
          }
        }
        if (mutable){
          //url_change_name = '?token=&channel='+channel_id+'&name='+new_channel_name+'&pretty=1'
          request.post(
              'https://slack.com/api/chat.postMessage?token='+slack_token+'&channel='+ channel_id +'&text=http://45.media.tumblr.com/tumblr_m5br53wRjA1rpugqso1_250.gif&pretty=1',
              {},
              function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                      console.log("Success!")
                  }
              }
          );
          sleep(3000);
          request.post(
              'https://slack.com/api/channels.rename?token='+slack_token+'&channel='+ channel_id +'&name='+new_channel_name+'&pretty=1',
              {},
              function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                      console.log("Success!")
                  }
              }
          );
          request.post(
              'https://slack.com/api/channels.archive?token='+slack_token+'&channel='+ channel_id +'&pretty=1',
              {},
              function (error, response, body) {
                  if (!error && response.statusCode == 200) {
                      console.log("Success!")
                  }
              }
          );
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end('post received');
        }
        else {
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end("You can't solve this channel");
        }

    }
}).listen(process.env.PORT || 5000);
//END AVOIDANCE

function getOneAcross(def,cons, cb){
  var options = {
    host: 'www3.oneacross.com',
    path: '/cgi-bin/search_banner.cgi?c0='+encodeURIComponent(def)+'&p0='+ encodeURIComponent(cons)+'&s=+Go%21+'
  };
  console.log(def);
  console.log(cons);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    // Buffer the body entirely for processing as a whole.
    var bodyChunks = [];
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      bodyChunks.push(chunk);
    });
    res.on('end', function() {
      var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      var words = [];
      $('tt').each(function(i, elem) {
        // var thisWord = $(this).text();
        var starEmoji = ":star:";
        var stars = 0;
        $(this).parent().siblings().first().children().each(function(i, elem) {
          if ($(this).attr('src')=="/images/smallstarblack.gif"){
            stars++;
          }
        });
        // console.log(thisWord + ' ' + stars);

        words.push(starEmoji.repeat(stars) + $(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

function getNutrimatic(query, cb){
  var options = {
    host: 'www.nutrimatic.org',
    path: '/?q='+query
  };
  console.log(query);
  var result ='';
  var req = http.get(options, function(res) {
    console.log('STATUS: ' + res.statusCode);
    console.log('HEADERS: ' + JSON.stringify(res.headers));
    //console.log('Body: ' + res.body);
    // Buffer the body entirely for processing as a whole.
    var body ='';
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      // You can process streamed parts here...
      //var textChunk = decoder.write(chunk);
      body = body.concat(chunk);
      //console.log(chunk);
    });
    res.on('end', function() {
      //console.log(body);
      // var body = Buffer.concat(bodyChunks);
      $ = cheerio.load(body);
      //console.log(body);
      var words = [];
      $('span').each(function(i, elem) {
        words.push($(this).text());
      });
      cb(words);
    })
  });
  req.on('error', function(e) {
    console.log('ERROR: ' + e.message);
    return "fail";
  });

  return result;
}

var controller = Botkit.slackbot({
  debug: false,
});

var bot = controller.spawn(
  {
    token:process.env.token
  }
).startRTM();

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

controller.hears(['call me (.*)'],'direct_message,direct_mention,mention',function(bot,message) {
  var matches = message.text.match(/call me (.*)/i);
  var output = '';
  for (var i = 0; i < matches.length; i++) {
    output = output.concat(i, matches[i]);
  }
  var name = matches[1];
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    user.name = name;
    controller.storage.users.save(user,function(err,id) {
      bot.reply(message,"Got it. I will call you " + output + " from now on.");
    })
  })
});

controller.hears(['what is my name','who am i'],'direct_message,direct_mention,mention',function(bot,message) {

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Your name is " + user.name);
    } else {
      bot.reply(message,"I don't know yet!");
    }
  })
});

controller.hears(['shutdown'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.startConversation(message,function(err,convo) {
    convo.ask("Are you sure you want me to shutdown?",[
      {
        pattern: bot.utterances.yes,
        callback: function(response,convo) {
          convo.say("Bye!");
          convo.next();
          setTimeout(function() {
            process.exit();
          },3000);
        }
      },
      {
        pattern: bot.utterances.no,
        default:true,
        callback: function(response,convo) {
          convo.say("*Phew!*");
          convo.next();
        }
      }
    ])
  })
})

controller.hears(['uptime','identify yourself','who are you','what is your name'],'direct_message,direct_mention,mention',function(bot,message) {

  var hostname = os.hostname();
  var uptime = formatUptime(process.uptime());

  bot.reply(message,':robot_face: I am a bot named <@' + bot.identity.name +'>. I have been running for ' + uptime + ' on ' + hostname + ".");

})

function formatUptime(uptime) {
  var unit = 'second';
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'minute';
  }
  if (uptime > 60) {
    uptime = uptime / 60;
    unit = 'hour';
  }
  if (uptime != 1) {
    unit = unit +'s';
  }

  uptime = uptime + ' ' + unit;
  return uptime;
}

controller.hears(['hello','hi'],'direct_message,direct_mention,mention',function(bot,message) {

  bot.api.reactions.add({
    timestamp: message.ts,
    channel: message.channel,
    name: 'robot_face',
  },function(err,res) {
    if (err) {
      bot.botkit.log("Failed to add emoji reaction :(",err);
    }
  });

  controller.storage.users.get(message.user,function(err,user) {
    if (user && user.name) {
      bot.reply(message,"Hello " + user.name+"!!");
    } else {
      bot.reply(message,"Hello.");
    }
  });
})

//ONE ACROSS
controller.hears(['!OA (.*) ([a-zA-Z0-9?]*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!OA (.*) ([a-zA-Z0-9?]*)/i);

  var definition = matches[1];
  var constraint = matches[2];

  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processWords(words){
        if (words[words.length-1]=='B???'){
          words.pop();
          words.pop();
        }
        bot.reply(message,"Results: " + words.join(', '));
      }
      getOneAcross(definition, constraint, processWords);
    })
  })
});

//NUTRIMATIC
controller.hears(['!NM (.*)'],'direct_message,direct_mention,mention,ambient',function(bot,message) {
  var matches = message.text.match(/!NM (.*)/i);
  //console.log(matches);
  var query = matches[1];
  //console.log(query);
  query = query.replace(/</g,"<");
  query = query.replace(/>/g,">");
  query = query.replace(/ /g,"%20");
  query = query.replace(/\*/g,"%2A");
  //query = query.replace(/"/g,"%22");
  //query = encodeURI(query);
  query = query.replace(/&/g,"%26");
  query = query.replace(/&/g,"%26");
  query = query.replace(/#/g,"%23");
  query = query.replace(/“/g,'"');
  query = query.replace(/”/g,'"');
  console.log(query);
  controller.storage.users.get(message.user,function(err,user) {
    if (!user) {
      user = {
        id: message.user,
      }
    }
    controller.storage.users.save(user,function(err,id) {
      function processQuery(query){
        numResults = 5;
        random_num = Math.random();
        if (random_num < 0.01) {
          bot.reply(message,"All your base are belong to us.");
        } else if (random_num < 0.02) {
          bot.reply(message,"Please welcome your new bot masters.");
        }

        if (query.length < numResults){
          numResults = query.length;
        }
        if (numResults > 0) {
          bot.reply(message,"Top five results: " + query.slice(0,numResults).join(', '));
        }
        else {
          bot.reply(message,"No good results. Ask Ricky.");
        }
      }
      getNutrimatic(query, processQuery);
    })
  })
});

<|endoftext|>


<commit_before>var HTTPS = require('https');
var FS = require('fs')
//Load all the config variables
var botID = process.env.BOT_ID;
var name1 = process.env.name;
var name2 = process.env.alternate_name;
var error = process.env.error;

//Contains method to check if another string lies in this string
String.prototype.contains = String.prototype.contains ||
function(str){
    return this.indexOf(str)!= -1;
};

aliases = load_aliases();

function load_aliases() {
    members =

    // WRITE THIS FUNCTION
}

function setAlias(nickname, alias) {
    var options, body, botReq;

    options = {
        hostname: 'api.groupme.com',
        path: '/v3/groups/8717323',
        method: 'GET'
    };
    //if response is long, replace the 1000th character with an elipsis and send it
    body = {};

    botReq = HTTPS.request(options, function(res) {
        if(res.statusCode == 200) {
            res.on('data', function(data) {
                var aliases = JSON.parse(fs.readFile("aliases.json"));
                postMessage(nickname + " is now " + alias + "! ;)");

                var user_id;
                var valid_user = false;
                for (var i = 0; i < data["members"].length; i++) {
                    if (nickname == data["members"][i]["nickname"]) {
                        user_id = data["members"][i]["user_id"];
                        valid_user = true;
                    }
                }
                if (valid_user) {
                    aliases[alias] = user_id;
                }

                var new_aliases = JSON.stringify(object)
                fs.writeFile("aliases.json", new_aliases);
            });
        } else {
            postMessage("Could not set alias of " + nickname + " to " + alias + ". Try again! :(");
        }
    });
}

function respond() {
    var request = JSON.parse(this.req.chunks[0]);
    var message = "";
    //default responses for the dogbot
    var barks = ["woof", "woof woof", "ruff", "ruff ruff", "arf", "arf arf", "bow wow", "yap", "yap yap", "yip", "yip yip", "wuff", "wuff wuff", "wau", "wau wau", "hev", "hev hev", "hav", "hav hav", "guau-guau", "gua", "gua gua","jau","jau jau", "blaf", "blaf blaf", "woef", "woef woef", "keff", "keff keff", "gav", "gav gav", "tyav", "tyav tyav", "meong", "meong meong", "wan", "wan-wan", "kyan", "kyan-kyan", "bau", "bau bau", "bow", "bow bow", "voff", "voff voff", "blaf", "blaf blaf", "kef", "kef kef", "waf", "waf waf", "woef", "woef woef", "vov", "vuf", "wang", "wang wang", "ham", "ham ham", "waouh", "waouh waouh", "ouah", "ouah ouah", "ouaf", "ouaf ouaf", "vaf", "vaf vaf", "wouf", "wouf wouf", "wouaf", "wouaf wouaf", "jappe", "jappe jappe", "💩", "💩💩", "💩💩💩", "💩💩💩💩", "💩💩💩💩💩", "💩💩💩💩💩💩", "💩💩💩💩💩💩💩", "😀", "😁", "😂", "😃", "😄", "😅", "😆", "😇", "😉", "😊", "☺", "😋", "😌", "😍", "😎", "😏", "😐", "😑", "😒", "😓", "😔", "😕", "😖", "😗", "😘", "😚", "😛", "😜", "😝", "😞", "😟", "😠", "😡", "😢", "😣", "😤", "😈", "👿", "😥", "😦", "😧", "😨", "😩", "😪", "😫", "😬", "😭", "😮", "😯", "😰", "😱", "😲", "😳", "😴", "😴😴😴", "😴😴", "😵", "😶", "😷", "👣", "👣👣", "👣👣👣", "👣👣👣👣", "👏", "👏👏", "👏👏👏", "👅👅👅👅👅", "👅👅👅👅", "👅👅👅", "👅👅", "👅", "👍", "👎", "👌", "🙏", "🐶", "💦🌱", "💦🌾", "💦🌲", "💦🌳", "💦🌴", "💦🌵", "💦🌵🌵", "💦🌵🌵🌵", "💦🌵🌵🌵🌵", "💦🌵🌵🌵🌵🌵", "🍖", "🍗", "🍚", "🍼", "🎾", "⚽", "🏀", "🏈", "⚾", "💤", "📬"];
    var aliases = JSON.parse(fs.readFile("aliases.json"));

    // sets alias
    if (request.text.toLowerCase().contains("set alias")) {
        var components = request.text.split(" ");
        var nickname = "";
        var alias = "";
        for (var i = 0; i < components.length - 2; i++) {
            var component = components[i];
            if (component == "alias") {
                nickname = components[i+1];
                alias = components[i+2];
            }
        }

        if (alias != "") {
            setAlias(nickname, alias);
        }
    }

    // checks if message contains alias
    var contains_alias = false;
    for (var alias in aliases) {
        if request.text.contains(alias) {
           contains_alias = true;
        }
    }
    // substitutes all aliases in
    if (contains_alias) {
        var message = request.text;
        var attachments = {};
        attachments["loci"] = [];
        attachments["type"] = "mentions";
        attachments["user_ids"] = [];
        for (var alias in aliases) {
            if request.text.contains(alias) {
                this.res.writeHead(200);

                var indices = {message.indexOf(alias), alias.length};
                attachments["loci"].push(indices);
                attachments["user_ids"].push(aliases[alias]);
                message = message.replace(alias, "@" + aliases[alias]);
            }
        }

        postMessageWithAttachments(message, attachments);
    }

    if((request.text.contains(name1)|| request.text.contains(name2) )&& request.text.contains("fetch")) {
        //if the user types the bot's name and fetch, fetch RSS feeds they want
        //Currently supports headlines from Any Subreddit, Al Jazeera, and QZ
        this.res.writeHead(200);
        var reddit = require("./rss.js");
        if(request.text.toLowerCase().contains("al jazeera")){
            reddit.rss_feed("http://america.aljazeera.com/content/ajam/articles.rss", "Fetching news from http://america.aljazeera.com/ :", 10, function(str){
                            postMessage(str);
                            });
        }else if(request.text.contains("qz")){
            reddit.rss_feed("http://qz.com/popular/feed", "Fetching news from http://qz.com/popular :", 10, function(str){
                            postMessage(str);
                            });
        }else if(request.text.contains("r/")){
            var sub = request.text.replace(name1, "");
            sub = sub.replace(name2, "");
            sub = sub.replace("r/", "");
            sub = sub.replace("fetch", "");
            sub = sub.replace(" ", "");
            sub = sub.trim();
            reddit.rss_feed("https://www.reddit.com/r/"+sub+"/top.rss", "Fetching news from https://m.reddit.com/r/"+sub+"/top :", 10, function(str){
                            postMessage(str);
                            });
        }
        this.res.end();
    }
    else if(request.text.contains(name1)||request.text.contains(name2) ) {
        this.res.writeHead(200);
        //run the Rnadom Selector method if there is an or in the text
        if(request.text.contains(" or ")){
            message = choose(request.text);
        }/*
          Example of custom response based on the user_id who sent the message
          else if(request.sender_id== 1234567890){
          message = "";
          }
          */
        //if there is no message choose a random bark
        if(message=="")
            message = barks[random(barks.length)-1];
        postMessage(message+" @"+request.name+" ");
        this.res.end();
    } else {
        //all other messages are ignored
        this.res.writeHead(200);
        this.res.end();
    }
}
//Function for randomly choosing an option
//Usage: @dogbot Smash Bros, FIFA 15, or NBA?
//@dogbot: Smash Bros
function choose(text){
    //remove everything but keyowards
    text = text.replace(name1, "");
    text = text.replace(name2, "");
    text = text.replace("?", "");
    text = text.replace("or", ",");
    //trim all extra unnecessary spaces
    text = text.replace(/\s+/g,' ').trim();
    //split the options into an array
    var array = text.split(',');
    var empty = true;
    //check if the array is empty, prevents an infinite loop when trying to get a nonempty option
    for(var j = 0; j < array.length; j++)
        if(array[j].trim()!="")
            empty = false;

    if(empty)
        return error;
    var i = 0;
    do{
        i = random(array.length)-1;
    }while(array[i].trim()=="");
    //return a space-trimemed version of the option
    return array[i].trim();
}

//simple random function
function random(num){
    return Math.floor((Math.random() * num) + 1);
}

// sorry DRY but I was lazy
function postMessageWithAttachments(response, attachments) {
    var options, body, botReq;

    options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
    };
    //if response is long, replace the 1000th character with an elipsis and send it
    response = response.length > 1000 ? response.substring(0,1000-1)+'…' : response;
    body = {
        "bot_id" : botID,
        "text" : response,
        "attachments": attachments,
    };

    botReq = HTTPS.request(options, function(res) {
                           if(res.statusCode == 202) {
                           //message has been sent
                           } else {
                           console.log('rejecting bad status code ' + res.statusCode);
                           }
                           });

    botReq.on('error', function(err) {
              console.log('error posting message '  + JSON.stringify(err));
              });
    botReq.on('timeout', function(err) {
              console.log('timeout posting message '  + JSON.stringify(err));
              });
    botReq.end(JSON.stringify(body));
}

//post message to the group
function postMessage(response) {
    var options, body, botReq;

    options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
    };
    //if response is long, replace the 1000th character with an elipsis and send it
    response = response.length > 1000 ? response.substring(0,1000-1)+'…' : response;
    body = {
        "bot_id" : botID,
        "text" : response
    };

    botReq = HTTPS.request(options, function(res) {
                           if(res.statusCode == 202) {
                           //message has been sent
                           } else {
                           console.log('rejecting bad status code ' + res.statusCode);
                           }
                           });

    botReq.on('error', function(err) {
              console.log('error posting message '  + JSON.stringify(err));
              });
    botReq.on('timeout', function(err) {
              console.log('timeout posting message '  + JSON.stringify(err));
              });
    botReq.end(JSON.stringify(body));
}

exports.respond = respond;
exports.postMessage = postMessage;
exports.random = random;<commit_msg>bug fix<commit_after>var HTTPS = require('https');
var FS = require('fs')
//Load all the config variables
var botID = process.env.BOT_ID;
var name1 = process.env.name;
var name2 = process.env.alternate_name;
var error = process.env.error;

//Contains method to check if another string lies in this string
String.prototype.contains = String.prototype.contains ||
function(str){
    return this.indexOf(str)!= -1;
};

function setAlias(nickname, alias) {
    var options, body, botReq;

    options = {
        hostname: 'api.groupme.com',
        path: '/v3/groups/8717323',
        method: 'GET'
    };
    //if response is long, replace the 1000th character with an elipsis and send it
    body = {};

    botReq = HTTPS.request(options, function(res) {
        if(res.statusCode == 200) {
            res.on('data', function(data) {
                var aliases = JSON.parse(fs.readFile("aliases.json"));
                postMessage(nickname + " is now " + alias + "! ;)");

                var user_id;
                var valid_user = false;
                for (var i = 0; i < data["members"].length; i++) {
                    if (nickname == data["members"][i]["nickname"]) {
                        user_id = data["members"][i]["user_id"];
                        valid_user = true;
                    }
                }
                if (valid_user) {
                    aliases[alias] = user_id;
                }

                var new_aliases = JSON.stringify(object)
                fs.writeFile("aliases.json", new_aliases);
            });
        } else {
            postMessage("Could not set alias of " + nickname + " to " + alias + ". Try again! :(");
        }
    });
}

function respond() {
    var request = JSON.parse(this.req.chunks[0]);
    var message = "";
    //default responses for the dogbot
    var barks = ["woof", "woof woof", "ruff", "ruff ruff", "arf", "arf arf", "bow wow", "yap", "yap yap", "yip", "yip yip", "wuff", "wuff wuff", "wau", "wau wau", "hev", "hev hev", "hav", "hav hav", "guau-guau", "gua", "gua gua","jau","jau jau", "blaf", "blaf blaf", "woef", "woef woef", "keff", "keff keff", "gav", "gav gav", "tyav", "tyav tyav", "meong", "meong meong", "wan", "wan-wan", "kyan", "kyan-kyan", "bau", "bau bau", "bow", "bow bow", "voff", "voff voff", "blaf", "blaf blaf", "kef", "kef kef", "waf", "waf waf", "woef", "woef woef", "vov", "vuf", "wang", "wang wang", "ham", "ham ham", "waouh", "waouh waouh", "ouah", "ouah ouah", "ouaf", "ouaf ouaf", "vaf", "vaf vaf", "wouf", "wouf wouf", "wouaf", "wouaf wouaf", "jappe", "jappe jappe", "💩", "💩💩", "💩💩💩", "💩💩💩💩", "💩💩💩💩💩", "💩💩💩💩💩💩", "💩💩💩💩💩💩💩", "😀", "😁", "😂", "😃", "😄", "😅", "😆", "😇", "😉", "😊", "☺", "😋", "😌", "😍", "😎", "😏", "😐", "😑", "😒", "😓", "😔", "😕", "😖", "😗", "😘", "😚", "😛", "😜", "😝", "😞", "😟", "😠", "😡", "😢", "😣", "😤", "😈", "👿", "😥", "😦", "😧", "😨", "😩", "😪", "😫", "😬", "😭", "😮", "😯", "😰", "😱", "😲", "😳", "😴", "😴😴😴", "😴😴", "😵", "😶", "😷", "👣", "👣👣", "👣👣👣", "👣👣👣👣", "👏", "👏👏", "👏👏👏", "👅👅👅👅👅", "👅👅👅👅", "👅👅👅", "👅👅", "👅", "👍", "👎", "👌", "🙏", "🐶", "💦🌱", "💦🌾", "💦🌲", "💦🌳", "💦🌴", "💦🌵", "💦🌵🌵", "💦🌵🌵🌵", "💦🌵🌵🌵🌵", "💦🌵🌵🌵🌵🌵", "🍖", "🍗", "🍚", "🍼", "🎾", "⚽", "🏀", "🏈", "⚾", "💤", "📬"];
    var aliases = JSON.parse(fs.readFile("aliases.json"));

    // sets alias
    if (request.text.toLowerCase().contains("set alias")) {
        var components = request.text.split(" ");
        var nickname = "";
        var alias = "";
        for (var i = 0; i < components.length - 2; i++) {
            var component = components[i];
            if (component == "alias") {
                nickname = components[i+1];
                alias = components[i+2];
            }
        }

        if (alias != "") {
            setAlias(nickname, alias);
        }
    }

    // checks if message contains alias
    var contains_alias = false;
    for (var alias in aliases) {
        if request.text.contains(alias) {
           contains_alias = true;
        }
    }
    // substitutes all aliases in
    if (contains_alias) {
        var message = request.text;
        var attachments = {};
        attachments["loci"] = [];
        attachments["type"] = "mentions";
        attachments["user_ids"] = [];
        for (var alias in aliases) {
            if request.text.contains(alias) {
                this.res.writeHead(200);

                var indices = {message.indexOf(alias), alias.length};
                attachments["loci"].push(indices);
                attachments["user_ids"].push(aliases[alias]);
                message = message.replace(alias, "@" + aliases[alias]);
            }
        }

        postMessageWithAttachments(message, attachments);
    }

    if((request.text.contains(name1)|| request.text.contains(name2) )&& request.text.contains("fetch")) {
        //if the user types the bot's name and fetch, fetch RSS feeds they want
        //Currently supports headlines from Any Subreddit, Al Jazeera, and QZ
        this.res.writeHead(200);
        var reddit = require("./rss.js");
        if(request.text.toLowerCase().contains("al jazeera")){
            reddit.rss_feed("http://america.aljazeera.com/content/ajam/articles.rss", "Fetching news from http://america.aljazeera.com/ :", 10, function(str){
                            postMessage(str);
                            });
        }else if(request.text.contains("qz")){
            reddit.rss_feed("http://qz.com/popular/feed", "Fetching news from http://qz.com/popular :", 10, function(str){
                            postMessage(str);
                            });
        }else if(request.text.contains("r/")){
            var sub = request.text.replace(name1, "");
            sub = sub.replace(name2, "");
            sub = sub.replace("r/", "");
            sub = sub.replace("fetch", "");
            sub = sub.replace(" ", "");
            sub = sub.trim();
            reddit.rss_feed("https://www.reddit.com/r/"+sub+"/top.rss", "Fetching news from https://m.reddit.com/r/"+sub+"/top :", 10, function(str){
                            postMessage(str);
                            });
        }
        this.res.end();
    }
    else if(request.text.contains(name1)||request.text.contains(name2) ) {
        this.res.writeHead(200);
        //run the Rnadom Selector method if there is an or in the text
        if(request.text.contains(" or ")){
            message = choose(request.text);
        }/*
          Example of custom response based on the user_id who sent the message
          else if(request.sender_id== 1234567890){
          message = "";
          }
          */
        //if there is no message choose a random bark
        if(message=="")
            message = barks[random(barks.length)-1];
        postMessage(message+" @"+request.name+" ");
        this.res.end();
    } else {
        //all other messages are ignored
        this.res.writeHead(200);
        this.res.end();
    }
}
//Function for randomly choosing an option
//Usage: @dogbot Smash Bros, FIFA 15, or NBA?
//@dogbot: Smash Bros
function choose(text){
    //remove everything but keyowards
    text = text.replace(name1, "");
    text = text.replace(name2, "");
    text = text.replace("?", "");
    text = text.replace("or", ",");
    //trim all extra unnecessary spaces
    text = text.replace(/\s+/g,' ').trim();
    //split the options into an array
    var array = text.split(',');
    var empty = true;
    //check if the array is empty, prevents an infinite loop when trying to get a nonempty option
    for(var j = 0; j < array.length; j++)
        if(array[j].trim()!="")
            empty = false;

    if(empty)
        return error;
    var i = 0;
    do{
        i = random(array.length)-1;
    }while(array[i].trim()=="");
    //return a space-trimemed version of the option
    return array[i].trim();
}

//simple random function
function random(num){
    return Math.floor((Math.random() * num) + 1);
}

// sorry DRY but I was lazy
function postMessageWithAttachments(response, attachments) {
    var options, body, botReq;

    options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
    };
    //if response is long, replace the 1000th character with an elipsis and send it
    response = response.length > 1000 ? response.substring(0,1000-1)+'…' : response;
    body = {
        "bot_id" : botID,
        "text" : response,
        "attachments": attachments,
    };

    botReq = HTTPS.request(options, function(res) {
                           if(res.statusCode == 202) {
                           //message has been sent
                           } else {
                           console.log('rejecting bad status code ' + res.statusCode);
                           }
                           });

    botReq.on('error', function(err) {
              console.log('error posting message '  + JSON.stringify(err));
              });
    botReq.on('timeout', function(err) {
              console.log('timeout posting message '  + JSON.stringify(err));
              });
    botReq.end(JSON.stringify(body));
}

//post message to the group
function postMessage(response) {
    var options, body, botReq;

    options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
    };
    //if response is long, replace the 1000th character with an elipsis and send it
    response = response.length > 1000 ? response.substring(0,1000-1)+'…' : response;
    body = {
        "bot_id" : botID,
        "text" : response
    };

    botReq = HTTPS.request(options, function(res) {
                           if(res.statusCode == 202) {
                           //message has been sent
                           } else {
                           console.log('rejecting bad status code ' + res.statusCode);
                           }
                           });

    botReq.on('error', function(err) {
              console.log('error posting message '  + JSON.stringify(err));
              });
    botReq.on('timeout', function(err) {
              console.log('timeout posting message '  + JSON.stringify(err));
              });
    botReq.end(JSON.stringify(body));
}

exports.respond = respond;
exports.postMessage = postMessage;
exports.random = random;<|endoftext|>


<commit_before>// Our Twitter library
var request = require('request');
var cheerio = require('cheerio');
var _ = require('underscore.deferred');
var Twit = require('twit');
var moment = require('moment');
var fs = require('fs');
moment().format();

// We need to include our configuration file
var T = new Twit(require('./config.js'));

var tweets = [];
var debug = false;

function composeTweet(event, eventType) {
	var tweetText = event;
	if (eventType == "Event") {
		tweetText = tweetText.substr(0,(tweetText.length)-1); // Events typically end in a period, which we don't want in the middle of a tweet
		if (tweetText.length > 93) { // If the tweet will be too long, truncate the event with an ellipsis
			tweetText = tweetText.substr(0,92)+"…";
		}
		tweetText = tweetText + ' occurred closer to the moon landing than today';
	}
	else if (eventType == "Death") {
		if (tweetText.length > 97) { // If the tweet will be too long, truncate the death with an ellipsis
			tweetText = tweetText.substr(0,96 )+"…";
		}
		tweetText = tweetText + ' died closer to the moon landing than today';
	} else if (eventType == "Birth") { // This if statement could be skipped, but it's here for form and parallelism
		if (tweetText.length > 93) { // If the tweet will be too long, truncate the death with an ellipsis
			tweetText = tweetText.substr(0,92 )+"…";
		}
		tweetText = tweetText + ' was born closer to the moon landing than today';
	}
//	console.log(tweetText);
	return(tweetText);
}

function tweetEvent(tweetText) {
	if (debug) {
		console.log(tweetText);
	}
	else {
		T.post('statuses/update', { status: tweetText }, function (err, data, response) {
	//		console.log(err, data);
			if (response) {
	//			console.log('Success! It tweeted an event');
			}
			if (err) {
				console.log('There was an error with Twitter:', error);
			}
		});
	}
}

function getLastTweet() {
	var dfd = new _.Deferred();
	var tweets = [];
	T.get('statuses/home_timeline', {count: 10}, function(err, data, response) {
//		console.log(err, data);
		if (data) {
			for (var exKey in data) {
				tweets.push(data[exKey].text);
			}
			dfd.resolve(tweets);
		}
		if (err) {
			console.log('There was an error fetching tweets:', err);
			dfd.reject();
		}
	});
	return dfd.promise();
}

function parseEvents(eventsJSON, dayToFind) { // This function parses a set of events from the sources in retrieveAllEvents(dayToFind) and dumps out the ones that match the desired year into an array of arrays
	var events = [];
	var deaths = [];
	var births = [];
	var exKey;
	for (exKey in eventsJSON.data.Events) {
		if (eventsJSON.data.Events[exKey].year == dayToFind.get('year')) {
			events.push(eventsJSON.data.Events[exKey].text);
		}
	}
	for (exKey in eventsJSON.data.Deaths) {
		if (eventsJSON.data.Deaths[exKey].year == dayToFind.get('year')) {
			deaths.push(eventsJSONeventsJSON.data.Deaths[exKey].text);
		}
	}
	for (exKey in eventsJSON.data.Births) {
		if (eventsJSON.data.Births[exKey].year == dayToFind.get('year')) {
			births.push(eventsJSON.data.Births[exKey].text);
		}
	}
	return {events: events, deaths: deaths, births: births};
}

function retrieveAllEvents(dayToFind) {
	var dfd = new _.Deferred();
	var allEvents = [];
	var eventsFile = "data/"+dayToFind.format("MM-DD")+".json"; // Local data files have 0 padding of single digit months and dates
	var eventsJSON;
	fs.readFile(eventsFile, function (err, data) { // Try to find a local data file generated using https://github.com/muffinista/history_parse
		if (err) {
			if (err.code === 'ENOENT') { // This checks for a simple file not found, and uses the web as a backup source
				console.log('File not found!');
				var url = "http://history.muffinlabs.com/date/" + dayToFind.format("M/D"); // This site doesn't require 0 padding of months or days
				request({
					url: url,
					json: true
				}, function (error, response, body) {
					if (!error && response.statusCode === 200) {
						allEvents = parseEvents(body,dayToFind);
						if (allEvents.events.length > 0 || allEvents.deaths.length > 0 || allEvents.births.length > 0) {
							dfd.resolve({
								events: allEvents.events,
								deaths: allEvents.deaths,
								births: allEvents.births
							});
						}
						else {
							dfd.reject();
						}
					}
					else {
						console.log("error");
						dfd.reject();
					}
				});
			}
			else  {
				console.log("Something's gone terrible wrong: ",err);
			}
		}
		else {
			allEvents = parseEvents(JSON.parse(data), dayToFind);
			if (allEvents.events.length > 0 || allEvents.deaths.length > 0 || allEvents.births.length > 0) {
				dfd.resolve({
					events: allEvents.events,
					deaths: allEvents.deaths,
					births: allEvents.births
				});
			}
			else {
				dfd.reject();
			}
		}
	});
	return dfd.promise();
}

function getEvent() {
	var today = moment();
	var landing = moment([1969, 6, 20]);
	var dayInHistory = moment();
	var recentTweets = [];
	var listOfEvents = [];
	var tweeted = false;
	var eventToTweet, composedEventToTweet, splicePoint;
	dayInHistory.subtract(Math.ceil(today.diff(landing, 'days')/2), 'days');
//	dayInHistory.subtract(10, 'days'); // Uncomment and edit this line if you need to move the date around for testing
	retrieveAllEvents(dayInHistory).then(function(returnedListOfEvents) {
		getLastTweet().then(function(recentTweets) {
			listOfEvents = returnedListOfEvents;
			while (listOfEvents.events.length > 0 && tweeted === false) {
				eventToTweet = listOfEvents.events[Math.floor(Math.random() * listOfEvents.events.length)];
				composedEventToTweet = composeTweet(eventToTweet, "Event");
				if (recentTweets.indexOf(composedEventToTweet) >= 0) {
					splicePoint = listOfEvents.events.indexOf(eventToTweet);
					listOfEvents.events.splice(splicePoint,1);
				}
				else {
					tweeted = true;
					tweetEvent(composedEventToTweet);
				}
			}
			while (listOfEvents.deaths.length > 0 && tweeted === false) {
				eventToTweet = listOfEvents.deaths[Math.floor(Math.random() * listOfEvents.deaths.length)];
				composedEventToTweet = composeTweet(eventToTweet, "Death");
				if (recentTweets.indexOf(composedEventToTweet) >= 0) {
					splicePoint = listOfEvents.deaths.indexOf(eventToTweet);
					listOfEvents.deaths.splice(splicePoint,1);
				}
				else {
					tweeted = true;
					tweetEvent(composedEventToTweet);
				}
			}
			while (listOfEvents.births.length > 0 && tweeted === false) {
				eventToTweet = listOfEvents.births[Math.floor(Math.random() * listOfEvents.births.length)];
				composedEventToTweet = composeTweet(eventToTweet, "Birth");
				if (recentTweets.indexOf(composedEventToTweet) >= 0) {
					splicePoint = listOfEvents.births.indexOf(eventToTweet);
					listOfEvents.births.splice(splicePoint,1);
				}
				else {
					tweeted = true;
					tweetEvent(composedEventToTweet);
				}
			}
			if (tweeted === false) {
				console.log("I guess there were duplicates today");
			}
		});
	});
}

// Try to retweet something as soon as we run the program...
getEvent();

// This code is originally from dariusk but I'm calling this script daily via cron instead
// ...and then every hour after that. Time here is in milliseconds, so
// 1000 ms = 1 second, 1 sec * 60 = 1 min, 1 min * 60 = 1 hour --> 1000 * 60 * 60
//setInterval(getEvent, 1000 * 60 * 60);
<commit_msg>Corrected a cut and paste error in the deaths array<commit_after>// Our Twitter library
var request = require('request');
var cheerio = require('cheerio');
var _ = require('underscore.deferred');
var Twit = require('twit');
var moment = require('moment');
var fs = require('fs');
moment().format();

// We need to include our configuration file
var T = new Twit(require('./config.js'));

var tweets = [];
var debug = false;

function composeTweet(event, eventType) {
	var tweetText = event;
	if (eventType == "Event") {
		tweetText = tweetText.substr(0,(tweetText.length)-1); // Events typically end in a period, which we don't want in the middle of a tweet
		if (tweetText.length > 93) { // If the tweet will be too long, truncate the event with an ellipsis
			tweetText = tweetText.substr(0,92)+"…";
		}
		tweetText = tweetText + ' occurred closer to the moon landing than today';
	}
	else if (eventType == "Death") {
		if (tweetText.length > 97) { // If the tweet will be too long, truncate the death with an ellipsis
			tweetText = tweetText.substr(0,96 )+"…";
		}
		tweetText = tweetText + ' died closer to the moon landing than today';
	} else if (eventType == "Birth") { // This if statement could be skipped, but it's here for form and parallelism
		if (tweetText.length > 93) { // If the tweet will be too long, truncate the death with an ellipsis
			tweetText = tweetText.substr(0,92 )+"…";
		}
		tweetText = tweetText + ' was born closer to the moon landing than today';
	}
//	console.log(tweetText);
	return(tweetText);
}

function tweetEvent(tweetText) {
	if (debug) {
		console.log(tweetText);
	}
	else {
		T.post('statuses/update', { status: tweetText }, function (err, data, response) {
	//		console.log(err, data);
			if (response) {
	//			console.log('Success! It tweeted an event');
			}
			if (err) {
				console.log('There was an error with Twitter:', error);
			}
		});
	}
}

function getLastTweet() {
	var dfd = new _.Deferred();
	var tweets = [];
	T.get('statuses/home_timeline', {count: 10}, function(err, data, response) {
//		console.log(err, data);
		if (data) {
			for (var exKey in data) {
				tweets.push(data[exKey].text);
			}
			dfd.resolve(tweets);
		}
		if (err) {
			console.log('There was an error fetching tweets:', err);
			dfd.reject();
		}
	});
	return dfd.promise();
}

function parseEvents(eventsJSON, dayToFind) { // This function parses a set of events from the sources in retrieveAllEvents(dayToFind) and dumps out the ones that match the desired year into an array of arrays
	var events = [];
	var deaths = [];
	var births = [];
	var exKey;
	for (exKey in eventsJSON.data.Events) {
		if (eventsJSON.data.Events[exKey].year == dayToFind.get('year')) {
			events.push(eventsJSON.data.Events[exKey].text);
		}
	}
	for (exKey in eventsJSON.data.Deaths) {
		if (eventsJSON.data.Deaths[exKey].year == dayToFind.get('year')) {
			deaths.push(eventsJSON.data.Deaths[exKey].text);
		}
	}
	for (exKey in eventsJSON.data.Births) {
		if (eventsJSON.data.Births[exKey].year == dayToFind.get('year')) {
			births.push(eventsJSON.data.Births[exKey].text);
		}
	}
	return {events: events, deaths: deaths, births: births};
}

function retrieveAllEvents(dayToFind) {
	var dfd = new _.Deferred();
	var allEvents = [];
	var eventsFile = "data/"+dayToFind.format("MM-DD")+".json"; // Local data files have 0 padding of single digit months and dates
	var eventsJSON;
	fs.readFile(eventsFile, function (err, data) { // Try to find a local data file generated using https://github.com/muffinista/history_parse
		if (err) {
			if (err.code === 'ENOENT') { // This checks for a simple file not found, and uses the web as a backup source
				console.log('File not found!');
				var url = "http://history.muffinlabs.com/date/" + dayToFind.format("M/D"); // This site doesn't require 0 padding of months or days
				request({
					url: url,
					json: true
				}, function (error, response, body) {
					if (!error && response.statusCode === 200) {
						allEvents = parseEvents(body,dayToFind);
						if (allEvents.events.length > 0 || allEvents.deaths.length > 0 || allEvents.births.length > 0) {
							dfd.resolve({
								events: allEvents.events,
								deaths: allEvents.deaths,
								births: allEvents.births
							});
						}
						else {
							dfd.reject();
						}
					}
					else {
						console.log("error");
						dfd.reject();
					}
				});
			}
			else  {
				console.log("Something's gone terrible wrong: ",err);
			}
		}
		else {
			allEvents = parseEvents(JSON.parse(data), dayToFind);
			if (allEvents.events.length > 0 || allEvents.deaths.length > 0 || allEvents.births.length > 0) {
				dfd.resolve({
					events: allEvents.events,
					deaths: allEvents.deaths,
					births: allEvents.births
				});
			}
			else {
				dfd.reject();
			}
		}
	});
	return dfd.promise();
}

function getEvent() {
	var today = moment();
	var landing = moment([1969, 6, 20]);
	var dayInHistory = moment();
	var recentTweets = [];
	var listOfEvents = [];
	var tweeted = false;
	var eventToTweet, composedEventToTweet, splicePoint;
	dayInHistory.subtract(Math.ceil(today.diff(landing, 'days')/2), 'days');
//	dayInHistory.subtract(10, 'days'); // Uncomment and edit this line if you need to move the date around for testing
	retrieveAllEvents(dayInHistory).then(function(returnedListOfEvents) {
		getLastTweet().then(function(recentTweets) {
			listOfEvents = returnedListOfEvents;
			while (listOfEvents.events.length > 0 && tweeted === false) {
				eventToTweet = listOfEvents.events[Math.floor(Math.random() * listOfEvents.events.length)];
				composedEventToTweet = composeTweet(eventToTweet, "Event");
				if (recentTweets.indexOf(composedEventToTweet) >= 0) {
					splicePoint = listOfEvents.events.indexOf(eventToTweet);
					listOfEvents.events.splice(splicePoint,1);
				}
				else {
					tweeted = true;
					tweetEvent(composedEventToTweet);
				}
			}
			while (listOfEvents.deaths.length > 0 && tweeted === false) {
				eventToTweet = listOfEvents.deaths[Math.floor(Math.random() * listOfEvents.deaths.length)];
				composedEventToTweet = composeTweet(eventToTweet, "Death");
				if (recentTweets.indexOf(composedEventToTweet) >= 0) {
					splicePoint = listOfEvents.deaths.indexOf(eventToTweet);
					listOfEvents.deaths.splice(splicePoint,1);
				}
				else {
					tweeted = true;
					tweetEvent(composedEventToTweet);
				}
			}
			while (listOfEvents.births.length > 0 && tweeted === false) {
				eventToTweet = listOfEvents.births[Math.floor(Math.random() * listOfEvents.births.length)];
				composedEventToTweet = composeTweet(eventToTweet, "Birth");
				if (recentTweets.indexOf(composedEventToTweet) >= 0) {
					splicePoint = listOfEvents.births.indexOf(eventToTweet);
					listOfEvents.births.splice(splicePoint,1);
				}
				else {
					tweeted = true;
					tweetEvent(composedEventToTweet);
				}
			}
			if (tweeted === false) {
				console.log("I guess there were duplicates today");
			}
		});
	});
}

// Try to retweet something as soon as we run the program...
getEvent();

// This code is originally from dariusk but I'm calling this script daily via cron instead
// ...and then every hour after that. Time here is in milliseconds, so
// 1000 ms = 1 second, 1 sec * 60 = 1 min, 1 min * 60 = 1 hour --> 1000 * 60 * 60
//setInterval(getEvent, 1000 * 60 * 60);
<|endoftext|>


<commit_before>require('./server.js');
var dischord = require('discord.js');

var bot = new dischord.Client({revive: true});

function normalizeCardInput(msg) {
    var lowercaseify = msg.toLowerCase();
    var removeColon = lowercaseify.replace(":", "");
    var output = removeColon.replace(/\s+/g, "-");

    return output;
}

function normalizeItemInput(msg) {
    var lowercaseify = msg.toLowerCase();
    var stripApostrophe = lowercaseify.replace("'", "");
    var output = stripApostrophe.replace(/\s+/g, "-");

    return output;
}

function filetype (file) {
    var jpg = file.endsWith('.jpg');
    var gif = file.endsWith('.gif');

    if (jpg) {
        return ".jpg";
    } else {
        return ".gif";
    };
}

function searchGrimoire() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('8');
        var siteSearch = input.startsWith('!search');

        if(siteSearch) {
            bot.reply(message, "http://www.ishtar-collective.net/search/" + encodeURIComponent(stripeCmd));
        } return
    });
}

function searchCard() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('6');
        var cardSearch = input.startsWith('!card');

        var query = normalizeCardInput(stripeCmd);

        if(cardSearch) {
            bot.reply(message, "http://www.ishtar-collective.net/cards/" + query);
        } return
    });
}

function searchItems() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('6');
        var cardSearch = input.startsWith('!item');

        var query = normalizeItemInput(stripeCmd);

        if(cardSearch) {
            bot.reply(message, "http://www.ishtar-collective.net/items/" + query);
        } return
    });
}

function help() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('6');
        var lowercaseify = stripeCmd.toLowerCase();
        var help = input.startsWith('!lorehelp');

        if(help) {
            bot.sendMessage(message,
            "**LoreBot Help Menu**" +'\n'+'\n'+
            "**__Search Ishtar by Topic__**" +'\n'+
            "**!search** *your search topic*" +'\n'+
            "ex: `!search osiris`" +'\n'+
            "This will return a link such as - ishtar-collective.net/search/osiris" +'\n'+'\n'+
            "**__Pull Card From Ishtar__**" +'\n'+
            "**!search** *exact name of card you want to show in chat*"+'\n'+
            "ex: `!card osiris`" +'\n'+
            "This will return a link to the card, with first 50 or so characters and image of card. If not, then no card name matched your query. The link provided will still take you to Ishtar and give suggestions based on your query." +'\n'+'\n'+
            "**__Pull Item From Ishtar__**" +'\n'+
            "**!item** *item you want to show in chat*" +'\n'+
            "ex: `!item ace of spades`" +'\n'+
            "This will, like the card method, return a link to the item or weapon along with the flavor text and an image of the item. If not, then your search did not match. Follow the link to Ishtar and check if it's suggestions match what you were looking for." +'\n'+'\n'+
            "**__Magic Word__**" +'\n'+
            "Don't do it! Really? I dare ya!" +'\n'+'\n'+
            "**__Display Help Menu__**" +'\n'+
            "`!lorehelp` - Displays this help menu" +'\n'+'\n');
        }return
    });

}

/*function paean() {

    bot.on("message", function(message) {
        var input = message.content;
        var help = /(!help)/;
        var paean = /(paean)/i;
        var poster = message.author.id;
        var checkPoster = '159985870458322944';
        var checkForPaean = input.search(paean) != -1;
        var checkForHelp = input.search(help) != -1;
        var memes = [
            "http://sos.campmobile.net/e/2h28ej_g/he7Ud015a309a37y82it_awsowi.jpg",
            "http://sos.campmobile.net/e/2h28ef_6/bbjUd015pzbbt8dfcbse_hsmjp8.jpg",
            "http://sos.campmobile.net/d/2h204b_e/469Ud0151fl3ky5g3fy6u_o6iq9q.jpg",
            "http://sos.campmobile.net/d/2h28cd_d/2d5Ud015psn7vdj6a3wt_l0ky7l.jpg",
            "http://sos.campmobile.net/d/2h068g_i/3e8Ud0158cjt8r6d5mxb_l0ky7l.jpg",
            "https://cdn.discordapp.com/attachments/143886914326495233/186270379533139979/IMG_0800.GIF"
            ]
        var pick = memes[Math.round(Math.random()*(memes.length-1))];
        var name = pick.substr(40, 5);

        breakMyth: if ( checkPoster === poster ) {
            break breakMyth;
        } else if ( checkForPaean ) {
            bot.reply(message, "That does not return any results. But, I have noticed a pattern. Because I am a genius HE HE HE");
            bot.sendFile( message.channel, pick, name + filetype(pick));
        }
    });
}*/

function quotes (input, message) {

    var query = normalizeItemInput(input.substr('8')).replace(/\s+/g, "-");

    switch (query) {
        case "speaker":
        case "the-speaker":
            var qSpeaker = require('./assets/speaker.js');
            bot.sendMessage(message.channel, "**The Speaker: **" + randomQuote(qSpeaker));
            break;
        case "cayde":
        case "cayde-6":
            var qCayde = require('./assets/cayde.js');
            bot.sendMessage(message.channel, "**Cayde-6: **" + randomQuote(qCayde));
            break;
        case "ikora":
        case "ikora-rey":
            var qIkora = require('./assets/ikora.js');
            bot.sendMessage(message.channel, "**Ikora Rey: **" + randomQuote(qIkora));
            break;
        case "zavala":
        case "commander-zavala":
            var qZavala = require('./assets/zavala.js');
            bot.sendMessage(message.channel, "**Zavala Rey: **" + randomQuote(qZavala));
            break;
        case "xur":
        case "agent-of-the-nine":
        case "agent-of-the-9":
            var qXur = require('./assets/xur.js');
            bot.sendMessage(message.channel, "**Xur: **" + randomQuote(qXur));
            break;
        case "eris":
        case "eris-morn":
            var qEris = require('./assets/eris.js');
            bot.sendMessage(message.channel, "**Eris Morn: **" + randomQuote(qEris));
            break;
        case "ives":
        case "master ives":
        case "reef-cryptarch":
        case "the-reef-cryptarch":
        case "reefs-cryptarch":
        case "the-reefs-cryptarch":
            var qIves = require('./assets/ives.js');
            bot.sendMessage(message.channel, "**Master Ives: **" + randomQuote(qIves));
            break;
        case "mara":
        case "mara-sov":
        case "the-queen":
        case "queen-of-the-reef":
        case "the-queen-of-the-reef":
            var qMara = require('./assets/mara.js');
            bot.sendMessage(message.channel, "**Mara Sov: **" + randomQuote(qMara));
            break;
        case "osiris":
            var qOsiris = require('./assets/osiris.js');
            bot.sendMessage(message.channel, "**Osiris: **" + randomQuote(qOsiris));
            break;
        case "petra":
        case "petra-venj":
            var qPetra = require('./assets/petra.js');
            bot.sendMessage(message.channel, "**Petra Venj: **" + randomQuote(qPetra));
            break;
        case "rahool":
        case "master-rahool":
        case "the-cryptarch":
        case "the-tower-cryptarch":
        case "the-towers-cryptarch":
            var qRahool = require('./assets/rahool.js');
            bot.sendMessage(message.channel, "**Master Rahool: **" + randomQuote(qRahool));
            break;
        default:
            bot.reply(message, "Sorry, either that NPC does not exist or I have not gathered their qoutes just yet. Check your spelling or check back soon.")
    }
}

bot.loginWithToken(process.env.CLIENT_ID, function (token, err) {
    if(err){
        console.log(err);
    }

    searchGrimoire();
    searchCard();
    searchItems();
    help();
    //paean();
    bot.on("message", function (message) {
        var input = message.content;
        var quoteCmd = input.startsWith('!quotes');

        if (quoteCmd) {
            quotes(input,message);
        }
    })

});<commit_msg>add missing method<commit_after>require('./server.js');
var dischord = require('discord.js');

var bot = new dischord.Client({revive: true});

function normalizeCardInput(msg) {
    var lowercaseify = msg.toLowerCase();
    var removeColon = lowercaseify.replace(":", "");
    var output = removeColon.replace(/\s+/g, "-");

    return output;
}

function normalizeItemInput(msg) {
    var lowercaseify = msg.toLowerCase();
    var stripApostrophe = lowercaseify.replace("'", "");
    var output = stripApostrophe.replace(/\s+/g, "-");

    return output;
}

function filetype (file) {
    var jpg = file.endsWith('.jpg');
    var gif = file.endsWith('.gif');

    if (jpg) {
        return ".jpg";
    } else {
        return ".gif";
    };
}

function randomQuote(list) {
    return list[Math.round(Math.random()*(list.length-1))];
}

function searchGrimoire() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('8');
        var siteSearch = input.startsWith('!search');

        if(siteSearch) {
            bot.reply(message, "http://www.ishtar-collective.net/search/" + encodeURIComponent(stripeCmd));
        } return
    });
}

function searchCard() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('6');
        var cardSearch = input.startsWith('!card');

        var query = normalizeCardInput(stripeCmd);

        if(cardSearch) {
            bot.reply(message, "http://www.ishtar-collective.net/cards/" + query);
        } return
    });
}

function searchItems() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('6');
        var cardSearch = input.startsWith('!item');

        var query = normalizeItemInput(stripeCmd);

        if(cardSearch) {
            bot.reply(message, "http://www.ishtar-collective.net/items/" + query);
        } return
    });
}

function help() {
    bot.on("message", function(message) {
        var input = message.content;
        var stripeCmd = input.substr('6');
        var lowercaseify = stripeCmd.toLowerCase();
        var help = input.startsWith('!lorehelp');

        if(help) {
            bot.sendMessage(message,
            "**LoreBot Help Menu**" +'\n'+'\n'+
            "**__Search Ishtar by Topic__**" +'\n'+
            "**!search** *your search topic*" +'\n'+
            "ex: `!search osiris`" +'\n'+
            "This will return a link such as - ishtar-collective.net/search/osiris" +'\n'+'\n'+
            "**__Pull Card From Ishtar__**" +'\n'+
            "**!search** *exact name of card you want to show in chat*"+'\n'+
            "ex: `!card osiris`" +'\n'+
            "This will return a link to the card, with first 50 or so characters and image of card. If not, then no card name matched your query. The link provided will still take you to Ishtar and give suggestions based on your query." +'\n'+'\n'+
            "**__Pull Item From Ishtar__**" +'\n'+
            "**!item** *item you want to show in chat*" +'\n'+
            "ex: `!item ace of spades`" +'\n'+
            "This will, like the card method, return a link to the item or weapon along with the flavor text and an image of the item. If not, then your search did not match. Follow the link to Ishtar and check if it's suggestions match what you were looking for." +'\n'+'\n'+
            "**__Magic Word__**" +'\n'+
            "Don't do it! Really? I dare ya!" +'\n'+'\n'+
            "**__Display Help Menu__**" +'\n'+
            "`!lorehelp` - Displays this help menu" +'\n'+'\n');
        }return
    });

}

/*function paean() {

    bot.on("message", function(message) {
        var input = message.content;
        var help = /(!help)/;
        var paean = /(paean)/i;
        var poster = message.author.id;
        var checkPoster = '159985870458322944';
        var checkForPaean = input.search(paean) != -1;
        var checkForHelp = input.search(help) != -1;
        var memes = [
            "http://sos.campmobile.net/e/2h28ej_g/he7Ud015a309a37y82it_awsowi.jpg",
            "http://sos.campmobile.net/e/2h28ef_6/bbjUd015pzbbt8dfcbse_hsmjp8.jpg",
            "http://sos.campmobile.net/d/2h204b_e/469Ud0151fl3ky5g3fy6u_o6iq9q.jpg",
            "http://sos.campmobile.net/d/2h28cd_d/2d5Ud015psn7vdj6a3wt_l0ky7l.jpg",
            "http://sos.campmobile.net/d/2h068g_i/3e8Ud0158cjt8r6d5mxb_l0ky7l.jpg",
            "https://cdn.discordapp.com/attachments/143886914326495233/186270379533139979/IMG_0800.GIF"
            ]
        var pick = memes[Math.round(Math.random()*(memes.length-1))];
        var name = pick.substr(40, 5);

        breakMyth: if ( checkPoster === poster ) {
            break breakMyth;
        } else if ( checkForPaean ) {
            bot.reply(message, "That does not return any results. But, I have noticed a pattern. Because I am a genius HE HE HE");
            bot.sendFile( message.channel, pick, name + filetype(pick));
        }
    });
}*/

function quotes (input, message) {

    var query = normalizeItemInput(input.substr('8')).replace(/\s+/g, "-");

    switch (query) {
        case "speaker":
        case "the-speaker":
            var qSpeaker = require('./assets/speaker.js');
            bot.sendMessage(message.channel, "**The Speaker: **" + randomQuote(qSpeaker));
            break;
        case "cayde":
        case "cayde-6":
            var qCayde = require('./assets/cayde.js');
            bot.sendMessage(message.channel, "**Cayde-6: **" + randomQuote(qCayde));
            break;
        case "ikora":
        case "ikora-rey":
            var qIkora = require('./assets/ikora.js');
            bot.sendMessage(message.channel, "**Ikora Rey: **" + randomQuote(qIkora));
            break;
        case "zavala":
        case "commander-zavala":
            var qZavala = require('./assets/zavala.js');
            bot.sendMessage(message.channel, "**Zavala Rey: **" + randomQuote(qZavala));
            break;
        case "xur":
        case "agent-of-the-nine":
        case "agent-of-the-9":
            var qXur = require('./assets/xur.js');
            bot.sendMessage(message.channel, "**Xur: **" + randomQuote(qXur));
            break;
        case "eris":
        case "eris-morn":
            var qEris = require('./assets/eris.js');
            bot.sendMessage(message.channel, "**Eris Morn: **" + randomQuote(qEris));
            break;
        case "ives":
        case "master ives":
        case "reef-cryptarch":
        case "the-reef-cryptarch":
        case "reefs-cryptarch":
        case "the-reefs-cryptarch":
            var qIves = require('./assets/ives.js');
            bot.sendMessage(message.channel, "**Master Ives: **" + randomQuote(qIves));
            break;
        case "mara":
        case "mara-sov":
        case "the-queen":
        case "queen-of-the-reef":
        case "the-queen-of-the-reef":
            var qMara = require('./assets/mara.js');
            bot.sendMessage(message.channel, "**Mara Sov: **" + randomQuote(qMara));
            break;
        case "osiris":
            var qOsiris = require('./assets/osiris.js');
            bot.sendMessage(message.channel, "**Osiris: **" + randomQuote(qOsiris));
            break;
        case "petra":
        case "petra-venj":
            var qPetra = require('./assets/petra.js');
            bot.sendMessage(message.channel, "**Petra Venj: **" + randomQuote(qPetra));
            break;
        case "rahool":
        case "master-rahool":
        case "the-cryptarch":
        case "the-tower-cryptarch":
        case "the-towers-cryptarch":
            var qRahool = require('./assets/rahool.js');
            bot.sendMessage(message.channel, "**Master Rahool: **" + randomQuote(qRahool));
            break;
        default:
            bot.reply(message, "Sorry, either that NPC does not exist or I have not gathered their qoutes just yet. Check your spelling or check back soon.")
    }
}

bot.loginWithToken(process.env.CLIENT_ID, function (token, err) {
    if(err){
        console.log(err);
    }

    searchGrimoire();
    searchCard();
    searchItems();
    help();
    //paean();
    bot.on("message", function (message) {
        var input = message.content;
        var quoteCmd = input.startsWith('!quotes');

        if (quoteCmd) {
            quotes(input,message);
        }
    })

});<|endoftext|>


<commit_before>const Discord = require('discord.js');
const bot = new Discord.Client();
const prefix = "!";

bot.on('ready', () => {
        bot.user.setGame('!commands for help');
});

bot.on('message', (message) => {

    if (!message.content.startsWith(prefix)) return;

    var args = message.content.substring(prefix.length).split(" ");
    var query = message.content.substring(6);
    var charLook = message.content.substring(9);

    if (message.channel.id === '334783038162468864') {
        switch (args[0].toLowerCase()) {
            case "commands":
                message.channel.send("The following are the commands used in this channel.");
                message.channel.send({embed: {
                    color: 3447003,
                    fields: [{
                        name: "!aqwchar",
                        value: "Syntax: !aqwchar <Player>\nThis looks up the character page of your desire.",
                    },
                    {
                        name: "!sellback",
                        value: "Syntax: !sellback <Price> <AC/Gold>\nThis tells you the sellback price of the item. AC Items will tell produce 'Before/After 24 Hours' values.",
                    },
                    {
                        name: "!wiki",
                        value: "Syntax: !wiki <query>\nThis searches the AQW wikidot for the query you have inputed.",
                    }]
                }});
            break;
            case "aqwchar":
                var char = charLook.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("http://www.aq.com/character.asp?id=" + char.join("%20"));
                }
                else message.channel.sendMessage("Please specify a name after !aqwchar");
                break;
            case "sellback":
                var price = args[1];
                var curr = args[2];

                function isInt(price) {
                    return !isNaN(price) && price > 0 && (function(price) { return (price | 0) === price; })(parseFloat(price)); }

                if (isInt(price) == true) {
                    if ((/Gold/i).test(curr) == true) {
                        message.channel.sendMessage("The sellback price is** " + Math.ceil(price * 0.25) + " Gold.**");
                    }
                    else if ((/AC/i).test(curr) == true) {
                        message.channel.sendMessage("Before 24 hours: **" + Math.ceil(price * 0.90) + " AC**" + "\nAfter 24 hours: **" + Math.ceil(price * 0.25) + " AC**");
                    }
                    else message.reply("Please use the following syntax: !sellback <Price> <AC/Gold>")
                }
                else if (price > 0 || price == 0) {
                        message.channel.sendMessage("Please enter a non-zero positive integer.");
                }
                else message.channel.sendMessage("That's not a number!");
                break;
            case "wiki":
                var term = query.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("Wiki search: http://aqwwiki.wikidot.com/search:site/q/" + term.join("+")); }
                else message.channel.sendMessage("Please specify what you want to search after !wiki");
                break;
        }
    }

    if (message.channel.id === '334783085512228887') {
        switch (args[0].toLowerCase()) {
            case "commands":
                message.channel.send("The following are the commands used in this channel.");
                message.channel.send({embed: {
                    color: 3447003,
                    fields: [{
                        name: "!3dchar",
                        value: "Syntax: !3dchar <Player>\nThis looks up the character page of your desire.",
                    },
                    {
                        name: "!wiki",
                        value: "Syntax: !wiki <query>\nThis searches the AQ3D wikidot for the query you have inputed.",
                    }]
                }});
            break;
            case "3dchar":
                var char = charLook.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("https://game.aq3d.com/account/Character?id=" + char.join("%20"));
                }
                else message.channel.sendMessage("Please specify a name after !3dchar");
                break;
            case "wiki":
                var term = query.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("Wiki search: http://aq-3d.wikidot.com/search:site/q/" + term.join("%20")); }
                else message.channel.sendMessage("Please specify what you want to search after !wiki");
                break;
        }
    }
});

bot.login(process.env.BOT_TOKEN)<commit_msg>Channel Updated<commit_after>const Discord = require('discord.js');
const bot = new Discord.Client();
const prefix = "!";

bot.on('ready', () => {
        bot.user.setGame('!commands for help');
});

bot.on('message', (message) => {

    if (!message.content.startsWith(prefix)) return;

    var args = message.content.substring(prefix.length).split(" ");
    var query = message.content.substring(6);
    var charLook = message.content.substring(9);

    if (message.channel.id === '334783038162468864') {
        switch (args[0].toLowerCase()) {
            case "commands":
                message.channel.send("The following are the commands used in this channel.");
                message.channel.send({embed: {
                    color: 3447003,
                    fields: [{
                        name: "!aqwchar",
                        value: "Syntax: !aqwchar <Player>\nThis looks up the character page of your desire.",
                    },
                    {
                        name: "!sellback",
                        value: "Syntax: !sellback <Price> <AC/Gold>\nThis tells you the sellback price of the item. AC Items will tell produce 'Before/After 24 Hours' values.",
                    },
                    {
                        name: "!wiki",
                        value: "Syntax: !wiki <query>\nThis searches the AQW wikidot for the query you have inputed.",
                    }]
                }});
            break;
            case "aqwchar":
                var char = charLook.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("http://www.aq.com/character.asp?id=" + char.join("%20"));
                }
                else message.channel.sendMessage("Please specify a name after !aqwchar");
                break;
            case "sellback":
                var price = args[1];
                var curr = args[2];

                function isInt(price) {
                    return !isNaN(price) && price > 0 && (function(price) { return (price | 0) === price; })(parseFloat(price)); }

                if (isInt(price) == true) {
                    if ((/Gold/i).test(curr) == true) {
                        message.channel.sendMessage("The sellback price is** " + Math.ceil(price * 0.25) + " Gold.**");
                    }
                    else if ((/AC/i).test(curr) == true) {
                        message.channel.sendMessage("Before 24 hours: **" + Math.ceil(price * 0.90) + " AC**" + "\nAfter 24 hours: **" + Math.ceil(price * 0.25) + " AC**");
                    }
                    else message.reply("Please use the following syntax: !sellback <Price> <AC/Gold>")
                }
                else if (price > 0 || price == 0) {
                        message.channel.sendMessage("Please enter a non-zero positive integer.");
                }
                else message.channel.sendMessage("That's not a number!");
                break;
            case "wiki":
                var term = query.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("Wiki search: http://aqwwiki.wikidot.com/search:site/q/" + term.join("+")); }
                else message.channel.sendMessage("Please specify what you want to search after !wiki");
                break;
        }
    }

    if (message.channel.id === '355188935900790786') {
        switch (args[0].toLowerCase()) {
            case "commands":
                message.channel.send("The following are the commands used in this channel.");
                message.channel.send({embed: {
                    color: 3447003,
                    fields: [{
                        name: "!3dchar",
                        value: "Syntax: !3dchar <Player>\nThis looks up the character page of your desire.",
                    },
                    {
                        name: "!wiki",
                        value: "Syntax: !wiki <query>\nThis searches the AQ3D wikidot for the query you have inputed.",
                    }]
                }});
            break;
            case "3dchar":
                var char = charLook.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("https://game.aq3d.com/account/Character?id=" + char.join("%20"));
                }
                else message.channel.sendMessage("Please specify a name after !3dchar");
                break;
            case "wiki":
                var term = query.split(" ");
                if (typeof args[1] !== 'undefined') {
                    message.channel.sendMessage("Wiki search: http://aq-3d.wikidot.com/search:site/q/" + term.join("%20")); }
                else message.channel.sendMessage("Please specify what you want to search after !wiki");
                break;
        }
    }
});

bot.login(process.env.BOT_TOKEN)<|endoftext|>


<commit_before>var HTTPS = require('https');
const fs = require('fs');

var botID = process.env.BOT_ID;

function parseResponse() {
  var request = JSON.parse(this.req.chunks[0]),
  //callback trigger probably shouldn't be in the response...
      botRegex = /\@Bo/;

  if(request.text && botRegex.test(request.text)) {
    console.log("Trigger detected: ");
    var botResponse = "";

    switch (true) {
      case (/about|help|who are/.test(request.text)):
        botResponse = buildAbout();
        break;
      case (/weather/.test(request.text)):
        botResponse = buildWeather();
        break;
    }

    this.res.writeHead(200);
    postMessage(botResponse);
    this.res.end();
  } else {
    console.log("No trigger detected.");
    this.res.writeHead(200);
    this.res.end();
  }
}

function buildAbout() {
  console.log("about")
  return fs.readFileSync(__dirname + '/README.md');
}

function buildWeather(request) {
  var arr = request.split(" ");
}

function postMessage(botResponse) {
  var botResponse, options, body, botReq;

  options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
  };

  body = {
    "bot_id" : botID,
    "text" : botResponse
  };

  console.log('sending ' + botResponse + ' to ' + botID);

  botReq = HTTPS.request(options, function(res) {
      if(res.statusCode == 202) {
        //neat
      } else {
        console.log('Response code ' + res.statusCode);
      }
  });

  botReq.on('error', function(err) {
    console.log('Error posting message '  + JSON.stringify(err));
  });
  botReq.on('timeout', function(err) {
    console.log('Timeout posting message '  + JSON.stringify(err));
  });
  botReq.end(JSON.stringify(body));
}

exports.respond = parseResponse;
<commit_msg>Stringify about response<commit_after>var HTTPS = require('https');
const fs = require('fs');

var botID = process.env.BOT_ID;

function parseResponse() {
  var request = JSON.parse(this.req.chunks[0]),
  //callback trigger probably shouldn't be in the response...
      botRegex = /\@Bo/;

  if(request.text && botRegex.test(request.text)) {
    console.log("Trigger detected: ");
    var botResponse = "";

    switch (true) {
      case (/about|help|who are/.test(request.text)):
        botResponse = buildAbout();
        break;
      case (/weather/.test(request.text)):
        botResponse = buildWeather();
        break;
    }

    this.res.writeHead(200);
    postMessage(botResponse);
    this.res.end();
  } else {
    console.log("No trigger detected.");
    this.res.writeHead(200);
    this.res.end();
  }
}

function buildAbout() {
  console.log("about")
  return JSON.stringify(fs.readFileSync(__dirname + '/README.md'));
}

function buildWeather(request) {
  var arr = request.split(" ");
}

function postMessage(botResponse) {
  var botResponse, options, body, botReq;

  options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
  };

  body = {
    "bot_id" : botID,
    "text" : botResponse
  };

  console.log('sending ' + botResponse + ' to ' + botID);

  botReq = HTTPS.request(options, function(res) {
      if(res.statusCode == 202) {
        //neat
      } else {
        console.log('Response code ' + res.statusCode);
      }
  });

  botReq.on('error', function(err) {
    console.log('Error posting message '  + JSON.stringify(err));
  });
  botReq.on('timeout', function(err) {
    console.log('Timeout posting message '  + JSON.stringify(err));
  });
  botReq.end(JSON.stringify(body));
}

exports.respond = parseResponse;
<|endoftext|>


<commit_before>var HTTPS = require('https');
var path = require('path');
var config = require('./config');
var bot = {};

var groupIdToBotMap = {};
config.bots.forEach(function (bot) {
  groupIdToBotMap[bot.groupID] = bot;
});

var commands = [];
bot.registerCommand = function (command, description, func) {
  commands[command] = [description, func];
};

var normalizedPath = path.join(__dirname, "commands");
require("fs").readdirSync(normalizedPath).forEach(function (file) {
  if (path.extname(file) === '.js') {
    require("./commands/" + file)(bot.registerCommand)
  }
});

bot.respond = function (request) {
  var bot = groupIdToBotMap[request.group_id],
      msg = request.text;
  if (!bot) {
    console.log('New message received, but no bot configured for Group ID ' + request.group_id);
  } else {
    console.log('New message from %s in group \'%s\': %s', request.name, bot.groupLocalID, msg);
    if (typeof msg === 'string' && msg.substring(0, 4) === 'bot ') {
      msg = msg.substring(4);
      processCommand(bot.groupLocalID, msg, function (response) {
        if (response !== null) {
          postMessage(bot.botID, response);
        }
      });
    }
  }
};

bot.processCommand = function (groupLocalID, message, cb) {
  var tokens = message.split(' '),
      commandString = tokens.shift();

  if (groupLocalID === '3') {
    // do not send anything to the group I assigned local id 3
    cb(null);
    return;
  }

  if (!commandString) {
    cb(null);
    return;
  }

  if (commandString === 'help') {
    var helpText = 'Usage: bot <command> <arguments> [optional arguments]\n' +
      'Available commands:\nhelp: Display this text\n';
    for (var key in commands) {
      if (commands.hasOwnProperty(key)) {
        helpText += commands[key][0] + '\n';
      }
    }
    cb(helpText);
    return;
  }

  var command = commands[commandString];
  if (!command) {
    cb('Command \'' + commandString + '\' not supported. Type \'bot help\' for available commands.');
    return;
  }

  command[1](groupLocalID, tokens, cb);
};

bot.postMessage = function (botID, text) {
  var options, body, botReq;

  options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
  };

  body = {
    "bot_id" : botID,
    "text" : text
  };

  console.log('sending ' + text + ' to ' + botID);

  botReq = HTTPS.request(options, function(res) {
      if(res.statusCode == 202) {
        //neat
      } else {
        console.log('rejecting bad status code ' + res.statusCode);
      }
  });

  botReq.on('error', function(err) {
    console.log('error posting message '  + JSON.stringify(err));
  });
  botReq.on('timeout', function(err) {
    console.log('timeout posting message '  + JSON.stringify(err));
  });
  botReq.end(JSON.stringify(body));
};

module.exports = bot;
<commit_msg>add source of code snipped<commit_after>var HTTPS = require('https');
var path = require('path');
var config = require('./config');
var bot = {};

var groupIdToBotMap = {};
config.bots.forEach(function (bot) {
  groupIdToBotMap[bot.groupID] = bot;
});

var commands = [];
bot.registerCommand = function (command, description, func) {
  commands[command] = [description, func];
};

// http://stackoverflow.com/a/5365577 (node.js require all files in a folder?)
// And http://stackoverflow.com/questions/5364928/node-js-require-all-files-in-a-folder#comment25520686_5365577
var normalizedPath = path.join(__dirname, "commands");
require("fs").readdirSync(normalizedPath).forEach(function (file) {
  if (path.extname(file) === '.js') {
    require("./commands/" + file)(bot.registerCommand)
  }
});

bot.respond = function (request) {
  var bot = groupIdToBotMap[request.group_id],
      msg = request.text;
  if (!bot) {
    console.log('New message received, but no bot configured for Group ID ' + request.group_id);
  } else {
    console.log('New message from %s in group \'%s\': %s', request.name, bot.groupLocalID, msg);
    if (typeof msg === 'string' && msg.substring(0, 4) === 'bot ') {
      msg = msg.substring(4);
      processCommand(bot.groupLocalID, msg, function (response) {
        if (response !== null) {
          postMessage(bot.botID, response);
        }
      });
    }
  }
};

bot.processCommand = function (groupLocalID, message, cb) {
  var tokens = message.split(' '),
      commandString = tokens.shift();

  if (groupLocalID === '3') {
    // do not send anything to the group I assigned local id 3
    cb(null);
    return;
  }

  if (!commandString) {
    cb(null);
    return;
  }

  if (commandString === 'help') {
    var helpText = 'Usage: bot <command> <arguments> [optional arguments]\n' +
      'Available commands:\nhelp: Display this text\n';
    for (var key in commands) {
      if (commands.hasOwnProperty(key)) {
        helpText += commands[key][0] + '\n';
      }
    }
    cb(helpText);
    return;
  }

  var command = commands[commandString];
  if (!command) {
    cb('Command \'' + commandString + '\' not supported. Type \'bot help\' for available commands.');
    return;
  }

  command[1](groupLocalID, tokens, cb);
};

bot.postMessage = function (botID, text) {
  var options, body, botReq;

  options = {
    hostname: 'api.groupme.com',
    path: '/v3/bots/post',
    method: 'POST'
  };

  body = {
    "bot_id" : botID,
    "text" : text
  };

  console.log('sending ' + text + ' to ' + botID);

  botReq = HTTPS.request(options, function(res) {
      if(res.statusCode == 202) {
        //neat
      } else {
        console.log('rejecting bad status code ' + res.statusCode);
      }
  });

  botReq.on('error', function(err) {
    console.log('error posting message '  + JSON.stringify(err));
  });
  botReq.on('timeout', function(err) {
    console.log('timeout posting message '  + JSON.stringify(err));
  });
  botReq.end(JSON.stringify(body));
};

module.exports = bot;
<|endoftext|>