I am building a web app that allows users to type in phone numbers and send text messages via the Twilio API. I've built the functionality in a file, shown below. If I cd to this file and run node twilioActions.js, the text message gets sent.
var client = require('twilio')(CLIENT_ID, CLIENT_SECRET);
// ideally, I'd like to send the message using this method and call this from other JavaScript files
export const sendMessage = () => {
}
// the following code works when I run 'node twilioActions.js'
client.sendMessage({
to:'...',
from: '...',
body: 'Text message test.'
}, function(err, responseData) {
if (!err) {
console.log(responseData.from); // outputs "+14506667788"
console.log(responseData.body); // outputs "word to your mother."
}
});
However, I want to call the sendMessage method from a different React file. Here is it:
import * as twilioActions from './twilioActions';
class PhoneView extends React.Component{
// other methods are hidden obviously, the one below is called when a button is pressed to send a message.
sendMessage() {
twilioActions.sendMessage();
}
}
When I try to build the project, I get the following errors:
ERROR in ./~/twilio/package.json
Module parse failed:/Users/Felix/Desktop/ECE590/node_modules/twilio/package.json Line 2: Unexpected token :
You may need an appropriate loader to handle this file type.
| {
| "_args": [
| [
| "twilio",
# ./~/twilio/lib/Client.js 5:17-43
ERROR in ./~/request/lib/har.js
Module not found: Error: Cannot resolve module 'fs' in /Users/Felix/Desktop/ECE590/node_modules/request/lib
# ./~/request/lib/har.js 3:9-22
ERROR in ./~/tunnel-agent/index.js
Module not found: Error: Cannot resolve module 'net' in /Users/Felix/Desktop/ECE590/node_modules/tunnel-agent
# ./~/tunnel-agent/index.js 3:10-24
ERROR in ./~/tunnel-agent/index.js
Module not found: Error: Cannot resolve module 'tls' in /Users/Felix/Desktop/ECE590/node_modules/tunnel-agent
# ./~/tunnel-agent/index.js 4:10-24
I feel like I am making a simple mistake and perhaps am not using the correct libraries or including the proper references. Could someone point me in the right direction about how to get this to work? Thank you so much!
Twilio developer evangelist here.
The twilio npm module is not built or recommended for use in the front end. The main thing is that you would need to expose your account credentials in the front end code of your site. This is a security risk as it means a malicious attacker could get hold of your credentials and abuse your Twilio account.
I recommend creating a service on your server side that you can call to with an AJAX request in order to perform actions like this.
Related
I've created a simple react redux app (using webpack) with a contact form which when the user clicks submit I want to generate and send an email. To do this I have been trying to use nodemailer like so:
import nodemailer from 'nodemailer';
//...
sendEmail () {
const emailInfo = {
to: 'foo#bar.com',
from: 'bar#foo.com',
subject: 'Message from bar',
text: 'Hello world!'
};
const connectionInfo = {
host: '...',
port: 123,
secure: true,
auth: {
user: 'foo#bar.com',
pass: 'foo123'
}
};
const transporter = nodemailer.createTransport('SMTP', connectionInfo);
transporter.sendMail(emailInfo, function(error){
if(error){ console.log('error'); }
console.log('sent');
});
}
... however I've been getting a lot of errors to do with the nodemailer import.
ERROR in ./~/nodemailer/package.json
Module parse failed: /Users/myUser/website/node_modules/nodemailer/package.json Unexpected token (2:8)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (2:8)
ERROR in ./~/nodemailer/lib/http-proxy.js
Module not found: Error: Cannot resolve module 'net' in /Users/myUser/website/node_modules/nodemailer/lib
# ./~/nodemailer/lib/http-proxy.js 7:10-24
ERROR in ./~/nodemailer/lib/http-proxy.js
Module not found: Error: Cannot resolve module 'tls' in /Users/myUser/website/node_modules/nodemailer/lib
# ./~/nodemailer/lib/http-proxy.js 8:10-24
ERROR in ./~/nodemailer/~/nodemailer-direct-transport/lib/direct-transport.js
Module not found: Error: Cannot resolve module 'dns' in /Users/myUser/website/node_modules/nodemailer/node_modules/nodemailer-direct-transport/lib
# ./~/nodemailer/~/nodemailer-direct-transport/lib/direct-transport.js 5:10-24
ERROR in ./~/nodemailer/~/nodemailer-direct-transport/lib/direct-transport.js
Module not found: Error: Cannot resolve module 'net' in /Users/myUser/website/node_modules/nodemailer/node_modules/nodemailer-direct-transport/lib
# ./~/nodemailer/~/nodemailer-direct-transport/lib/direct-transport.js 6:10-24
ERROR in ./~/nodemailer/~/nodemailer-direct-transport/package.json
Module parse failed: /Users/myUser/website/node_modules/nodemailer/node_modules/nodemailer-direct-transport/package.json Unexpected token (2:8)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (2:8)
Am I missing something here or is nodemailer simply not designed for use in the browser? If that's the case is there another option I should be looking at?
node.js is for server side JavaScript, and allows you to do many things that can't be done in a browser.
Sending email is not something that can be done in the sandbox provided by a browser, beyond the limited capabilities of mailto links which can basically pop up the user's email client with some links filled in.
You need to implement server side code to do this, triggered by some action from the client, which could be node.js and nodemailer.
Preamble
To start off, I'm not a developer; I'm just an analyst / product owner with time on their hands. While my team's actual developers have been busy finishing off projects before year-end I've been attempting to put together a very basic API server in Node.js for something we will look at next year.
I used Swagger to build an API spec and then used the Swagger code generator to get a basic Node.js server. The full code is near the bottom of this question.
The Problem
I'm coming across an issue when writing out to a log file using the fs module. I know that the ENOENT error is usually down to just specifying a path incorrectly, but the behaviour doesn't occur when I comment out the Swagger portion of the automatically generated code. (I took the logging code directly out of another tool I built in Node.js, so I'm fairly confident in that portion at least...)
When executing npm start, a few debugging items write to the console:
"Node Server Starting......
Current Directory:/mnt/c/Users/USER/Repositories/PROJECT/api
Trying to log data now!
Mock mode: disabled
PostgreSQL Pool created successfully
Your server is listening on port 3100 (http://localhost:3100)
Swagger-ui is available on http://localhost:3100/docs"
but then fs throws an ENOENT error:
events.js:174
throw er; // Unhandled 'error' event
^
Error: ENOENT: no such file or directory, open '../logs/logEvents2021-12-24.log'
Emitted 'error' event at:
at lazyFs.open (internal/fs/streams.js:277:12)
at FSReqWrap.args [as oncomplete] (fs.js:140:20)
Investigating
Now normally, from what I understand, this would just mean I've got the paths wrong. However, the file has actually been created and the first line of the log file has been written just fine
My next thought was that I must've set the fs flags incorrectly, but it was set to 'a' for append:
var logsFile = fs.createWriteStream(__logdir+"/logEvents"+dateNow()+'.log',{flags: 'a'},(err) =>{
console.error('Could not write new Log File to location: %s \nWith error description: %s',__logdir, err);
});
Removing Swagger Code
Now here's the weird bit: if I remove the Swagger code, the log files write out just fine and I don't get the fs exception!
This is the specific Swagger code:
// swaggerRouter configuration
var options = {
routing: {
controllers: path.join(__dirname, './controllers')
},
};
var expressAppConfig = oas3Tools.expressAppConfig(path.join(__dirname, '/api/openapi.yaml'), options);
var app = expressAppConfig.getApp();
// Initialize the Swagger middleware
http.createServer(app).listen(serverPort, function () {
console.info('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
console.info('Swagger-ui is available on http://localhost:%d/docs', serverPort);
}).on('error',console.error);
When I comment out this code, the log file writes out just fine.
The only thing I can think that might be happening is that somehow Swagger is modifying (?) the app's working directory so that fs no longer finds the same file?
Full Code
'use strict';
var path = require('path');
var fs = require('fs');
var http = require('http');
var oas3Tools = require('oas3-tools');
var serverPort = 3100;
// I am specifically tried using path.join that I found when investigating this issue, and referencing the app path, but to no avail
const __logdir = path.join(__dirname,'./logs');
//These are date and time functions I use to add timestamps to the logs
function dateNow(){
var dateNow = new Date().toISOString().slice(0,10).toString();
return dateNow
}
function rightNow(){
var timeNow = new Date().toTimeString().slice(0,8).toString();
return "["+timeNow+"] "
};
console.info("Node Server Starting......");
console.info("Current Directory: " + __dirname)
// Here I create the WriteStreams
var logsFile = fs.createWriteStream(__logdir+"/logEvents"+dateNow()+'.log',{flags: 'a'},(err) =>{
console.error('Could not write new Log File to location: %s \nWith error description: %s',__logdir, err);
});
var errorsFile = fs.createWriteStream(__logdir+"/errorEvents"+dateNow()+'.log',{flags: 'a'},(err) =>{
console.error('Could not write new Error Log File to location: %s \nWith error description: %s',__logdir, err);
});
// And create an additional console to write data out:
const Console = require('console').Console;
var logOut = new Console(logsFile,errorsFile);
console.info("Trying to log data now!") // Debugging logging
logOut.log("========== Server Startup Initiated ==========");
logOut.log(rightNow() + "Server Directory: "+ __dirname);
logOut.log(rightNow() + "Logs directory: "+__logdir);
// Here is the Swagger portion that seems to create the behaviour.
// It is unedited from the Swagger Code-Gen tool
// swaggerRouter configuration
var options = {
routing: {
controllers: path.join(__dirname, './controllers')
},
};
var expressAppConfig = oas3Tools.expressAppConfig(path.join(__dirname, '/api/openapi.yaml'), options);
var app = expressAppConfig.getApp();
// Initialize the Swagger middleware
http.createServer(app).listen(serverPort, function () {
console.info('Your server is listening on port %d (http://localhost:%d)', serverPort, serverPort);
console.info('Swagger-ui is available on http://localhost:%d/docs', serverPort);
}).on('error',console.error);
In case it helps, this is the project's file structure . I am running this project within a WSL instance in VSCode on Windows, same as I have with other projects using fs.
Is anyone able to help me understand why fs can write the first log line but then break once the Swagger code gets going? Have I done something incredibly stupid?
Appreciate the help, thanks!
Edit: Tried to fix broken images.
Found the problem with some help from a friend. The issue boiled down to a lack of understanding of how the Swagger module works in the background, so this will likely be eye-rollingly obvious to most, but keeping this post around in case anyone else comes across this down the line.
So it seems that as part of the Swagger initialisation, any scripts within the utils folder will also be executed. I would not have picked up on this if it wasn't pointed out to me that in the middle of the console output there was a reference to some PostgreSQL code, even though I had taken all reference to it out of the main index.js file.
That's when I realised that the error wasn't actually being generated from the code posted above: it was being thrown from to that folder.
So I guess the answer is don't add stuff to the utils folder, but if you do, always add a bunch of console logging...
Server :
Meteor.publish('trades', function() {
return Trades.find();
});
Client:
Meteor.subscribe("trades");
Both:
Trades = new Meteor.Collection('trades');
When I run meteor, its giving me
TypeError: Object # has no method 'subscribe'
Any suggestions?
You might have your client code running in the root directory /. It would also then execute on the server and give this error. (Not sure if its this).
I am having a problem similar to socket.io issue using sails.js. Every once in a while (once per day, or even few hours, it varies), a visitor to the web site/app will crash Node, seemingly due to the way his websocket client tries to connect. Anyway, here's the crash log:
debug: Lowering sails...
/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/express/node_modules/connect/lib/utils.js:216
return 0 == str.indexOf('s:')
^
TypeError: Cannot call method 'indexOf' of undefined
at exports.parseSignedCookie (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/express/node_modules/connect/lib/utils.js:216:19)
at Manager.socketAttemptingToConnect (/Volumes/Two/Sites/lsdfinder/node_modules/sails/lib/hooks/sockets/authorization.js:35:26)
at Manager.authorize (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:910:31)
at Manager.handleHandshake (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:786:8)
at Manager.handleRequest (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:593:12)
at Server.<anonymous> (/Volumes/Two/Sites/lsdfinder/node_modules/sails/node_modules/socket.io/lib/manager.js:119:10)
at Server.EventEmitter.emit (events.js:98:17)
at HTTPParser.parser.onIncoming (http.js:2076:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:120:23)
at Socket.socket.ondata (http.js:1966:22)
9 Oct 10:42:24 - [nodemon] app crashed - waiting for file changes before starting...
In config/sockets.js, authorization is set to true. Not sure what else to do, where to fix this. Any suggestions? I can read the Sails docs too, but this appears to be a problem in Express/Connect, no? Thanks.
...René
The problem is that once every so often, a client will connect that has no cookies. Sails.js is using util.parseSignedCookie() from Connect without checking for errors, and therefore an error is thrown. This is what it looks like in Sails:
if (handshake.headers.cookie) {
handshake.cookie = cookie.parse(handshake.headers.cookie);
handshake.sessionID = parseSignedCookie(handshake.cookie[sails.config.session.key], sails.config.session.secret);
}
If you take a look into the cookieParser() middleware of Connect, you can see error checking is required:
if (cookies) {
try {
req.cookies = cookie.parse(cookies);
if (secret) {
req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
req.signedCookies = utils.parseJSONCookies(req.signedCookies);
}
req.cookies = utils.parseJSONCookies(req.cookies);
} catch (err) {
err.status = 400;
return next(err);
}
}
I've created a Gist here that fixes the problem, and will submit a pull request to Sails.js when I have the time. The Gist uses Connect's cookieParser() middleware to automatically handle errors. If you want to use this, modify this file in your modules folder:
node_modules/sails/lib/hooks/sockets/authorization.js
If you are doing a crossdomain request, you could turn off authorization.
In *site_dir/config/sockets.js* set authorization to false. One way of doing it. You can also call your api with something like this
bash
**http://localhost:1337?cookie=smokeybear**
Its is in the comments on the sockets.js file.
I need to use LOAD DATA LOCAL INFILE using mysql-libmysqlclient in node. However I get an error
[Error: Query error #1148: The used command is not allowed with this MySQL version]
This does not happen running the same command from sequel pro so the issue is most likely with the connection used by mysql-libmysqlclient.
Anoyone know what parameters to send to mysql-libmysqlclient in order to fix this?
initializing connection:
secrets = stuff
mysql_db = mysql.createConnectionQueuedSync()
mysql_db.initSync()
mysql_db.realConnectSync secrets.host, secrets.user, secrets.password, secrets.database
mysql_db.connectError
module.exports = exports = mysql_db
Sending query:
mysql_db = require('./config/mysql_db')
sql_insert_into = "LOAD DATA local INFILE 'file_to_send.txt'
into table #{table.name}
FIELDS TERMINATED BY ';'
LINES TERMINATED by '\\n'
"
mysql_db.query sql_insert_into, (err, answer)->
console.log "sent " + sql_insert_into
The error I get:
[Error: Query error #1148: The used command is not allowed with this MySQL version]
Minor note: I program in coffee script but this shouldn't change anything
If LOAD DATA LOCAL is disabled, either in the server or the client, a client that attempts to issue such a statement receives the following error message:
ERROR 1148: The used command is not allowed with this MySQL version
You can refer MySql website link below for how to enable:
https://dev.mysql.com/doc/refman/5.5/en/load-data-local.html