PubNub How to handle failed requests - pubnub

I'm using Pubnub JS and need to handle subscribe request fails like 400 403 etc
addListener method don't have such option to handle error

You want to listen for status events and filter by category, i.e.:
pubnub.addListener({
status: function (s) {
const affectedChannelGroups = s.affectedChannelGroups; // Array of channel groups affected in the operation
const affectedChannels = s.affectedChannels; // Array of channels affected in the operation
const category = s.category; // Returns category (status event)
const operation = s.operation; // Returns PNSubscribeOperation
const lastTimetoken = s.lastTimetoken;
const currentTimetoken = s.currentTimetoken;
const subscribedChannels = s.subscribedChannels;
},
});
For a list of categories, see https://www.pubnub.com/docs/sdks/javascript/api-reference/configuration#listener-status-events. I'm not sure how they map to the specific 4xx error codes but there is a dedicated PNUnknownCategory for non-200 responses.

Related

Get user join / leave events retroactively from Channels

I'm trying to do some analytics on average response time from some of our users on Twilio Chat.
I'm iterating through my channels, and I'm able to pull the info about messages, so I can compare times a message went un-responded to. However, I can't determine which users were in the channel at that time.
Is there anything on the channel that would give me historic member data? Who was in the channel? The channel.messages().list() method is only giving me the text of the messages sent to the channel and who it was by, but the user who may have been in a channel to respond changes throughout a channel's life time.
This is on the backend using the node.js SDK. note: This isn't a complete implementation for what I'm trying to do, but taking it in steps to get access to the information I'd need to do this. Once I have these messages and know which users are supposed to be in a channel at a given time, I can do the analytics to see how long it took for the users I am looking for to respond.
var fs = require('fs');
const Twilio = require('twilio');
const client = new Twilio(env.TWILIO_ACCOUNT_SID, env.TWILIO_AUTH);
const service = client.chat.services(env.TWILIO_IPM_SERVICE_SID);
async function getChatMessages() {
const fileName = 'fileName.csv';
const getLine = message => {
return `${message.channelSid},${message.sid},${message.dateCreated},${message.from},${message.type},${message.body}\n`;
}
const writeToFile = message => { fs.appendFileSync(fileName, getLine(message)); };
const headerLine = `channelSid,messageSid,dateCreated,author,type,body`;
fs.writeFileSync(fileName, headerLine);
await service.channels.each(
async (channel, done) => {
i++;
let channelSid = channel.sid;
if( channel.messagesCount == 0 ) return;
try {
await channel.messages().list({limit:1000, order:"asc"}).then(
messages => {
messages.forEach( writeToFile );
}
);
} catch(e) {
console.log(`There was an error getting messages for ${channelSid}: ${e.toString()}`);
}
if( i >= max ) done();
}
);
}
I'm beginning to be resigned to the fact that maybe this would only have been possible to track had I set up the proper event listeners / webhooks to begin with. If that's the case, I'd like to know so I can get that set up. But, if there's any endpoint I can reach out to and see who was joining / leaving a channel, that would be ideal for now.
The answer is that unfortunately you can not get this data retroactively. Twilio offers a webhooks API for chat which you can use to track this data yourself as it happens, but if you don't capture the events, you do not get access to them again.

Cannot Perform HTTP Request in Hyperledger Composer

I am trying to create a business network which demonstrates nondeterministic behaviour by requesting a random number from a URL (https://random-number-api.mybluemix.net/random).
However, when I invoke the transaction from, the following error appears:
TypeError: request.get is not a function
In the documentation (https://hyperledger.github.io/composer/latest/integrating/call-out), it is mentioned that request is global and can be used directly.
To test the URL,
curl -X GET https://random-number-api.mybluemix.net/random
I am using Composer 0.18.2.
The following is the code. The whole business network definition is found here: https://github.com/caveman7/nondeterministic
async function createStock(request) {
const factory = getFactory();
const namespace = 'org.nondeterministic';
const stock = factory.newResource(namespace, 'Stock', request.stockId);
const priceAsStr = await request.get({uri: 'https://random-number-api.mybluemix.net/random'});
stock.price = parseInt(priceAsStr);
//stock.price = getPrice();
console.log('#debug - Stock Price Generated is: USD' + stock.price);
const ar = await getAssetRegistry(namespace + '.Stock')
await ar.add(stock);
}
const getPrice = () => {
const price = Math.floor((Math.random() * 10000) + 1);
return price;
}
probably because you're providing request as an object to the TP. As shown above or https://github.com/caveman7/nondeterministic/blob/master/lib/script.js#L22
Errors as its 'not' got a method called get?. It should be async function createStock(createStock ) to match the parameter name in the transaction decorator (tracing the github script file from the above link) - and then you should be able to access request.get() as you would expect (since request.get came in in 0.18.1 IIRC).

Twilio - Incoming calls not being processed (quickstart)

I've sign up to start using Twilio and I'm trying to setup the quickstart (https://www.twilio.com/docs/voice/client/javascript/quickstart) and it's almost working but incoming calls are not being received by:
Client code (used on browser after getTokenCapabilities):
Twilio.Device.incoming(function (conn) {
log('Incoming connection from ' + conn.parameters.From);
var archEnemyPhoneNumber = '+12093373517';
if (conn.parameters.From === archEnemyPhoneNumber) {
conn.reject();
log('It\'s your nemesis. Rejected call.');
} else {
// accept the incoming connection and start two-way audio
conn.accept();
}
});
Code on Twilio Function for voice calls (consoles are always printed and else condition is never called:
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.VoiceResponse();
console.log('entrou aqui');
if(event.To) {
console.log('entrou ali');
// Wrap the phone number or client name in the appropriate TwiML verb
// if is a valid phone number
const attr = isAValidPhoneNumber(event.To) ? 'number' : 'client';
const dial = twiml.dial({
callerId: context.CALLER_ID,
});
dial[attr]({}, event.To);
} else {
twiml.say('Thanks for calling!');
}
console.log('callback');
callback(null, twiml);
};
/**
* Checks if the given value is valid as phone number
* #param {Number|String} number
* #return {Boolean}
*/
function isAValidPhoneNumber(number) {
return /^[\d\+\-\(\) ]+$/.test(number);
}
I've include my phone number as Verified Caller ID, got a number from Twilio and create the functions using template Twilio Client Quickstart.
On Twilio Client Quickstart, i've paste TwiML SID as TWIML_APP_SID and tried to use my phone number and the number from Twilio as CALLER_ID.
Also I've changed VOICE URL on TwiML configuration and changed the VOICE URL on phone number from twilio configuration.
Any ideas on what is missing or what is wrong? When I open on browser http://127.0.0.1:8080/, It's possible to make calls but I don't receive any call on browser when I call to twilio number.
In order to answer call, you need to have your token name identity in a tag in your VoiceResponse, here is an example.
exports.incomingVoiceResponse = function voiceResponse( to ) {
// Create a TwiML voice response
const twiml = new VoiceResponse();
// Wrap the phone number or client name in the appropriate TwiML verb
// if is a valid phone number
const attr = isAValidPhoneNumber(to) ? 'client' : 'number';
const dial = twiml.dial({
callerId: to,
});
dial[attr]({}, 'jesus');
console.log(twiml.toString())
return twiml.toString();
};
See the 'jesus' client tag I have put ? Here is the token generator side :
exports.tokenGenerator = function tokenGenerator() {
const identity = 'jesus';
const capability = new ClientCapability({
accountSid: config.accountSid,
authToken: config.authToken,
});
capability.addScope(new ClientCapability.IncomingClientScope(identity));
capability.addScope(new ClientCapability.OutgoingClientScope({
applicationSid: config.twimlAppSid,
clientName: identity,
}));
// Include identity and token in a JSON response
return {
identity: identity,
token: capability.toJwt(),
};
};
This works for me using the node quickstart as is and changing both of these functions.
However, don't forger to change the from 'number' to 'client' in function voiceResponse because it's an incoming call and not an outgoing.
const attr = isAValidPhoneNumber(to) ? 'client' : 'number';
instead of
const attr = isAValidPhoneNumber(to) ? 'number' : 'client';
Since the default nameGenerator from the client-quickstart-node from Twilio generates a random name, it isn't properly set when receiving incoming call.

How to log the response message in a Registered Handler - ServiceStack RabbitMQ

Given this snippet of code:
//DirectApi
mqServer.RegisterHandler<LeadInformationInfo>(m =>
{
repository.SaveMessage(m as Message);
LeadInformationInfoResponse response = new LeadInformationInfoResponse();
try
{
var client = new JsonServiceClient(settingsFactory.GetMasterSetting("ProcessorApi:baseUri"));
response = client.Post(m.GetBody());
}
catch (WebServiceException webServiceException)
{
_log.Error("RegisterHandler<LeadInformationInfo>", webServiceException);
response = ((LeadInformationInfoResponse) webServiceException.ResponseDto);
response.CorrelationId = m.Id;
}
// Log response message here
return response;
}, 1);
I've gone to great lengths to make sure that a correlationId based off the original message Id property is propagated through the life of this message and any child messages spawned from this action. How do I get a handle on the response message so that I may log it in the handler? I only have access to the ResponseDto and not the message.
One of the reasons for this request is that the message queue client does not have access to the database, only the process that has the handler registered does. Hope that explains the situation better.
Just to clarify, this question is about persisting a MQ Response Message in the handler, the correlation Id is something that all messages in 1 request/response workflow will share. I'm also using ServiceStack ORMlite to persist the Message object, so querying this table by ID for troubleshooting is paramount.
Thank you,
Stephen
You're calling a WebService from within your MQ Handler:
var client = new JsonServiceClient(...);
response = client.Post(m.GetBody());
So there is no MQ Response which is only available in MQ Services. Although the WebService will return the response for the request that's sent so you can either use the CorrelationId on the MQ Request, otherwise you can have your Response DTO implement an interface like IHasCorrelationId and get it that way, e.g:
var correlationResponse = response as IHasCorrelationId;
if (correlationResponse != null)
{
var correlationId = correlationResponse.CorrelationId;
}
Create your own Instance of Message
As the Message<T> class is just a POCO if you wanted to create your own you can intialize your own instance:
var mqResponse = new Message<Response>(response);
If you only had the runtime late-bound type info, you can create one with:
var mqResponse = MessageFactory.Create(response);
Use RabbitMQ Message Filters
If you just wanted to log incoming and outgoing messages you can use the RabbitMQ Message Filters, e.g:
var mqServer = new RabbitMqServer("localhost")
{
PublishMessageFilter = (queueName, properties, msg) => {
properties.AppId = "app:{0}".Fmt(queueName);
},
GetMessageFilter = (queueName, basicMsg) => {
var props = basicMsg.BasicProperties;
receivedMsgType = props.Type; //automatically added by RabbitMqProducer
receivedMsgApp = props.AppId;
}
};

agent.set.context() not working Dialogflow fulfillment

We are facing issues while managing multiple user interaction at the same time in Dialogflow.
How we can manage user unique session as we are using custom event which will process our 3rd party API and then return a response to the specific user.
To manage User unique session We try Dailogflow Set/Get Context method, to set Context with Unique Id (using this id will store API response to the Redis server) from the first intent when a user makes a first request then will traverse that Unique Id through the custom event.
Will get that Unique Id from Context and grab data from Redis server which we stored in first intent.
We used agent.set.context() to set unique id but this method is not working with "dialogflow-fulfillment"  version ^0.5.0, To get this work we have updated the version with "^0.6.1". But this will provide other error like "UnhandledPromiseRejectionWarning: Error: No responses defined for platform: null".
Required Output: Context set with a unique id and will get a proper response.
Current Output: UnhandledPromiseRejectionWarning: Error: No responses defined for platform: null
async function searchFromAPI(agent){
axios.post('https://testApi.com', searchString.data, {headers: headers})
.then((resp) => {
response.data = resp;
redisClient.set(sessionId, JSON.stringify(response));
}
}).catch(error => {
response.error = true;
response.message = error.response.statusText;
redisClient.set(sessionId, JSON.stringify(response));
});
await customsleep(2000);
const sessionId = uuid.v4();
const contextData = {'name':'userSession','lifespan': 5,'parameters':{'sessionId':sessionId}};
agent.context.set(contextData);
console.log(contextData);
agent.add('We are processing your request, Could you please wait?');
agent.add(new Suggestion("Yes"));
agent.add(new Suggestion("No"));
}
// wait for 4.5sec and call custom event
async function followOne(agent){
await customsleep(4500);
agent.setFollowupEvent('followUpTwo');
}
// wait for 4.7sec then red API response from redis server and return
async function followUpTwo(agent){
await customsleep(4000);
sess = session;
//get context
const response = agent.context.get('userSession');
// get the sessionId, Get the data from redis server
agent.add(response);
}
async function PleaseWait(agent){
await customsleep(3500);
agent.setFollowupEvent('followUpOne');
}
I found the only workaround to reassign a new context object via context.set(ctx). Then it worked.
//update context to show full menu
let context = agent.context.get('user_data');
if (!context) throw "User_data context ius nod defined in PreferrenceAdd"
let context2 = new Object();
context2 = {'name': 'user_data', 'lifespan': 40,
'parameters': context.parameters};
console.log("ctx: = " + JSON.stringify(context2));
context2.parameters.new = false;
context2.parameters.refresh = true;
agent.context.set(context2);
Check this resource on how to set a new Dialogflow outgoing context
dialogflow webhook-client.
I hope this helps you?

Resources