I am developing a chat bot, where the user need to continue the chat after some days. So I am planning to store the session ID, to make make sure that the user can start the conversation form where he left.
Any solution for this?
According to the dialogflow documentation a context has a lifetime of 20 mins. Which indirectly means that the session has the same lifetime. But when I was trying this out I felt this is less than 20 mins. Which is more like 10-20 mins. Only storing the session ID won't help. You will have to save the contexts of the response received and send it with the request next time.
so i also tried this for a chatbot, here is what i did,i stored the dialog flow response context in db , and sent the last context stored in db with the request to dialogflow detectIntent after 30 min. and it worked fine .instead of hitting default fallback. it gave the expected intent response.
// request to dialogflow detect intent
const request = {
session: session,
queryInput: {
input
},
context:"last received context from dialogflow" //recent context from db
};
detectIntent(request).then(response=>{
const context = response.context; //response context
db.save(context); // save this in db
return response;
});
Related
I'm wondering if there is a way to asynchronously respond to MS Teams Task module fetch events. By asynchronous I mean that we would lose the original context of the request because we sent the original request to another service. So one service to receive the requests and another to actually process the events.
I tried to build a new context using TurnContext.getConversationReference along with TurnContext.SendActivity. While this successfully sent the "continue" task module body using the original turnContext, it didn't work using the new context that I created with conversation reference.
// Service A - simply ack the request and formats and enqueues the request to a queue
const conversationReference = TurnContext.getConversationReference(context.activity);
// send this conversationReference as part of the payload to another service
// Service B - dequeues from the queue and processes the request
await botFrameworkAdapter.continueConversation(conversationReference, async (newContext) => {
const response = await newContext.sendActivity({
type: "invokeResponse",
value: { status: 200, body: taskCardResponse },
});
});
Task module is being launched through when a user clicks on a messaging extension. When this is launched, messaging extension task fetch is triggered. The backend then returns a form in task module for the user to fill out and submit.
This is the original implementation and in the new approach, we can't simply return the form to the modal because we don't have access to the original request in the service B.
Diagram of Current vs Future interaction between services
Per the discussion in comments above, the code in the bot to launch the message extension can simply pass via querystring anything that is needed to actual web content page that is launched, and it can do whatever is necessary with what it receives.
My nestjs + React app has a Google oauth flow loosely based on this process. One thing that the Google library tries to help with is to take a refresh_token (that you've likely stored in your app's db) and use it to automatically retrieve a new access_token if the old one is expired. When it does this refresh, it emits a 'tokens' signal, and in my code I need something like
oauth2Client.on('tokens', async (tokens) => {
if (tokens.refresh_token) {
// store the refresh_token in your secure persistent database
console.log(tokens.refresh_token);
}
console.log(tokens.access_token);
});
It appears that the Google library intentionally does not let you proactively make a call to do the token refresh. The refresh happens automatically when you've set a refresh_token on the oauth2 client object and use that client object to next make any Google API call where the previous access_token has expired.
What I'm finding tricky is that when the above listener runs, I ideally would be able to get the 'current user' whose initial client session is what led to this server code path running. I can certainly create a chain of events like
User is logged into my app on the client
User does something on the frontend
A call to the server is made that has #UseGuards(AuthGuard()) and where I can get the user from the #Req
The above controller calls some additional functions, one of which can use the oauth2 client to make any random Google API call
If the random Google API call caused a token refresh, it would run the listener quoted above.
...but then, when #5 happens, is there any way to get the user detected in #3? Perhaps put another way, is there any way to 'inject' more info when the certain signal is emitted (but it's emitted in the Google library, not my code), or is there a way for the listener to pull the user from some kind of context?
(In case it matters, the emitter looks like this)
I, have this issue: when I start the bot it immediately starts looking for updates. However, in my particular case (especially during the developing) this can be very frustrating and uncomfortable. There is a way to tell the bot to process the update sent after the starting of the bot itself?
Thank you
You need to tell Telegram to "forget" those updates. This is how you would do it:
Send a request to: https://api.telegram.org/bot$TELEGRAM_TOKEN/getUpdates
Get the message_id of the last element (pop) of the result array
Send another request https://api.telegram.org/bot$TELEGRAM_TOKEN/getUpdates?offset=$OFFSET where $OFFSET is the message_id + 1
This is a stateless way of clearing pending requests. You can use curl,the browser or a request library (recommended) to do this. You can do this with node-telegram-bot-api but I don't recommend since you will have to create 2 bot instances, 1 polling and 1 non polling to clear the updates which is not a good practice since ntba doesn't decouple its methods in a different class.
So in pseudocode code:
const TOKEN = 'MY_TOKEN'
async function clearUpdates(token) {
const { result } = await request.get(`https://api.telegram.org/bot${token}/getUpdates`).json()
return await request.get(`https://api.telegram.org/bot${token}/getUpdates?offset=${result[result.length - 1].message_id + 1}`)
}
Now run clearUpdates before starting your bot.
I'm using socket stream to send the data to the logged in user by using the following code
var ss = require('socketstream');
....
....
ss.api.publish.user('userId', content);
but the ss.api.publish is undefined is what the error i'm receiving.
Where am i going wrong.
Please advice.
The API for a publish to a user is:
Sending to Users
Once a user has been authenticated (which basically means their session now includes a value for req.session.userId), you can message the user directly by passing the userId (or an array of IDs) to the first argument of ss.publish.user as so:
// in a /server/rpc file
ss.publish.user('fred', 'specialOffer', 'Here is a special offer just for you!');
Important: When a user signs out of your app, you should call req.session.setUserId(null, cb) to prevent the browser from receiving future events addressed to that userId. Note: This command only affects the current session. If the user is logged in via other devices/sessions these will be unaffected.
The above is taken from the original document describing the socketstream pub/sub api.
as you can see, you need to supply one more argument than you thought. That is, becasue on the client side you need to subscribe to a message channel in order to get the message. In the above example, you need to do this in your client side code:
ss.event.on('specialOffer', function(message){
alert(message);
});
I have a PHP application that has a chat functionality using nodejs and socket.io.
What I now need to do is to log the user out if the user is dormant for more than 15 minutes.
The sessions are shared between the PHP application and Nodejs server. So nodejs server knows when a user last logged in or when his/her last activity was.
I am thinking of sending a logoff command to the socket.io client, and it would be really easy if I could distinguish between the heartbeat and a message from a client.
As the PHP application would only know about the activity of a user on a page reload or navigation, the user could still be chatting while he is dormant and PHP application won't know if the user is chatting. So checking the last activity of a user from session won't work.
So main question here is, can I identify a client which has only been sending heartbeat for more than 15 minutes (no emits) ?
The easiest way to log off based on chat activity is to have a simple timer that is reset every time the user is chatting. Something like this:
io.sockets.on('connection', function(socket) {
// ...
var logoffTimer;
socket.on('chat', function() {
// clear the timer on activity
// should also update activity timestamp in session
clearTimeout(logoffTimer);
// set a timer that will log off the user after 15 minutes
logoffTimer = setTimeout(function(){
// add log off logic here
// you can also check session activity here
// and perhaps emit a logoff event to the client as mentioned
socket.emit("logoff", { reason: "Logged off due to inactivity" });
}, 60 * 15);
});
});