How to connect Javascript to a remote IBM MQ? - node.js

I'm making APIs with LoopBack( a Javascript Framework), pushing and getting messages with IBM MQ.
I followed this tut: Nodejs and MQ
I can do it with local Queue Manager, but I dont know how to connect to a remote Queue Manager.
So, can any one explain me how to do this ?
Tks all.

I can do it with that link, which from #JoshMc's comment.
This is my code, it works fine:
module.exports = function (server) {
var mq = require('ibmmq');
var MQC = mq.MQC; // Want to refer to this export directly for simplicity
// The queue manager and queue to be used. These can be overridden on command line.
var qMgr = "QM1";
var qName = "soa.log";
var mqmd = new mq.MQMD(); // Defaults are fine.
var pmo = new mq.MQPMO();
var cd = new mq.MQCD();
var cno = new mq.MQCNO();
cd.ConnectionName = "localhost(1414)";
cd.ChannelName = "CHAN1";
var csp = new mq.MQCSP();
cno.ClientConn = cd;
cno.Options = MQC.MQCNO_CLIENT_BINDING; // use MQCNO_CLIENT_BINDING to connect as client
function putMessage(hObj) {
var msg = Buffer.from(JSON.stringify(coff));
// Describe how the Put should behave
pmo.Options = MQC.MQPMO_NO_SYNCPOINT |
MQC.MQPMO_NEW_MSG_ID |
MQC.MQPMO_NEW_CORREL_ID;
mq.Put(hObj,mqmd,pmo,msg,function(err) {
if (err) {
console.log(formatErr(err));
} else {
console.log("MQPUT successful");
}
});
}
mq.Connx(qMgr, cno, function (err, hConn) {
if (err) {
console.log((err));
} else {
console.log("MQCONN to %s successful ", qMgr);
// Define what we want to open, and how we want to open it.
var od = new mq.MQOD();
od.ObjectName = qName;
od.ObjectType = MQC.MQOT_Q;
var openOptions = MQC.MQOO_OUTPUT;
mq.Open(hConn, od, openOptions, function (err, hObj) {
if (err) {
console.log(formatErr(err));
} else {
console.log("MQOPEN of %s successful", qName);
putMessage(hObj);
}
// cleanup(hConn, hObj);
});
}
});
};

Related

Create and handle multiple session for multiple users while making web socket connection in Microsoft Bot Builder

I am new to Microsoft Bot Framework .I have created a bot using Microsoft Bot Framework. How do I create a session for individual user. Currently the problem I am facing is whenever multiple users are creating connection, the values in the variables are getting over written thus giving wrong values to the users.
Here is the code
if (turnContext.activity.text === 'CCP') {
const url = await this.connectToAgent(members);
const initialMessage = {
topic: "aws/subscribe",
content: {
topics: ["aws/chat"]
}
};
ws = new WebSocket(url[1]);
ws.addEventListener("open", () => {
ws.send(JSON.stringify(initialMessage));
});
await turnContext.sendActivity("Please wait while we connect you to an agent.");
conversationReferences[currentUser] = TurnContext.getConversationReference(turnContext.activity);
adapter = turnContext.adapter;
ws.addEventListener('message', async function (event) {
const msg = JSON.parse(event.data);
});
let sendChatHistory = (function() {
let executed = false;
return function() {
if (!executed) {
executed = true;
const param = {
ConnectionToken: connectionToken, /* required */
Content: sendHistory, /* required */
ContentType: 'text/plain', /* required */
};
connectparticipant.sendMessage(param,async function (err, data) {
chatHistory = '';
sendHistory = '';
if (err) {
errorMsg = "Error while sending a message";
}
});
}
};
})();
sendChatHistory();
}
According to the official documentation we have the procedure of StateClient where we can give separate activity holder for individual users. This works when we are creating multiple users with multiple connections.
StateClient sc = activity.GetStateClient();
userData.SetProperty<string>("MyDetails", < some value >);
// How to save the BotUserData
await sc.BotState.SetUserDataAsync(activity.ChannelId, activity.From.Id, userData);
// Getting User data from bot
BotData userData = await sc.BotState.GetUserDataAsync(activity.ChannelId, activity.From.Id);
As this is a parallel operation, the method Async is required to get the data of user simultaneously.

How to connect my electron app using PouchDB (leveldb) with Cloudant or any other database that support couchDB and sync

I'm creating an electron app using pouchDB and I want the app to be able to diferents customers and sync the data between them. As an example I'm making the tutorial: https://github.com/nolanlawson/pouchdb-getting-started-todo, I adapt the code to electron and I created a noSQL database at cloudant.
At the moment I can save data but I cannot sync with my remote db that is in cloudant. Here is the endpoint I'm using to sync data between both database.
Here is the error that I'm getting.
Here is the code of my script.js
(function() {
'use strict';
var $ = document.querySelector.bind(document);
var ENTER_KEY = 13;
var newTodoDom = document.getElementById('new_todo');
var syncDom = document.getElementById('sync-wrapper');
// EDITING STARTS HERE (you dont need to edit anything above this line)
var NodePouchDB = require('pouchdb');
var db = new NodePouchDB('todos');
var couchdb = require('felix-couchdb')
var remoteCouch = couchdb.createClient(5984, 'https://ac725f4e-29ec-4614-8e96-02ebc74a529b-bluemix.cloudant.com/')
db.info(function(err, info) {
console.log("is working", info)
db.changes({
since: info.update_seq,
live: true
}).on('change', showTodos);
});
// We have to create a new todo document and enter it in the database
function addTodo(text) {
var todo = {
_id: new Date().toISOString(),
title: text,
completed: false
};
db.put(todo).then(function (result) {
console.log("everything is A-OK");
console.log(result);
}).catch(function (err) {
console.log('everything is terrible');
console.log(err);
});
}
// Show the current list of todos by reading them from the database
function showTodos() {
db.allDocs({include_docs: true, descending: true}).then(function(doc) {
redrawTodosUI(doc.rows);
}).catch(function (err) {
console.log(err);
});
}
function checkboxChanged(todo, event) {
todo.completed = event.target.checked;
console.log(todo);
db.put(todo);
}
// User pressed the delete button for a todo, delete it
function deleteButtonPressed(todo) {
db.remove(todo);
}
// The input box when editing a todo has blurred, we should save
// the new title or delete the todo if the title is empty
function todoBlurred(todo, event) {
var trimmedText = event.target.value.trim();
if (!trimmedText) {
db.remove(todo);
} else {
todo.title = trimmedText;
db.put(todo);
}
}
// Initialise a sync with the remote server
function sync() {
syncDom.setAttribute('data-sync-state', 'syncing');
var opts = {live: true};
db.sync(remoteCouch, opts, syncError);
}
// EDITING STARTS HERE (you dont need to edit anything below this line)
// There was some form or error syncing
function syncError() {
syncDom.setAttribute('data-sync-state', 'error');
}
// User has double clicked a todo, display an input so they can edit the title
function todoDblClicked(todo) {
var div = document.getElementById('li_' + todo._id);
var inputEditTodo = document.getElementById('input_' + todo._id);
div.className = 'editing';
inputEditTodo.focus();
}
// If they press enter while editing an entry, blur it to trigger save
// (or delete)
function todoKeyPressed(todo, event) {
if (event.keyCode === ENTER_KEY) {
var inputEditTodo = document.getElementById('input_' + todo._id);
inputEditTodo.blur();
}
}
// Given an object representing a todo, this will create a list item
// to display it.
function createTodoListItem(todo) {
var checkbox = document.createElement('input');
checkbox.className = 'toggle';
checkbox.type = 'checkbox';
checkbox.addEventListener('change', checkboxChanged.bind(this, todo));
var label = document.createElement('label');
label.appendChild( document.createTextNode(todo.title));
label.addEventListener('dblclick', todoDblClicked.bind(this, todo));
var deleteLink = document.createElement('button');
deleteLink.className = 'destroy';
deleteLink.addEventListener( 'click', deleteButtonPressed.bind(this, todo));
var divDisplay = document.createElement('div');
divDisplay.className = 'view';
divDisplay.appendChild(checkbox);
divDisplay.appendChild(label);
divDisplay.appendChild(deleteLink);
var inputEditTodo = document.createElement('input');
inputEditTodo.id = 'input_' + todo._id;
inputEditTodo.className = 'edit';
inputEditTodo.value = todo.title;
inputEditTodo.addEventListener('keypress', todoKeyPressed.bind(this, todo));
inputEditTodo.addEventListener('blur', todoBlurred.bind(this, todo));
var li = document.createElement('li');
li.id = 'li_' + todo._id;
li.appendChild(divDisplay);
li.appendChild(inputEditTodo);
if (todo.completed) {
li.className += 'complete';
checkbox.checked = true;
}
return li;
}
function redrawTodosUI(todos) {
var ul = document.getElementById('todo-list');
ul.innerHTML = '';
todos.forEach(function(todo) {
ul.appendChild(createTodoListItem(todo.doc));
});
}
function newTodoKeyPressHandler( event ) {
if (event.keyCode === ENTER_KEY) {
addTodo(newTodoDom.value);
newTodoDom.value = '';
}
}
function addEventListeners() {
newTodoDom.addEventListener('keypress', newTodoKeyPressHandler, false);
}
addEventListeners();
showTodos();
if (remoteCouch) {
sync();
}
})();
To get to where the problem sits, can you verify that you can speak to the Cloudant database normally, that is using curl from the command-line? Using curl, fetch a document by its _id, perhaps a document you created manually using the Cloudant dashboard. That should shake out any problems with authentication: I note you're using IAM, which isn't always straight-forward -- and to my knowledge, not supported by PouchDB (or wasn't, last time I looked).
If that is the problem, create a new Cloudant instance with IAM+Legacy credentials.

Log the conversation to Azure CosmosDB with nodejs

We're trying to save the conversations for analytics purposes, and since we're using CosmosDB to store the User and Conversation States, we would like to log the conversations there too.
I've been able to find ways to do so using BlobStorage but that isn't really possible for us.
Is there any way or implementation that we can follow/use to log into CosmosDB?
Thanks
I created a custom logger to do this. This is implemented in index.js via TranscriptLoggerMiddleware (part of botbuilderlibrary). The main additions to index.js here are:
const { TranscriptLoggerMiddleware } = require('botbuilder')
const { CustomLogger } = require('./helpers/CustomLogger');
const logger = new TranscriptLoggerMiddleware(new CustomLogger());
adapter.use(logger);
For the logger itself, because of the speed of the request/response, we found that often only one part of the conversation was getting logged. So we created a for-loop delay function. I've tried other methods such as awaiting a promise, but it didn't fix the issue. This has been rock solid after adding the delay. Here is the full custom logger code:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
const { CosmosDbStorage } = require('botbuilder-azure');
class CustomLogger {
// Set up Cosmos Storage
constructor() {
this.transcriptStorage = new CosmosDbStorage({
serviceEndpoint: process.env.ACTUAL_SERVICE_ENDPOINT,
authKey: process.env.ACTUAL_AUTH_KEY,
databaseId: process.env.DATABASE,
collectionId: 'bot-transcripts'
});
this.conversationLogger = {};
this.msDelay = 250;
}
async logActivity(activity) {
if (!activity) {
throw new Error('Activity is required.');
}
// Log only if this is type message
if (activity.type === 'message') {
// Check if activity contains a card
if (activity.attachments) {
var logTextDb = `${activity.from.name}: ${activity.attachments[0].content.text}`;
} else {
var logTextDb = `${activity.from.name}: ${activity.text}`;
}
if (activity.conversation) {
var id = activity.conversation.id;
if (id.indexOf('|') !== -1) {
id = activity.conversation.id.replace(/\|.*/, '');
}
// Get today's date for datestamp
var currentDate = new Date();
var day = currentDate.getDate();
var month = currentDate.getMonth()+1;
var year = currentDate.getFullYear();
var datestamp = year + '-' + month + '-' + day;
var fileName = `${datestamp}_${id}`;
var timestamp = Math.floor(Date.now()/1);
// Prep object for CosmosDB logging
if (!(fileName in this.conversationLogger)) {
this.conversationLogger[fileName] = {};
this.conversationLogger[fileName]['botName'] = process.env.BOTNAME;
}
this.conversationLogger[fileName][timestamp] = logTextDb;
let updateObj = {
[fileName]:{
...this.conversationLogger[fileName]
}
}
// Add delay to ensure messages logged sequentially
await this.wait(this.msDelay);
// Write to CosmosDB
try {
let result = await this.transcriptStorage.write(updateObj);
console.log(`Transcript written successfully to DB\n\n`);
} catch(err) {
console.log(`There was an error writing the transcript to DB`);
console.log(err);
}
}
}
}
async wait(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds) {
break;
}
}
}
}
exports.CustomLogger = CustomLogger;

Node js client for grpc server

I have GRPC server running using openssl - static way and I am trying to connect to server using nodejs client
I do not see any error but I do not see its connecting to server either.
Please share if you have any sample.
Please refer code below:
var rootCertPath = path.join('.','.', 'server-root.PEM');
var privateCertPath = path.join('.','.', 'server-private.PEM');
var domainCertPath = path.join('.','.', 'server-domain.PEM');
var rootCert = fs.readFileSync(rootCertPath);
var privateCert = fs.readFileSync(privateCertPath);
var domainCert = fs.readFileSync(domainCertPath);
var buf1 = new Buffer('rootCert');
var buf2 = new Buffer('privateCert');
var buf3 = new Buffer('domainCert');
var chat_proto = grpc.load("Chat.proto").com.company.grpc;
var client = new chat_proto.ChatService('https://servervip:443',grpc.credentials.createSsl(buf1,buf2,buf3));
Chat.proto
syntax = "proto3";
// Service definition.
service ChatService {
// Sends a chat
rpc chat(stream ChatMessage) returns (stream ChatMessageFromServer) {}
}
// The request message containing the user's name.
message ChatMessage {
string name = 1;
string message = 2;
}
// The response message containing the greetings
message ChatMessageFromServer {
string name = 1;
string message = 2;
}
//Code to make a request
var username = process.argv[2];
var stdin = process.openStdin();
function main() {
console.log("starting");
console.log(client); // prints { '$channel': Channel {} }
var chat=client.chat();
chat.on('data', function(msg) {
console.log(msg.name + ': ' + msg.message);
console.log("after message");
});
stdin.addListener('data',function(input) {
chat.write({ name: username, message: input.toString().trim()
});
});
}
main();
so good new is - below thing worked for me
var rootCertPath = path.join('.','.', 'roots.PEM');
var rootCert = fs.readFileSync(rootCertPath);
var chat_proto = grpc.load("Chat.proto").com.americanexpress.grpc.chat;
var client = new chat_proto.ChatService('servervip:443',grpc.credentials.createSsl(rootCert));
Looks like an issue with the cert - I used the default roots.PEM in grpc client and it worked for me. will look internally to have correct root of my servervip CA certificate chain.
Thanks all for your support

nodejs process.exit() prevents function from executing properly

I am writing my first NodeJs script. Below is some code I have set up to test a database connection.
When I include process.exit() at the very end of the script, nothing is logged to the console - however, when I simply remove that line of code, the function logs the query results appropriately (output included also).
I am wondering why the process.exit() at the very end of the code prevents the function from functioning and if I am using the exit method wrong.
Code:
/*
* Runs every minute on an uptime agent
* Checks list of sites to see if they're up
*/
// strict mode (see http://stackoverflow.com/questions/8651415/what-is-strict-mode-and-how-is-it-used for information)
'use strict';
// cuz im lazy
String.prototype.lc = function() { return this.toLowerCase(); }
String.prototype.uc = function() { return this.toUpperCase(); }
/** EXCEPTIONS **/
var DbConnectError = function(m) {
this.name = 'DbConnectError';
this.message = m;
}
var DbConfigError = function(m) {
this.name = 'DbConfigError';
this.message = m;
}
/** DATABSE **/
/*
* change log
* 08/07/2015 Tyler J Barnes
* -- init dev
*/
var db = function() {
// error messages
this._errors = [];
// connection state
this._isConnected = false;
// db configuration
this._config = {
host: '',
user: '',
password: '',
database: ''
};
// reference
this._db = null;
// connection obj ref
this._con = null;
// sql statement
this._sqlStmt = '';
// is prepared statement -- needs data binded
this._isPrepared = false;
// data to bind to prepared stmts
this._sqlData = null;
// query result set
this._result = null;
/*
* initialize
* #param (object) : cofig prop and values
* #return void
*/
this.ini = function(config) {
// make sure config was passed
if(!config || (typeof config).lc() != 'object') {
throw new DbConnectError('Invalid DB Configuration');
}
// check for appropriate properties
// if exist, store value
for(var p in this._config) {
if(!(p in config)) {
this._errors.push('Missing database config: '+p+'\n');
} else {
this._config[p] = config[p];
}
}
// throw any errors before continue
if(this._errors.length > 0) {
var tmp = '';
for(var i = 0; i < this._errors.length; i++) {
tmp+=this._errors[i];
}
throw new DbConfigError(tmp);
}
this._db = require('mysql');
};
// create connection -- returns thread id
this.con = function() {
this._con = this._db.createConnection(this._config);
this._con.connect();
this._isConnected = true;
};
// sets sql statement
this.setSqlStmt = function(str, prepared, bindData) {
this._sqlStmt = str;
if(prepared) {
this._isPrepared = true;
this._sqlData = bindData;
} else {
this._isPrepared = false;
this._sqlData = null;
}
};
// kills connection
this.die = function() {
if(this._isConnected) {
this._con.end();
}
};
}
var c = {
host: 'asdfasdf',
user: 'asdfasdf',
password: 'asdfasdf',
database: 'asdfasdf'
};
var d = new db();
d.ini(c);
d.con();
d._con.query('SELECT * FROM Agents', function(err,rows,fields) {
if(err) console.log(err);
console.log(rows);
});
d._con.end();
// this is what upsets me
process.exit();
Output when process.exit() is removed:
[{agentid:1, host: 'asdfasdfadf'....etc}]
The database query operation is asynchronous. This means that it will only be concluded after the program executes all of the main module, including the exit system call.
Instead, you should only terminate the process when the results are obtained from the database:
var d = new db();
d.ini(c);
d.con();
d._con.query('SELECT * FROM Agents', function(err,rows,fields) {
if(err) console.log(err);
console.log(rows);
process.exit();
});
d._con.end();
This is one of the typical misunderstandings of how JavaScript's asynchronous function calls work. I would advise you to read on the subject. These two questions may have some useful content:
How does Asynchronous Javascript Execution happen? and when not to use return statement?
How does JavaScript handle AJAX responses in the background?

Resources