edit: added a bit more code.
const express = require('express');
var bodyParser = require('body-parser');
const app = express();
var urlencodedParser = bodyParser.urlencoded({extended: false})
const {google} = require('googleapis');
const {PubSub} = require('#google-cloud/pubsub');
const iot = require('#google-cloud/iot');
const API_VERSION = 'v1';
const DISCOVERY_API = 'https://cloudiot.googleapis.com/$discovery/rest';
app.get('/', urlencodedParser, (req, res) => {
const projectId = req.query.proyecto;
const cloudRegion = req.query.region;
const registryId = req.query.registro;
const numSerie = req.query.numSerie;
const command = req.query.command;
const client = new iot.v1.DeviceManagerClient();
if (client === undefined) {
console.log('Did not instantiate client.');
} else {
console.log('Did instantiate client.');
sendCom();
}
async function sendCom() {
const formattedName = await client.devicePath(projectId, cloudRegion, registryId, numSerie)
const binaryData = Buffer.from(command);
const request = {
name: formattedName,
binaryData: binaryData,
};
return client.sendCommandToDevice(request).then(responses => res.status(200).send(JSON.stringify({
data: OK
}))).catch(err => res.status(404).send('Could not send command. Is the device connected?'));
}
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
I have this function, that I call after the client initiate: sendCom();
async function sendCom() {
const formattedName = await client.devicePath(projectId, cloudRegion, registryId, deviceId)
const binaryData = Buffer.from(command);
const request = { name: formattedName, binaryData: binaryData, };
client.sendCommandToDevice(request)
.then(responses => {
res.status(200).send(JSON.stringify({ data: OK })).end();
})
.catch(err => {
res.status(404).send('Could not send command. Is the device connected?').end();
});
}
My problem is that sendCommandToDevice gets executed perfectly, however I get the catch error.
As I understand it, it's because in the .then ends the connection.
I've looked at this and thats's what I tried, however I'm not sure I understand what's going on.
You can not use send with end.
end() is used when you want to end the request and want to respond with no data.
send() is used to end the request and respond with some data.
You can found more about it here.
Related
How to connect new mongodb v5 to nodejs
const express = require('express');
const app = express();
const { MongoClient } = require('mongodb');
const url = 'mongodb://localhost:27017';
const client = new MongoClient(url);
async function main() {
await client.connect();
}
const collection = client.db('internfeb').collection('dashboard');
const port = process.env.PORT || 7710;
app.get('/health',async(req,res) => {
const output = []
const cursor = collection.find({});
for await (const doc of cursor) {
output.push(doc)
}
cursor.closed;
res.send(output)
})
app.post('/addUser',async(req,res) => {
await collection.insertOne(req.body)
res.send('Data Added')
})
app.listen(port,() => {
main()
console.log(`Running on thr port ${port}`)
})
You should initialize collection after the client has connected:
const express = require('express');
const app = express();
const { MongoClient } = require('mongodb');
const url = 'mongodb://localhost:27017';
const client = new MongoClient(url);
let collection;
async function main() {
try {
await client.connect();
collection = client.db('internfeb').collection('dashboard');
} catch (err) {
console.log(err);
process.exit(1);
}
}
const port = process.env.PORT || 7710;
app.get('/health', async (req, res) => {
const output = [];
const cursor = collection.find({});
for await (const doc of cursor) {
output.push(doc);
}
cursor.closed;
res.send(output);
});
app.post('/addUser', async (req, res) => {
await collection.insertOne(req.body);
res.send('Data Added');
});
app.listen(port, () => {
main();
console.log(`Running on thr port ${port}`);
});
I have created a socket server as shown below.
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server, {cors:{origin:'*'}})
const mongoose= require("mongoose")
const port = process.env.PORT || 4002;
server.listen(port, ()=>{
console.log(`Listening on port ${port}......`)
})
onlineUsers = [];
const addNewUser = (userId, socketId)=>{
!onlineUsers.some((user)=>user.userId === userId) &&
onlineUsers.push({userId,socketId})
}
const removeUser= (socketId) =>{
onlineUsers = onlineUsers.filter((user)=> user.socketId!==socketId)
}
const getUser = (userId)=>{
return onlineUsers.find(user=>user.userId ===userId)
}
io.on("connection", (socket=> {
console.log("User connected:", socket.id);
socket.on("disconnect",()=>{
removeUser(socket.id)
})
socket.on("newUser",(userId)=>{
addNewUser(userId, socket.id)
})
export function handleMessaging (userId,clientID,messageId )
{
const receiver = getUser(userId);
if(receiver)
{
io.to(receiver.socketId).emit("sendMessage", {data:"working properly"});
return true;
}
else return false
}
}));
I want to export the function handle messaging so that I can use it inside the API like (shown below) to see if a user is online and if yes, send a message.
But as someone new to programming, I can't figure out how to export handle messaging the proper way. I tried to use export but its telling me "Modifiers cannot appear here".
router.post('/:companyId' async (req, res) => {
const {userId,clientId,messageId} = req.body
handleMessaging (userId,clientID,messageId )
{
//do xyz
}
}
I am using socket.io for bi-directional communication between client-server side , i have also used web speech api for speech synthesis and recognition in my web app ,though it fulfills default responses and it gives output properly , but during contextual conversation my intents doesn't match with context and results in fallback intent.
It works fine on dialogflow "try" console but doesn't work on my webapp , please can anyone help..!
here's my app.js file :-
const path = require("path");
const express = require("express");
const colors = require("colors");
const dotenv = require("dotenv");
const socketio = require("socket.io");
const dialogflow = require("#google-cloud/dialogflow");
const uuid = require("uuid");
const app = express();
dotenv.config({ path: "./config/config.env" });
app.use(express.static(path.join(__dirname, "views")));
app.use(express.static(path.join(__dirname, "public")));
const PORT = process.env.PORT || 3000;
const server = app.listen(
PORT,
console.log(
`Server is runnig on ${process.env.NODE_ENV} mode at port ${PORT} for ${process.env.PROJECT_ID}`.yellow
.bold
)
);
const io = socketio(server);
io.on("connection", function (socket) {
console.log("a user connected");
socket.on("chat message", (message) => {
console.log(message);
const callapibot = async (projectId = process.env.PROJECT_ID) => {
try {
const sessionId = uuid.v4();
const sessionClient = new dialogflow.SessionsClient({
keyFilename: "/home/abat/Downloads/kiosk-cwbx-8e7bd8645085.json",
});
const sessionPath = sessionClient.projectAgentSessionPath(
projectId,
sessionId,
);
const request = {
session: sessionPath,
queryInput: {
text: {
text: message,
languageCode: "en-US",
},
},
};
const responses = await sessionClient.detectIntent(request);
console.log("Detected intent");
const result = responses[0].queryResult;
socket.emit("bot reply", result.fulfillmentText);
console.log(result);
if (result.intent) {
console.log(` Intent: ${result.intent.displayName}`);
} else {
console.log(` No intent matched.`)
}
} catch (error) {
console.log(error);
}
};
callapibot();
});
});
here's my script.js file :-
const btn = document.querySelector("button");
const outputme = document.querySelector(".output-you");
const outputbot = document.querySelector(".output-bot");
const socket = io();
const SpeechRecognition =
window.SpeechRecognition || window.webkitSpeechRecognition;
const recognition = new SpeechRecognition();
recognition.lang = "en-US";
recognition.interimResults = false;
btn.addEventListener("click", () => {
recognition.start();
});
recognition.onresult = function (event) {
const last = event.results.length - 1;
const text = event.results[last][0].transcript;
console.log(text);
outputme.textContent = text;
socket.emit("chat message", text);
};
const botReply = (text) => {
const synth = window.speechSynthesis;
const voices = synth.getVoices();
const utterance = new SpeechSynthesisUtterance();
utterance.voice = voices[4];
utterance.lang = "hi-IN";
utterance.text = text;
utterance.pitch = 1;
utterance.volume = 1;
synth.speak(utterance);
};
socket.on("bot reply", (text) => {
outputbot.textContent = text;
botReply(text);
});
Does my code need modifications for handling contexts for dialogflow ?
Got the answer , it was because the session id was inside the async function() , i then removed it from there and placed it on the top
const sessionId = uuid.v4();
Don't put this under the async function , that's it.
I have this in Google's App Engine (node.js).
My device gets all the commands but I still get the Could not send command. Is the device connected? error.
BTW, already tried this: Await for function before end()
And same result.
Trying to follow this example BTW:
https://cloud.google.com/nodejs/docs/reference/iot/0.2.x/v1.DeviceManagerClient#sendCommandToDevice
const express = require('express');
var bodyParser = require('body-parser');
const app = express();
var urlencodedParser = bodyParser.urlencoded({
extended: false
})
const iot = require('#google-cloud/iot');
app.get('/', urlencodedParser, (req, res) => {
res.setHeader('Content-Type', 'application/json');
const projectId = req.query.proyecto;
const cloudRegion = req.query.region;
const registryId = req.query.registro;
const numSerie = req.query.numSerie;
const command = req.query.command;
const client = new iot.v1.DeviceManagerClient();
if (client === undefined) {
console.log('Did not instantiate client.');
} else {
console.log('Did instantiate client.');
sendCom();
}
async function sendCom() {
const formattedName = client.devicePath(projectId, cloudRegion, registryId, numSerie)
const binaryData = Buffer.from(command);
const request = {
name: formattedName,
binaryData: binaryData,
};
return client.sendCommandToDevice(request).then(responses => res.status(200).end(JSON.stringify({
data: OK
}))).catch(err => res.status(404).end('Could not send command. Is the device connected?'));
}
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
On my end I should get status 200 and OK but it doesn't happen.
This is what I want, server is a file server, when client asks for certain file, it'll stream that file back. Instead of koi-static, I try to do this, but the dest.jpg only contains 'Not found'.
client code:
var Koa = require('koa');
var Router = require('koa-router');
const HttpStatus = require('http-status');
const fs = require('fs');
const koaBody = require('koa-body');
const request = require('request');
const tempSaveFile = fs.createWriteStream('dest.jpg');
const writeStream = request.post('http://localhost:3456/getfile/src.jpg').pipe(tempSaveFile);
writeStream.on('finish', () => {
tempSaveFile.end();
console.log('Upload successful! ');
});
server code:
var Koa = require('koa');
var Router = require('koa-router');
const HttpStatus = require('http-status');
const fs = require('fs');
const koaBody = require('koa-body');
var app = new Koa();
var router = new Router();
const serve = require('koa-static');
router
.post([`/getfile/:fileName`],
(ctx) => {
const { params: { fileName } } = ctx;
console.error(`------- server will return ${fileName} --------`);
const readStream = fs.createReadStream(fileName).pipe(ctx.res);
readStream.on('finish', () => {
console.error('---- server finished stream ----');
ctx.status = HttpStatus.OK;
});
})
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3456);
When I change the server to use koa-static, client can gets the file successfully, did diff, look the same.
I suspect server returns too fast before it finishes, but another post said this is the way to wait for pipe to finish.
callback to handle completion of pipe
Any suggestions ? thanks !
ok, I added async, working now
const multiparty = require('multiparty');
const multer = require('koa-multer');
const request = require('request');
var app = new Koa();
var router = new Router();
const serve = require('koa-static');
const streamEnd = fd => new Promise((resolve, reject) => {
fd.on('end', () => {console.error('-- 51 --'); resolve(51); });
fd.on('finish', () => {console.error('-- 53 --'); resolve(53); });
fd.on('error', reject);
});
router
.get([`/getfile/:fileName`],
async (ctx) => {
const { params: { fileName } } = ctx;
console.error(`------- server will return ${fileName} --------`);
if (fs.existsSync(fileName)) {
const readStream = fs.createReadStream(fileName).pipe(ctx.res);
await streamEnd(readStream);
ctx.status = HttpStatus.OK;
} else {
console.error(`File ${fileName} doesnot exist`);
ctx.status = HttpStatus.INTERNAL_SERVER_ERROR;
}
})
app.use(serve('./customer'));
app.use(router.routes());
app.use(router.allowedMethods());
app.listen(3456);