Cách xử lý DIRECT_LINE / POST_ACTIVITY_REJECTED

Nov 12 2020

Tôi đang triển khai webchat với mã thông báo dựa trên tính năng trò chuyện liên tục, mọi thứ hoạt động tốt khi người dùng trực tuyến, nhưng sau một thời gian nhàn rỗi nếu người dùng ngoại tuyến không có kết nối internet, trong khoảng 30-45 phút sau đó anh ta sẽ trực tuyến trở lại và bao giờ anh ta nhắn tin cho bất kỳ thứ gì mà bot đã chuyển sang trạng thái DIRECT_LINE / POST_ACTIVITY_REJECTED và người dùng không thể trò chuyện với bot, hãy gửi thử lại trên bong bóng tin nhắn của tôi. Có cách nào có thể để xử lý không ?.

 (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));

lưu ý: mã thông báo chưa hết hạn và Nếu tôi làm mới, bot của trang sẽ bắt đầu trả lời.

Trả lời

1 StevenKanberg Nov 17 2020 at 15:02

Tôi đã thực hiện một vài điều chỉnh đối với mã bạn cung cấp. Tôi tin rằng tokengiá trị của bạn đang bị ghi đè hoặc bị hỏng, vì vậy tôi đã tách riêng việc gán mã thông báo trong lệnh gọi API ( token) và gán biến trong tập lệnh ( dl_token).

Tôi cũng gặp lỗi khi gọi mã thông báo làm mới được gói trong setInterval()hàm, đó là lý do tại sao tôi sử dụng Babel, như được hiển thị bên dưới. (Đối với thử nghiệm, nó giúp xác định các lỗi có thể đã bị bỏ sót.). Việc xóa lệnh gọi API thực tế khỏi đó setInterval()và gọi nó như một hàm riêng biệt dường như đã khắc phục được điều này.

Sau những thay đổi này, mọi thứ dường như đang hoạt động trơn tru. Tôi chỉ thử nghiệm một vài lần khi đợi đến phút 45-50, nhưng không gặp bất kỳ sự cố nào với mã thông báo, cần phải làm mới hoặc nhận DIRECT_LINE/POST_ACTIVITY_REJECTED.

(Lưu ý rằng tôi đã thực hiện các cuộc gọi đến máy chủ 'mã thông báo' của riêng mình để tạo và làm mới mã thông báo.)

<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>

Mong được giúp đỡ!