Slack node js program running session shut down - node.js

Sorry to disturb. I am programming a Slack robot to reply user message by using the API
In the morning, it works totally okay. Then after I returned back from my office it just shut down and show me this error
Jiatongs-MacBook-Pro:news-bot jiatongli$ node index.js
Assertion failed: token must be defined
/Users/jiatongli/Desktop/news-bot/node_modules/vow/lib/vow.js:105
throw e;
^
Error: not_authed
at _api.then.fail (/Users/jiatongli/Desktop/news-bot/node_modules/slackbots/index.js:46:33)
at Array.<anonymous> (/Users/jiatongli/Desktop/news-bot/node_modules/vow/lib/vow.js:773:56)
at callFns (/Users/jiatongli/Desktop/news-bot/node_modules/vow/lib/vow.js:24:35)
at process._tickCallback (internal/process/next_tick.js:61:11)
Emitted 'error' event at:
at _api.then.fail (/Users/jiatongli/Desktop/news-bot/node_modules/slackbots/index.js:46:19)
at Array.<anonymous> (/Users/jiatongli/Desktop/news-bot/node_modules/vow/lib/vow.js:773:56)
at callFns (/Users/jiatongli/Desktop/news-bot/node_modules/vow/lib/vow.js:24:35)
at process._tickCallback (internal/process/next_tick.js:61:11)
Jiatongs-MacBook-Pro:news-bot jiatongli$
I personally have no idea what is going on because it seems like the program itself do not have bug. What i miss?
Here is the code in my index.js file:
var SlackBot = require("slackbots");
var request = require("request");
var NewsAPI = require("newsapi");
var unirest = require("unirest");
var API_KEY = process.env.API_KEY;
var Slack_API = process.env.Slack_API;
// create a bot
var bot = new SlackBot({
token: Slack_API,
name: "aloha-ai"
});
bot.on("message", msg => {
switch (msg.type) {
case "message":
// we only want to listen to direct messages that come from the user
if (msg.channel[0] === "D" && msg.bot_id === undefined) {
getRandomTechNews(postMessage, msg.user)
}
break
}
})
const postMessage = (message, user) => {
bot.postMessage(user, message, {
as_user: true
});
}
const getRandomTechNews = (callback, user) => {
unirest.get("https://nuzzel-news-v1.p.rapidapi.com/news?count=10&q=product")
.header("X-RapidAPI-Host", "nuzzel-news-v1.p.rapidapi.com")
.header("X-RapidAPI-Key", API_KEY)
.end(function (response) {
var newsJSON = response.body;
var news = "*Viral News* in product : \n\n\n\n";
for (i = 0; i < newsJSON.results.stories.length; i++) {
news += "_Excerpt:_ \n" + ">" + newsJSON.results.stories[i].excerpt + "\n"
news += "_Let's see the article!_ \n" + newsJSON.results.stories[i].url + "\n\n\n"
};
callback(news, user);
});
}

Your error message seems to indicate that your program is not authenticated with the Slack API: Error: not_authed
Since you are retrieving your API key and token from environment variables:
var API_KEY = process.env.API_KEY;
var Slack_API = process.env.Slack_API;
my guess is that you have started a new terminal session where you have not yet set that environment variable, or you are on a different computer where it is not set.
Before running your program, try exporting those variables from the command line:
export API_KEY=<my-api-key>
export Slack_API=<my-token>
If you have security concerns about your API keys showing up in your bash history you can do one of two things (these are examples of things that I do, but there are probably better, safer practices out there):
You can put an empty space before your command [space]export API_KEY=<my-api-key> instead of export API_KEY=<my-api-key>. This will make it so the command does not show up in your history.
You can put your export commands in a separate file called e.g., ~/.secrets and then run the command source ~/.secrets which will run your export commands.
Probably these will give you a sense of security rather than actual security though, since you can just echo the value of the environment variables, but I personally like taking one of these steps as an extra precaution.

i use this answer and can solve it.
Add a bot https://my.slack.com/services/new/bot and put the token
do you get token for your bot from above url:
did you set this ?

Related

Slash command registers command from wrong folder discord.js14

I'm tired of trying to solve this. First off, here is my deployment code
const { REST, Routes } = require('discord.js');
const fs = require('node:fs');
const { client_id } = require('./config.json')
const commands = [];
// Grab all the command files from the commands directory you created earlier
const commandFiles = fs.readdirSync('./slashCommands').filter(file => file.endsWith('.js'));
// Grab the SlashCommandBuilder#toJSON() output of each command's data for deployment
for (const file of commandFiles) {
const command = require(`./slashCommands/${file}`);
commands.push(command.data.toJSON());
}
// Construct and prepare an instance of the REST module
const rest = new REST({ version: '10' }).setToken(process.env.TOKEN);
// and deploy your commands!
(async () => {
try {
console.log(`Started refreshing ${commands.length} application (/) commands.`);
// The put method is used to fully refresh all commands in the guild with the current set
const data = await rest.put(
Routes.applicationCommands(client_id),
{ body: commands },
);
console.log(`Successfully reloaded ${data.length} application (/) commands.`);
} catch (error) {
// And of course, make sure you catch and log any errors!
console.error(error);
}
})();
It is supposed to get the command from the "slashCommand" folder. So I run 'node deploy-commands.js' and it works.
The problem is when I do the slash command '/ping', I get this error:
/home/runner/Nocinel/commands/ping.js:8
message.reply('🏓 **Ball is going over the net...**').then(m => { m.edit(`**🏓 Pong!\n:stopwatch: Uptime: ${Math.round(message.client.uptime / 60000)} minutes\n:sparkling_heart: Websocket Heartbeat: ${message.client.ws.ping}ms\n:round_pushpin: Rountrip Latency: ${m.createdTimestamp - message.createdTimestamp}ms**`) });
^
TypeError: m.edit is not a function
at /home/runner/Nocinel/commands/ping.js:8:73
repl process died unexpectedly: exit status 1
Now this error indicates that I am running a command from my "command" folder rather than my "slashCommand" folder. Which doesnt make sense because I explicitly coded it to only get commands from the "slash command folder"
I have restarted, deleted, waited for an hour, and tested it multiple times, it always gives the same disappointing result. I see absolutely nothing wrong with my code.
There is no problem with registring comannd (deploy-comannds.js is only registring comannds not using making them work). Problem have to be in your index.js you have to handle interaction comannds to your folder slashComannds. Registring comannds was sucessfull.
Documentation:
https://discordjs.guide/creating-your-bot/command-handling.html#loading-command-files

How would I write a changed variable to my config.js file for a permanent change?

My Problem
I am currently writing a Discord bot to be used on one server at the moment. I have set up a command that will change the prefix of the bot's commands but as soon as I restart my repl, it resets to the original prefix. I would like to change the command so that it will write to my config.js file to stop this from happening.
What I've Tried So Far
To be honest, I haven't tried anything yet as I have no idea where to start
My code Files
config.js file:
var config={};
config.token = "My Bot Token";
config.prefix = "//";
config.statusMessage = "video games | (" + config.prefix + "help)";
config.dbltoken = undefined;
module.exports = config;
change-prefix.js file:
config = require('../config.js');
module.exports = (client, message, args) => {
config.prefix = args;
message.reply("Prefix has been changed to: " + config.prefix);
console.log("Command Used: Change-Prefix");
}
What Should Happen
The change-prefix.js file should successfully write the new prefix determined by the user to the config.js file. At this moment in time, I have no errors, but I would like to change this as it would vastly improve the user experience for my bot.
If you want to write the file, you can use fs module. The code below saves custom prefix to prefix.txt file and checks if it exists every time you start your repl. If not, it's using the default value.
Note: the code doesn't have any error handling or any other features, it's just a simple code to show you the idea. In real life scenario, you'll probably want to save your prefix to database, add per-server prefix setting, filter messages from other bots, include prefix in command invocation. Just one more thing - please put Discord token in .env, not in config file.
const Discord = require('discord.js');
const fs = require('fs');
const config = require('./config.js');
const client = new Discord.Client();
// If prefix.txt exist, use it. Otherwise, get data from config file
let prefix = fs.existsSync('prefix.txt') ? fs.readFileSync('prefix.txt').toString() : config.prefix;
client.on('message', (msg) => {
// 'set prefix XXX' to change your prefix to XXX
if (/^set prefix /i.exec(msg.content)) {
const newPrefix = msg.content.split(' ')[2];
fs.writeFile("./prefix.txt", newPrefix, function(err) {
if(err) {
return console.log(err);
}
prefix = newPrefix;
console.log(`Prefix changed to ${prefix}`);
});
}
// 'show prefix' to show current prefix
if (/^show prefix/i.exec(msg.content)) {
console.log(`Prefix is ${prefix}`);
};
});
client.on('ready', () => {
console.log(`I'm in`);
});
client.login(process.env.DISCORD_TOKEN);

ssh2-sftp-client get() request giving 'denied permission - error'

I am using this code in my electron app to connect to an sftp server where I need to collect some data. I have no problem listing the files in the /out folder, but it fails to get the sftp file with 'deined permission' error. Ideally I would like to be able get() file and access the text data within directly in the function without storing to a file.
let Client = require('ssh2-sftp-client');
let sftp = new Client();
var root = '/out';
var today = new Date();
var mon = ((today.getMonth()+1) < 10)? "0" + (today.getMonth()+1) : (today.getMonth()+1);
var date = (today.getDate() < 10)? "0" + today.getDate() : today.getDate();
var fileDate = mon + date;
sftp.connect({
host: '<server-address>',
port: 2222,
username: 'XXXXXXXX',
password: 'xxxxxxxx',
privateKey: fs.readFileSync(path.join(__dirname, '../rsa/<file-name-here>.pem'))
})
.then(() => {
return sftp.list(root, 'SN5M' + fileDate);
})
.then((fileInfo) => {
if (fileInfo) {
var filePath = root + '/' + fileInfo[fileInfo.length - 1].name;
return sftp.get(filePath).then((file) => {
console.log(file);
event.returnValue = file;
sftp.end();
})
.catch((err) => {
console.log('File get error', err);
event.returnValue = err;
sftp.end();
});
}
})
.catch((err) => {
console.log('File info error', err);
event.returnValue = err;
sftp.end();
});
Try this and see if it works or not
'get' returns (String|Stream|Buffer).
let dst = fs.createWriteStream('/local/file/path/data.txt');
sftp.get(filePath,dst)
Refer https://www.npmjs.com/package/ssh2-sftp-client#orga0dfcd5
Looking at your code, you have two problems.
If you call get() with only 1 argument, it returns a buffer, not a file. To get the file, just do
client.get(sourceFilePath, localFilePath)
and the file will be saved locally as localFilePath. Both arguments are strings and need to be full paths i.e. include the filename, not just the directory. The filename for the second argument can be different from the first. However, if all you want is to retrieve the file, you are better off using fastGet() rather than get(). The get() method is good for when you want to do something in the code with the data e.g. a buffer or write stream piping/processing. The fastGet() method is faster than get() as it does the transfer using concurrent processes, but does not permit use of buffers or streams for further processing.
The error message you are seeing is either due to the way you are calling get() or it is an indication you don't have permission to read the file your trying to access (as the user your connected with). Easiest way to check this is to use the openSSH sftp program (available on Linux, mac and windows) and the key your using (use the -i switch) to try and download the file. If it fails with a permission error, then you know it is a permission error and not a problem with your code or ssh2-sftp-client module.
EDIT: I just noticed you are also using both a password and a key file. You don't need both - either one will work, but you don't need to use both. I tend to use a keyfile when possible as it avoids having to have a password stored somewhere. Make sure not to add a passphrase to your key. Alternatively, you can use something like the dotenv module and store your credentials and other config in a .env file which you do not check into version control.

Meteor/Node writeFile crashes server

I have the following code:
Meteor.methods({
saveFile: function(blob, name, path, encoding) {
var path = cleanPath(path), fs = __meteor_bootstrap__.require('fs'),
name = cleanName(name || 'file'), encoding = encoding || 'binary',
chroot = Meteor.chroot || 'public';
// Clean up the path. Remove any initial and final '/' -we prefix them-,
// any sort of attempt to go to the parent directory '..' and any empty directories in
// between '/////' - which may happen after removing '..'
path = chroot + (path ? '/' + path + '/' : '/');
// TODO Add file existance checks, etc...
fs.writeFile(path + name, blob, encoding, function(err) {
if (err) {
throw (new Meteor.Error(500, 'Failed to save file.', err));
} else {
console.log('The file ' + name + ' (' + encoding + ') was saved to ' + path);
}
});
function cleanPath(str) {
if (str) {
return str.replace(/\.\./g,'').replace(/\/+/g,'').
replace(/^\/+/,'').replace(/\/+$/,'');
}
}
function cleanName(str) {
return str.replace(/\.\./g,'').replace(/\//g,'');
}
}
});
Which I took from this project
https://gist.github.com/dariocravero/3922137
The code works fine, and it saves the file, however it repeats the call several time and each time it causes meteor to reset using windows version 0.5.4. The F12 console ends up looking like this: . The meteor console loops over the startup code each time the 503 happens and repeats the console logs in the saveFile function.
Furthermore in the target directory the image thumbnail keeps displaying and then display as broken, then a valid thumbnail again, as if the fs is writing it multiple times.
Here is the code that calls the function:
"click .savePhoto":function(e, template){
e.preventDefault();
var MAX_WIDTH = 400;
var MAX_HEIGHT = 300;
var id = e.srcElement.id;
var item = Session.get("employeeItem");
var file = template.find('input[name='+id+']').files[0];
// $(template).append("Loading...");
var dataURL = '/.bgimages/'+file.name;
Meteor.saveFile(file, file.name, "/.bgimages/", function(){
if(id=="goodPhoto"){
EmployeeCollection.update(item._id, { $set: { good_photo: dataURL }});
}else{
EmployeeCollection.update(item._id, { $set: { bad_photo: dataURL }});
}
// Update an image on the page with the data
$(template.find('img.'+id)).delay(1000).attr('src', dataURL);
});
},
What's causing the server to reset?
My guess would be that since Meteor has a built-in "automatic directories scanning in search for file changes", in order to implement auto relaunching of the application to newest code-base, the file you are creating is actually causing the server reset.
Meteor doesn't scan directories beginning with a dot (so called "hidden" directories) such as .git for example, so you could use this behaviour to your advantage by setting the path of your files to a .directory of your own.
You should also consider using writeFileSync insofar as Meteor methods are intended to run synchronously (inside node fibers) contrary to the usual node way of asynchronous calls, in this code it's no big deal but for example you couldn't use any Meteor mechanics inside the writeFile callback.
asynchronousCall(function(error,result){
if(error){
// handle error
}
else{
// do something with result
Collection.update(id,result);// error ! Meteor code must run inside fiber
}
});
var result=synchronousCall();
Collection.update(id,result);// good to go !
Of course there is a way to turn any asynchronous call inside a synchronous one using fibers/future, but that's beyond the point of this question : I recommend reading this EventedMind episode on node future to understand this specific area.

node.js + express error: cannot read property 'url' of undefined

I'm fairly new to Node.js, installing it to try out the DrupalChat (v7dev) module. I believe this problem is with either node.js or express, as I am beyond the stage where the chat module's settings are loaded. I am faced with the following output when trying to start the chat server
Extension loaded: drupalchat_nodejs.server.extension.js
Started http server.
info - socket.io started
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Cannot read property 'url' of undefined
at Function.handle (/usr/local/lib/node_modules/npm/node_modules/express/node_modules/connect/lib/proto.js:105:18)
at Server.app (/usr/local/lib/node_modules/npm/node_modules/express/node_modules/connect/lib/connect.js:60:31)
at Server.serverListening (/usr/local/lib/node_modules/npm/node_modules/socket.io/node_modules/policyfile/lib/server.js:136:16)
at Server.g (events.js:154:14)
at Server.emit (events.js:64:17)
at Array.1 (net.js:710:10)
at EventEmitter._tickCallback (node.js:192:40)
I remember when express installed, it gave a warning like ".... bugs['web'] should probably be bugs['url']" (I can't remember the prefix)
So is it that the server is trying to read an (API?) variable 'url' but its currently 'web'?
I have all the modules up to date, is it that I should downgrade? Or is there some way of working around this using another module?
EDIT:
line 201 is the last very line (delete authenticatedClients[authData.authToken];)... I just added to whole function for proper context
var authenticateClientCallback = function (error, response, body) {
if (error) {
console.log("Error with authenticate client request:", error);
return;
}
if (response.statusCode == 404) {
if (settings.debug) {
console.log('Backend authentication url not found, full response info:', response);
}
else {
console.log('Backend authentication url not found.');
}
return;
}
var authData = false;
try {
authData = JSON.parse(body);
}
catch (exception) {
console.log('Failed to parse authentication message:', exception);
if (settings.debug) {
console.log('Failed message string: ' + body);
}
return;
}
if (!checkServiceKey(authData.serviceKey)) {
console.log('Invalid service key "', authData.serviceKey, '"');
return;
}
if (authData.nodejsValidAuthToken) {
if (settings.debug) {
console.log('Valid login for uid "', authData.uid, '"');
}
setupClientConnection(authData.clientId, authData, authData.contentTokens);
authenticatedClients[authData.authToken] = authData;
}
else {
console.log('Invalid login for uid "', authData.uid, '"');
delete authenticatedClients[authData.authToken];
}
}
Per #thesnufkin's post, looks like the underlying express version currently pulled is not stable. Roll back to 2.5.9 and you should be good to go:
npm uninstall express
npm install express#2.5.9
As requested,
The v7 chat module from drupal is not stable. You should not use it in production.
Check bugs : http://drupal.org/project/issues/drupalchat?status=All&categories=All
Check forums : http://drupalchat7.botskool.co.in/?q=forum
Still looking for a new maintener:
"New maintainer wanted - please ping beejeebus if you're interested!".
nodejs module has this issue, so I don't think its related to the drupalchat server specifically. Here is the issue for that: http://drupal.org/node/1537702
The option to use node.js as backend in DrupalChat is currently under development. It also depends when (date on which) you downloaded the DrupalChat since the dev code is updated everyday, if new code is committed.
Please raise an issue for the same at this link - http://drupal.org/project/issues/drupalchat?status=All&categories=All.
Thanks,
darklrd

Resources