mirror of
				https://github.com/hexastack/hexabot
				synced 2025-06-26 18:27:28 +00:00 
			
		
		
		
	fix: re-subscribe on ws reconnect
This commit is contained in:
		
							parent
							
								
									dee2eb5c81
								
							
						
					
					
						commit
						2b433ef755
					
				| @ -1,11 +1,12 @@ | |||||||
| /* | /* | ||||||
|  * Copyright © 2024 Hexastack. All rights reserved. |  * Copyright © 2025 Hexastack. All rights reserved. | ||||||
|  * |  * | ||||||
|  * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: |  * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: | ||||||
|  * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. |  * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. | ||||||
|  * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). |  * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| import React, { | import React, { | ||||||
|   SyntheticEvent, |   SyntheticEvent, | ||||||
|   useCallback, |   useCallback, | ||||||
| @ -75,7 +76,7 @@ const UserSubscription: React.FC = () => { | |||||||
|         }); |         }); | ||||||
|         setMessages(messages); |         setMessages(messages); | ||||||
|         setParticipants([ |         setParticipants([ | ||||||
|           ...participants, |           participants[0], | ||||||
|           { |           { | ||||||
|             id: profile.foreign_id, |             id: profile.foreign_id, | ||||||
|             foreign_id: profile.foreign_id, |             foreign_id: profile.foreign_id, | ||||||
|  | |||||||
| @ -1,11 +1,12 @@ | |||||||
| /* | /* | ||||||
|  * Copyright © 2024 Hexastack. All rights reserved. |  * Copyright © 2025 Hexastack. All rights reserved. | ||||||
|  * |  * | ||||||
|  * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: |  * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: | ||||||
|  * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. |  * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. | ||||||
|  * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). |  * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| import React, { | import React, { | ||||||
|   createContext, |   createContext, | ||||||
|   ReactNode, |   ReactNode, | ||||||
| @ -268,7 +269,7 @@ const ChatProvider: React.FC<{ | |||||||
|               content_type: QuickReplyType.text, |               content_type: QuickReplyType.text, | ||||||
|               text: qr.title, |               text: qr.title, | ||||||
|               payload: qr.payload, |               payload: qr.payload, | ||||||
|             }) as ISuggestion, |             } as ISuggestion), | ||||||
|         ), |         ), | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
| @ -308,11 +309,17 @@ const ChatProvider: React.FC<{ | |||||||
|     async (firstName?: string, lastName?: string) => { |     async (firstName?: string, lastName?: string) => { | ||||||
|       try { |       try { | ||||||
|         setConnectionState(2); |         setConnectionState(2); | ||||||
|  |         const queryParams: Record<string, string> = | ||||||
|  |           firstName && lastName | ||||||
|  |             ? { first_name: firstName, last_name: lastName } | ||||||
|  |             : {}; | ||||||
|         const { body } = await socketCtx.socket.get<{ |         const { body } = await socketCtx.socket.get<{ | ||||||
|           messages: TMessage[]; |           messages: TMessage[]; | ||||||
|           profile: ISubscriber; |           profile: ISubscriber; | ||||||
|         }>( |         }>( | ||||||
|           `/webhook/${config.channel}/?first_name=${firstName}&last_name=${lastName}`, |           `/webhook/${config.channel}/?${new URLSearchParams( | ||||||
|  |             queryParams, | ||||||
|  |           ).toString()}`,
 | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         localStorage.setItem("profile", JSON.stringify(body.profile)); |         localStorage.setItem("profile", JSON.stringify(body.profile)); | ||||||
| @ -332,7 +339,7 @@ const ChatProvider: React.FC<{ | |||||||
|           }), |           }), | ||||||
|         ); |         ); | ||||||
|         setParticipants([ |         setParticipants([ | ||||||
|           ...participants, |           participants[0], | ||||||
|           { |           { | ||||||
|             id: body.profile.foreign_id, |             id: body.profile.foreign_id, | ||||||
|             foreign_id: body.profile.foreign_id, |             foreign_id: body.profile.foreign_id, | ||||||
| @ -382,6 +389,24 @@ const ChatProvider: React.FC<{ | |||||||
|     if (screen === "chat" && connectionState === ConnectionState.connected) { |     if (screen === "chat" && connectionState === ConnectionState.connected) { | ||||||
|       handleSubscription(); |       handleSubscription(); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // When user loses internet connection, on reconnect
 | ||||||
|  |     // we will need to subscribe him again (join the io room)
 | ||||||
|  |     const reSubscribe = () => { | ||||||
|  |       const item = localStorage.getItem("profile"); | ||||||
|  | 
 | ||||||
|  |       if (item) { | ||||||
|  |         const profile = JSON.parse(item) as ISubscriber; | ||||||
|  | 
 | ||||||
|  |         handleSubscription(profile.first_name, profile.last_name); | ||||||
|  |       } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     socketCtx.socket.io.on("reconnect", reSubscribe); | ||||||
|  | 
 | ||||||
|  |     return () => { | ||||||
|  |       socketCtx.socket.io.off("reconnect", reSubscribe); | ||||||
|  |     }; | ||||||
|     // eslint-disable-next-line react-hooks/exhaustive-deps
 |     // eslint-disable-next-line react-hooks/exhaustive-deps
 | ||||||
|   }, []); |   }, []); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,11 +1,12 @@ | |||||||
| /* | /* | ||||||
|  * Copyright © 2024 Hexastack. All rights reserved. |  * Copyright © 2025 Hexastack. All rights reserved. | ||||||
|  * |  * | ||||||
|  * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: |  * Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: | ||||||
|  * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. |  * 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. | ||||||
|  * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). |  * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| import { io, ManagerOptions, Socket, SocketOptions } from "socket.io-client"; | import { io, ManagerOptions, Socket, SocketOptions } from "socket.io-client"; | ||||||
| 
 | 
 | ||||||
| import { Config } from "../types/config.types"; | import { Config } from "../types/config.types"; | ||||||
| @ -56,6 +57,8 @@ export class SocketIoClient { | |||||||
| 
 | 
 | ||||||
|   private config: SocketIoClientConfig; |   private config: SocketIoClientConfig; | ||||||
| 
 | 
 | ||||||
|  |   public id: string; | ||||||
|  | 
 | ||||||
|   constructor( |   constructor( | ||||||
|     apiUrl: string, |     apiUrl: string, | ||||||
|     socketConfig: SocketIoClientConfig, |     socketConfig: SocketIoClientConfig, | ||||||
| @ -72,6 +75,10 @@ export class SocketIoClient { | |||||||
|     this.init(handlers); |     this.init(handlers); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   get io() { | ||||||
|  |     return this.socket.io; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   /** |   /** | ||||||
|    * Initializes the socket client and sets up event handlers. |    * Initializes the socket client and sets up event handlers. | ||||||
|    * @param handlers Event handlers for connection, disconnection, and connection errors |    * @param handlers Event handlers for connection, disconnection, and connection errors | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user