Cómo manejar DIRECT_LINE / POST_ACTIVITY_REJECTED
Estoy implementando el chat web con token basado junto con la persistencia del chat, todo funciona bien cuando el usuario está en línea, pero después de un tiempo de inactividad, si el usuario está desconectado sin conexión a Internet, durante aproximadamente 30-45 minutos y luego vuelve a estar en línea y cuando quiera enviar mensajes de texto a cualquier bot fue al estado DIRECT_LINE / POST_ACTIVITY_REJECTED y el usuario no pudo chatear con el bot, está regalando enviar reintento en mi burbuja de mensaje. ¿Hay alguna forma de manejarlo ?.
(async function() {
'use strict';
const {
hooks: { usePostActivity },
hooks: { useDirection },
ReactWebChat
} = window.WebChat;
let { token, conversation_Id } = sessionStorage;
if ( !token ) {
const res = await fetch( 'https:/localhost/api/generateToken', { method: 'POST' } );
const { token: directLineToken, conversationId: conversationId } = await res.json();
sessionStorage[ 'token' ] = directLineToken;
sessionStorage[ 'conversation_Id' ] = conversationId;
token = directLineToken;
conversation_Id = conversationId;
}
if (token) {
await setInterval(async () => {
var myHeaders = new Headers();
myHeaders.append("Authorization","Bearer "+ sessionStorage[ 'token' ]);
let res = await fetch( 'https://directline.botframework.com/v3/directline/tokens/refresh', {
method: 'POST',
headers: myHeaders,
});
const { token: directLineToken, conversationId } = await res.json();
sessionStorage[ 'token' ] = directLineToken;
sessionStorage[ 'conversation_Id' ] = conversationId;
token = directLineToken;
conversation_Id = conversationId;
}, 1000*60*15)}
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if(action.payload && action.payload.directLine) {
const subscription = action.payload.directLine.connectionStatus$.subscribe({
error: error => console.log( error ),
next: value => {
if ( value === 0 ) {console.log('Uninitialized')}
else if ( value === 1 ) {console.log('Connecting')}
else if ( value === 2 ) {console.log('Online')}
else if ( value === 3 ) {console.log('Expire Token')}
else if ( value === 4 ) {console.log('FailedToConnect')}
else if ( value === 5 ) {console.log('Ended')}
}
});
}
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'Welcome',
value: { language: window.navigator.language }
}
});
}
if (action.type === 'DIRECT_LINE/POST_ACTIVITY') {
action = window.simpleUpdateIn(action, ['payload', 'activity', 'channelData', 'CustomChannel'], () =>"webchat");
}
return next(action);
});
const botconnection = createDirectLine( {token,webSockets: true,watermark: "0" });
window.ReactDOM.render(
<ReactWebChat directLine={botconnection}
store={store}
/>,
document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
nota: el token no ha expirado y si actualizo la página, el bot comienza a responder.
Respuestas
Hice algunos ajustes en el código que proporcionaste. Creo que su tokenvalor se sobrescribió o se corrompió, así que separé la asignación del token en la llamada API ( token) y la asignación de variable en el script ( dl_token).
También recibí un error en la llamada del token de actualización envuelta en la setInterval()función, razón por la cual uso Babel, como se muestra a continuación. (Para las pruebas, ayuda a identificar errores que de otro modo se habrían pasado por alto). Eliminar la llamada a la API real setInterval()y llamarla como una función separada parecía solucionar esto.
Después de estos cambios, todo parece estar funcionando sin problemas. Solo probé unas pocas veces esperando hasta el minuto 45-50, pero no experimenté ningún problema con el token, necesidad de actualizar o recibir DIRECT_LINE/POST_ACTIVITY_REJECTED.
(Tenga en cuenta que hice llamadas a mi propio servidor 'token' para generar y actualizar el token).
<script crossorigin="anonymous" src="https://unpkg.com/@babel/[email protected]/babel.min.js"></script>
<script type="text/babel" data-presets="es2015,react,stage-3">
( async function () {
'use strict';
const {
ReactWebChat
} = window.WebChat;
let { dl_token, conversation_Id } = sessionStorage;
if ( !dl_token ) {
const res = await fetch( 'http://localhost:3500/directline/conversations', { method: 'POST' } );
const { token, conversationId } = await res.json();
sessionStorage[ 'dl_token' ] = token;
sessionStorage[ 'conversation_Id' ] = conversationId;
dl_token = token;
conversation_Id = conversationId;
}
if ( dl_token === sessionStorage['dl_token'] ) {
setInterval( () => {
refreshToken()
}, 1000 * 60 * 1 )
}
const refreshToken = async () => {
const res = await fetch( 'http://localhost:3500/directline/refresh', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
token: dl_token
})
} );
const { token, conversationId } = await res.json();
sessionStorage[ 'dl_token' ] = token;
sessionStorage[ 'conversation_Id' ] = conversationId;
dl_token = token;
conversation_Id = conversationId;
}
const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => action => {
if ( action.payload && action.payload.directLine ) {
const subscription = action.payload.directLine.connectionStatus$.subscribe( {
error: error => console.log( error ),
next: value => {
if ( value === 0 ) { console.log( 'Uninitialized' ) }
else if ( value === 1 ) { console.log( 'Connecting' ) }
else if ( value === 2 ) { console.log( 'Online' ) }
else if ( value === 3 ) { console.log( 'Expire Token' ) }
else if ( value === 4 ) { console.log( 'FailedToConnect' ) }
else if ( value === 5 ) { console.log( 'Ended' ) }
}
} );
}
if ( action.type === 'DIRECT_LINE/CONNECT_FULFILLED' ) {
dispatch( {
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'Welcome',
value: { language: window.navigator.language }
}
} );
}
if ( action.type === 'DIRECT_LINE/POST_ACTIVITY' ) {
action = window.simpleUpdateIn( action, [ 'payload', 'activity', 'channelData', 'CustomChannel' ], () => "webchat" );
}
return next( action );
} );
const botconnection = await createDirectLine( { token: dl_token } );
window.ReactDOM.render(
<ReactWebChat directLine={botconnection}
store={store}
/>,
document.getElementById( 'webchat' ) );
document.querySelector( '#webchat > *' ).focus();
} )().catch( err => console.error( err ) );
</script>
¡Esperanza de ayuda!