Come gestire DIRECT_LINE / POST_ACTIVITY_REJECTED
Sto implementando webchat con token basato insieme alla persistenza della chat, tutto funziona bene quando l'utente è online, ma dopo un po 'di tempo di inattività se l'utente è offline senza connettività Internet, per circa 30-45 minuti poi torna online e quando mai lui inviare messaggi di testo a qualsiasi cosa bot è andato allo stato DIRECT_LINE / POST_ACTIVITY_REJECTED e l'utente non è stato in grado di chattare con il bot, sta dando via, invia un nuovo tentativo sul mio messaggio. C'è un modo possibile per gestire ?.
(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: il token non è scaduto e se aggiorno la pagina il bot inizia a rispondere.
Risposte
Ho apportato alcune modifiche al codice che hai fornito. Credo che il tuo tokenvalore venisse sovrascritto o danneggiato, quindi ho separato l'assegnazione del token nella chiamata API ( token) e l'assegnazione della variabile nello script ( dl_token).
Ho anche ricevuto un errore sulla chiamata del token di aggiornamento avvolta nella setInterval()funzione, motivo per cui uso Babel, come mostrato di seguito. (Per i test, aiuta a identificare gli errori che altrimenti sarebbero stati persi.). La rimozione della chiamata API effettiva da setInterval()e la chiamata come funzione separata sembrava risolvere questo problema.
Dopo queste modifiche, tutto sembra funzionare senza problemi. Ho provato solo poche volte aspettando fino al minuto 45-50, ma non ho riscontrato alcun problema con il token, che necessitava di aggiornamento o ricezione DIRECT_LINE/POST_ACTIVITY_REJECTED.
(Tieni presente che ho effettuato chiamate al mio server "token" per generare e aggiornare il 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>
Speranza di aiuto!