Speech to text bing speech API Azure - node.js

When I trying to execute the code below, I get the following error:
(node:3784) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Voice recognition failed miserably: socket hang up
var fs = require('fs');
var bing = require('bingspeech-api-client');
var audioStream = fs.createReadStream('d:\\node.wav');
var subscriptionKey = 'xxxxxxxxxxxxxxxxx';
var client = new bing.BingSpeechClient(subscriptionKey);
client.recognizeStream(audioStream)
.then(response => console.log(response.results[0].name));
Please help me.

I tried with your code snippet and the example audio file in the repository at https://github.com/palmerabollo/bingspeech-api-client/tree/master/examples. It works fine on my side.
Dived into the source code, I found the error message is thrown by
throw new Error(`Voice recognition failed miserably: ${err.message}`);
at https://github.com/palmerabollo/bingspeech-api-client/blob/master/src/client.ts#L129
Usually it's an Internet issue, please double check your internet work, or you can try to ping url https://api.cognitive.microsoft.com/sts/v1.0/issueToken to check whether you have a problem connect to the API.

Came across the issue while playing with the service and it was due to the timeout settings hardcoded in bingspeech-api-client in Line 110:
open_timeout: 5000,
Full code here.
You might want to try to set higher values based on your internet connection.

if you are behind a proxy server, try setting the proxy in the node_modules\bingspeech-api-client\lib\client.js file using
https-proxy-agent
in option of all the http request, include issue token.

The below code works for me
const { BingSpeechClient, VoiceRecognitionResponse } = require('bingspeech-api-client');
const fs = require('fs');
let audioStream = fs.createReadStream("audiowav.wav");
// Bing Speech Key (https://www.microsoft.com/cognitive-services/en-us/subscriptions)
let subscriptionKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx';
let client = new BingSpeechClient(subscriptionKey);
client.recognizeStream(audioStream).then(function(response)
{
console.log("response is ",response);
console.log("-------------------------------------------------");
console.log("response is ",response.results[0]);
}).catch(function(error)
{
console.log("error occured is ",error);
});
I think you need to import both BingSpeechClient, VoiceRecognitionResponse from bingspeech-api-client.
Here is the reference bingspeech-api-client

Related

Posting message to slack get TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["User-Agent"]

I have a working slack app running as an Azure Function using NodeJS. It is posting payloads fine to my channel. I would also like the Function to post a message to the channel via client.chat.postMessage. As far as I can see I have set everything up correctly but whenever I attempt to post the message I get an error:
TypeError [ERR_INVALID_CHAR]: Invalid character in header content ["User-Agent"]
The code to post the message is:
const { WebClient, LogLevel } = require("#slack/web-api");
const client = new WebClient(process.env['BOT_USER_OAUTH_TOKEN'], {
// LogLevel can be imported and used to make debugging simpler
logLevel: LogLevel.DEBUG
});
const channelId = "C0319MTLHB8";
try {
// Call the chat.postMessage method using the WebClient
const result = await client.chat.postMessage({
channel: channelId,
text: "Hello world"
});
console.log(result);
} catch (error) {
context.res = {
// status: 200, /* Defaults to 200 */
body: "error: " + error
};
}
and this piece of code sits within module.exports.
I guess something doesn't like the contents of BOT_USER_OAUTH_TOKEN but this is a direct copy of the xoxb bot user oauth token. And is of the form:
xoxb-999999999999999-9999999999999-aBunchOfUpperAndLowerCaseCharacters
Any suggestions as to what I am doing wrong?
Thank you I'm Joe Too for your valuable discussed resolution. Posting as an answer to help other community members:
You missed an open bracket in const result = await client.chat.postMessage(
Glad #JimBurke, that you have solved yourself by correcting the syntax/transcription.
Isn't it Node.js 16 LTS?
I had a similar problem, But I made Node.js 14 LTS and it worked

Trouble Connecting to Google Cloud IoT via MQTT with Node.js

I'm trying to create a MQTT client that'll connect to the Google Cloud IoT Core, but for some reason, it won't connect at all. Here's what I have so far
mqtt = require("mqtt")
fs = require("fs")
var jwt = require('jsonwebtoken');
const projectId = "my-project"
const deviceId = "my-device"
const registryId = "my-degistry"
const region = "us-central1"
const algorithm = "RS256"
const privateKeyFile = "./rsa_private.pem"
const mqttBridgeHostname = "mqtt.googleapis.com"
const mqttBridgePort = 8883
const messageType = "events"
//The mqttClientId is a unique string that identifies a particular device.
//For Google Cloud IoT Core, it must be the format below
const mqttClientId = `projects/${projectId}/locations/${region}/registries/${registryId}/devices/${deviceId}`
const mqttTopic = `/devices/${deviceId}/${messageType}`;
const createJwt = (projectId, privateKeyFile, algorithm) => {
// Create a JWT to authenticate this device. The device will be disconnected
// after the token expires, and will have to reconnect with a new token. The
// audience field should always be set to the GCP project id.
const token = {
iat: parseInt(Date.now() / 1000),
exp: parseInt(Date.now() / 1000) + 20 * 60, // 20 minutes
aud: projectId,
};
const privateKey = fs.readFileSync(privateKeyFile);
return jwt.sign(token, privateKey, {algorithm: algorithm});
};
//Username field is ignored in Cloud IoT Core, but it must be set to something
//Password field sends a JWT (javascript web token) to authorize the device
//mqtts protocol causes library to connecti using SSL, which is required for IoT Core
const connectionArgs = {
host: mqttBridgeHostname,
port: mqttBridgePort,
clientId: mqttClientId,
username: "unused",
password: createJwt(projectId, privateKeyFile, algorithm),
protocol: "mqtts",
secureProtocol: "TLSv1_2_method"
}
const client = mqtt.connect(connectionArgs)
client.on("connect", (connected)=>{
console.log("Attempting to connect")
if (!connected) {
console.log("Client failed to connect")
} else {
console.log("Client is connected!")
}
})
client.on("error", err => {
console.log(err)
setTimeout(( ()=> {
console.log('Terminating process')
return process.kill(process.pid);
}), 1000);
})
client.on("packetsend", (payload) => {
console.log("Payload has been sent")
return process.kill(process.pid)
})
client.on("packetreceive", packet => {
console.log("Killing")
//return process.kill(process.pid)
})
client.on("reconnect", ()=>{
console.log("Attempting a reconnect")
//return process.kill(process.pid)
})
client.on("close", ()=>{
console.log("A disconnect occurred")
// return process.kill(process.pid)
})
client.on("offline", () => {
console.log("Client is offline")
//return process.kill(process.pid)
})
I'm not getting any errors when I try to connect to the server. In other words, everything seems to be authenticating properly and I get no error messages, but the client never connects to the Cloud and instead repeatedly tries to reconnect in an endless cycle (which is why I included code to kill the script). I tried going through the Google Cloud troubleshooting page but nothing there really seemed to help. I don't get any sort of errors messages or helpful tidbits of information when using the Cloud SDK like the guide suggested.
I've opened up the port 8883 through my firewall just in case that was the issue but it doesn't appear to be.
I based this code off some of Google's guides and based on this guide here. I have a registry, project, and device all set up with a proper RSA key.
So I'm not really sure how to proceed! If there's any additional information that would help, please let me know.
Thank you.
I realized that when I was creating the project and registry on the Google Console, I actually mistyped the name I was intending (I thought it was "testmqtt" but it was actually "tesmqtt").
So if you're having an issue similar to this, I'd suggest trying the follwing:
Make sure your you've spelled everything right. Make sure the project title is correct, the registry title, etc. It sounds dumb but these types of mistakes happen, so it doesn't hurt to check them first. Otherwise you'll overthink things like I did.
Check out this this page for troubleshooting. There's two parts of this troubleshooting page that might really help you. The first is trying to see if you can actually connect to the cloud at all. You can test if you're able to make a connection by issuing a command like openssl s_client -connect mqtt.googleapis.com:8883 on the command line. You'll need to have openssl downloaded in order to issue that command, however. You can see the page I just linked for more details about testing your connection. The second thing you can do is check to see if you have authentication by running a gcloud command using Google's sdk. The troubleshooting page I linked also has more details in this regard.
This quickstart guide is also particularly helpful. It might be confusing to navigate at first but understanding it will be your best bet.
Google's github repository also has some good examples of how to make an mqtt connection to the cloud IoT core.
DavidC in the comments below helped me find some of these helpful links, so credit should go to him.
Apart from the links I provided in the comment section and as additional to what you have found out, some users use the Project Number instead of the Project ID which leads to a similar concern which you have encountered. It really pays to double check everything in your configuration as you troubleshoot.
If you need to have a refresher about the authentication, you may also refer to this link.

'FIRESTORE INTERNAL ASSERTION FAILED: Unexpected state' when unit testing with Jest

I'ḿ setting up a jest test suite for a Node.js and Express REST API i'm building, i'm using #firebase/testing module to initialize a testing app, however when i try to perform any sort of operation to the database this error comes out:
FIRESTORE (7.17.2) INTERNAL ASSERTION FAILED: Unexpected state
at fail (/home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/util/assert.ts:39:9)
at hardAssert (/home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/util/assert.ts:53:5)
at fromBytes (/home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/remote/serializer.ts:270:5)
at fromWatchChange (/home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/remote/serializer.ts:486:25)
at PersistentListenStream.onMessage (/home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/remote/persistent_stream.ts:576:25)
at /home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/remote/persistent_stream.ts:456:21
at /home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/remote/persistent_stream.ts:509:18
at /home/cardonapablo/Documentos/Proyectos/Optica (Ilicit)../../../../../node_modules/#firebase/testing/node_modules/#firebase/firestore/src/util/async_queue.ts:369:14
I also tried connecting to my regular firestore database with the credentials i have been using to develop the endpoints and same error pops out even tho it's the app i use daily
Weird thing is, data is being written to the database, but error still stops testing
Here is firebase setup:
(src/db/functions.js)
let app = initializeTestApp({
projectId: "illicit"
})
db = app.firestore()
module.exports = { db }
Function throwing the error
(tests/fixtures/db.js)
const { db } = require('../../src/db/functions')
const bcrypt = require('bcrypt');
const createAdmin = async function() {
// Encrypt password
let encPass = await bcrypt.hash("admin", 8)
let admin = {
name: "Admin Test User",
email: "admin#test.com",
password: encPass,
tokens: []
}
// Add to db
let docRef = await db.collection('admins').add(admin) // <- This line throws the error
return;
}
module.exports = {
createAdmin
}
And finally testing file
(tests/glasses.test.js)
const supertest = require('supertest');
const app = require('../src/app')
const functions = require('./fixtures/db')
let adminToken;
let glassesId;
//Executes before any test, here is where error occurs, before any tests
beforeAll( async () => {
await functions.createAdmin()
return
})
test('Should log in an admin', async () => {
let response = await supertest(app)
.post('/admins/login')
.send({
email: 'admin#test.com',
password: 'admin'
})
.expect(200);
expect(response.body.token).toEqual(expect.any(String))
adminToken = response.token;
});
This only happens only when i try to test, regular app works just fine
Things i've tried:
Firestore rules are read and write true, so it's not a rules error
Mocked Firestore with firebase-mock and Jest seems to work fine, however this is not a
solution, since i need to test data inside the database
Hope you can help me :)
You should change Jest's test environment from the default jsdom to node using jest --env=node or by setting the testEnvironment option to node in your Jest config.
Solved the problem myself, i was using the Firebase web client, I switched to the Admin SDK made specifically for servers, i guess it was some sort of auth problem, because the admin sdk automatically authenticates you in the db
This is a open issue on GitHub. I'm pasting my comment from that issue here to hopefully help some other people:
I experienced the same error message on 9.6.6 with NextJS. I believe
this error message could be presented due to a range of errors - as I
see 100+ Stackoverflow questions with this error message.
After lots of debugging I realized I accidently used SQL
capitalization:
.orderBy('time', 'ASC') = "INTERNAL ASSERTION FAILED: Unexpected state" .orderBy('time', 'asc') = No Errors!
This was a pain to debug, and my mistake was so small. Maybe better
error reporting is needed in cases like this? When you get then Google
this error message it easily leads you down a path of debugging things
completely irrelevant to the real error.
So pretty much - a tiny syntax error can cause the error message and lead you down a road of debugging the wrong things. To solve this you have to find exactly where it is happening and narrow in your debuging.
execute this command with what is indicated a little above yarn test jest --env=node
after this the error disappears

How to handle server side error during authentication in react-native

So I was making an app and in that app I have say login with facebook
For login, I am using expo-web-browser
Here is my relevant code,
loginWithFacebook = async () => {
const redirectUrl = await Linking.getInitialURL()
const authUrl = config.backendUrl + '/auth/facebook'
Linking.addEventListener('url', this.handleRedirect)
try {
const authResult = await WebBrowser.openAuthSessionAsync(authUrl, redirectUrl)
console.log(authResult)
Linking.removeEventListener('url', this.handleRedirect)
} catch (err) {
console.warn('ERROR:', err)
}
}
While this works, my problem is on error handling, I am using passport Js on the backend (NodeJS). On successful authentication, I am re-directing to my deep link url
return res.redirect(myapplink://)
and currently, on error (say there is an sql connection error), I am throwing a 500 internal error
return res.status(error.status).send(error.message)
Since typically auth related events are done using href and not using ajaxy request, How would you typically handle the error in this situation? I think the answer for the app and web should be identical but if not can you please suggest the way I can handle error in the app and web.

Connecting to Accumulo from NodeJS

I have been trying to connect to Accumulo from NodeJS through the Thrift proxy, but have been unsuccessful.
var thrift = require("thrift");
var AccumuloClient = require("./AccumuloProxy");
var transport = thrift.TFramedTransport;
var protocol = thrift.TBinaryProtocol;
var connection = thrift.createConnection("localhost", 42424, {
transport: transport,
protocol: protocol
});
var client = thrift.createClient(AccumuloClient, connection);
client.login("root", {'password': "password"});
When I try to login I get
org.apache.thrift.protocol.TProtocolException: Expected protocol id ffffff82 but got ffffff80
Is anyone able to help me out and give me an idea of what I'm doing wrong here?
UPDATE:
I modified protocolFactory line in the proxy.properties file located in Accumulo and restarted the proxy.
protocolFactory=org.apache.thrift.protocol.TBinaryProtocol$Factory
I performed the same steps as above, but added a callback to the createClient call.
var login;
var client = thrift.createClient(AccumuloClient, connection,
function(err, success) { login = success });
This populates the login variable. I then try to use that login variable to execute other functions
client.listTables(login, function(a) { console.log(a) })
results in
{name: 'TApplicationException',
type: 6,
message: 'Internal error processing listTables'}
Trying to create a table
client.createTable(login, "testTable", 1, "", function(a) { console.log(a)})
results in
{name: 'AccumuloSecurityException',
msg: 'org.apache.accumulo.core.client.AccumuloSecurityException: Error SERIALIZATION_ERROR for user unknown - Unknown security exception'}
See answer below.
It turns out that the problem existed because of the handling of the response back from Accumulo. In the AccumuloProxy.js file when the login result is received and read in AccumuloProxy_login_result.prototype.read it will set the success as this.success = input.readString()
The readString() function will take the Buffer and call toString() using the utf8 encoding. This was resulting in characters showing up incorrectly.
I modified the AccumuloProxy_login_result.prototype.read function to set success as this.success = input.readBinary() so that a Buffer is returned. This Buffer can be passed in to the other function calls and will get a correct result back from Accumulo instead of an Exception.
This was put in as an issue with Thrift here and has apparently been fixed in the master branch.
Seems that Accumulo uses the compact protocol, not the binary protocol. It also seems, that there is currently no compact protocol support available for NodeJS.
Please have a look at this SO question as well. It deals with C#, but nevertheless it can be helpful. There are also some solutions out there utilizing RabbitMQ or other message brokers, see here.

Resources