@chat21/chat21-web-widget 5.1.34-rc1 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/docker-community-push-latest.yml +13 -23
- package/.github/workflows/docker-image-tag-community-tag-push.yml +12 -22
- package/CHANGELOG.md +22 -118
- package/Dockerfile +4 -4
- package/README.md +1 -1
- package/docs/ACCESSIBILITY-STATEMENT.md +388 -0
- package/docs/TILEDESK_WIDGET_ACCESSIBILITY_ALIGNMENT.md +60 -0
- package/docs/TILEDESK_WIDGET_ACCESSIBILITY_STATEMENT_COMPLETE.md +386 -0
- package/docs/changelog/this-branch.md +0 -36
- package/nginx.conf +2 -22
- package/package.json +1 -1
- package/src/app/app.component.ts +9 -10
- package/src/app/component/conversation-detail/conversation/conversation.component.html +2 -2
- package/src/app/component/conversation-detail/conversation/conversation.component.scss +2 -2
- package/src/app/component/conversation-detail/conversation/conversation.component.ts +16 -34
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +3 -3
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +2 -2
- package/src/app/component/conversation-detail/conversation-content/conversation-content.component.spec.ts +0 -1
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +52 -63
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.scss +17 -11
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.spec.ts +10 -4
- package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +5 -8
- package/src/app/component/form/inputs/form-text/form-text.component.ts +1 -1
- package/src/app/component/last-message/last-message.component.ts +1 -4
- package/src/app/component/message/audio-sync/audio-sync.component.spec.ts +17 -8
- package/src/app/component/message/audio-sync/audio-sync.component.ts +96 -25
- package/src/app/component/message/bubble-message/bubble-message.component.html +12 -9
- package/src/app/component/message/bubble-message/bubble-message.component.spec.ts +38 -45
- package/src/app/component/message/bubble-message/bubble-message.component.ts +49 -45
- package/src/app/component/message/json-sources/json-sources.component.html +6 -5
- package/src/app/component/message/json-sources/json-sources.component.scss +26 -18
- package/src/app/component/message/json-sources/json-sources.component.ts +41 -0
- package/src/app/providers/global-settings.service.ts +0 -42
- package/src/app/providers/json-sources-parser.service.ts +13 -1
- package/src/app/providers/translator.service.ts +1 -4
- package/src/app/providers/tts-audio-playback-coordinator.service.spec.ts +7 -8
- package/src/app/providers/tts-audio-playback-coordinator.service.ts +13 -0
- package/src/app/providers/voice/STT&TTS/openai-voice.provider.ts +67 -82
- package/src/app/providers/voice/voice.service.spec.ts +35 -35
- package/src/app/providers/voice/voice.service.ts +3 -7
- package/src/app/sass/_variables.scss +0 -1
- package/src/app/utils/globals.ts +2 -8
- package/src/assets/i18n/en.json +22 -1
- package/src/assets/i18n/es.json +22 -1
- package/src/assets/i18n/fr.json +22 -1
- package/src/assets/i18n/it.json +22 -1
- package/src/assets/twp/index-dev.html +0 -18
- package/src/chat21-core/providers/firebase/firebase-init-service.ts +5 -5
- package/src/chat21-core/providers/tiledesk/tiledesk-requests.service.ts +1 -1
- package/src/chat21-core/utils/utils-message.ts +4 -4
- package/src/chat21-core/utils/utils.ts +2 -5
- package/src/widget-config-template.json +0 -1
- package/src/widget-config.json +28 -30
- package/.github/workflows/build.yml +0 -22
- package/src/assets/twp/tiledesk_widget_files/widget-css-override-example.css +0 -14
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
name: Docker Image Community latest CI
|
|
2
2
|
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
5
|
branches: [ master ]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [ master ]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [ master ]
|
|
8
8
|
|
|
9
9
|
jobs:
|
|
10
10
|
push_to_registry:
|
|
@@ -12,22 +12,12 @@ jobs:
|
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
13
|
|
|
14
14
|
steps:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
25
|
-
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
26
|
-
|
|
27
|
-
- name: Build and push multiarch Docker image
|
|
28
|
-
uses: docker/build-push-action@v3
|
|
29
|
-
with:
|
|
30
|
-
context: .
|
|
31
|
-
push: true
|
|
32
|
-
platforms: linux/amd64,linux/arm64
|
|
33
|
-
tags: chat21/chat21-web-widget:latest
|
|
15
|
+
- uses: actions/checkout@v2
|
|
16
|
+
name: Check out the repo
|
|
17
|
+
- uses: docker/build-push-action@v1
|
|
18
|
+
with:
|
|
19
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
20
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
21
|
+
repository: chat21/chat21-web-widget
|
|
22
|
+
push: true
|
|
23
|
+
tags: latest
|
|
@@ -3,30 +3,20 @@ name: Publish Docker Community image tags
|
|
|
3
3
|
on:
|
|
4
4
|
push:
|
|
5
5
|
tags:
|
|
6
|
-
- '**'
|
|
7
|
-
|
|
6
|
+
- '**' # Push events to every tag including hierarchical tags like
|
|
8
7
|
jobs:
|
|
8
|
+
|
|
9
9
|
push_to_registry:
|
|
10
10
|
name: Push Docker image to Docker Hub
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
|
-
|
|
13
12
|
steps:
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
25
|
-
|
|
26
|
-
- name: Build and push multiarch Docker image
|
|
27
|
-
uses: docker/build-push-action@v3
|
|
28
|
-
with:
|
|
29
|
-
context: .
|
|
30
|
-
push: true
|
|
31
|
-
platforms: linux/amd64,linux/arm64
|
|
32
|
-
tags: chat21/chat21-web-widget:${{ github.ref_name }}
|
|
13
|
+
- name: Check out the repo
|
|
14
|
+
uses: actions/checkout@v2
|
|
15
|
+
- name: Push to Docker Hub
|
|
16
|
+
uses: docker/build-push-action@v1
|
|
17
|
+
with:
|
|
18
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
19
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
20
|
+
repository: chat21/chat21-web-widget
|
|
21
|
+
push: true
|
|
22
|
+
tag_with_ref: true
|
package/CHANGELOG.md
CHANGED
|
@@ -7,49 +7,18 @@
|
|
|
7
7
|
*Tiledesk SRL*
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
# 5.1
|
|
11
|
-
- **
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- **
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- **changed**:
|
|
18
|
-
- **added**:
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# 5.1.33-rc9
|
|
24
|
-
- **changed**: **Conversation footer** — accessibility-focused markup (ARIA roles/labels, live regions, semantic send control), stream-audio layout (wrapper + voice mode: hide attach/emoji while streaming, inline status, stream button + spectrum), optional **Close chat** action when `closeChatInConversation` is enabled; emoji restriction alert uses assertive live region semantics.
|
|
25
|
-
- **bug-fixed**: **`getConversationDetail` Tiledesk fallback** — when `getMyRequests()` rejects, the conversation is treated as archived (`isConversationArchived = true`) and the handler returns immediately instead of resetting state from an empty fallback payload.
|
|
26
|
-
- **bug-fixed**: **`VoiceService`** — skip Web Audio `createMediaStreamSource` when the `MediaStream` has no audio tracks (avoids `InvalidStateError` under mocked `getUserMedia` in unit tests and edge browsers).
|
|
27
|
-
- **bug-fixed**: **`TtsAudioPlaybackCoordinator`** — avoid emitting a duplicate `isTTSPlaying$` `true` when preempting an already-playing owner (keeps emission sequence stable for consumers).
|
|
28
|
-
- **bug-fixed**: **Unit tests** — aligned `BubbleMessageComponent` specs with `calcImageSize` + DI mocks; `AudioSyncComponent` spec module setup (`declarations` + `CommonModule`) and TTS streaming call expectations; `VoiceService` specs with realistic mic streams and updated expectations for proxy `listening` / `barge_in` (no `setAudioMuted` on those paths); `TtsAudioPlaybackCoordinator` `stopAll` test asserts `_stopAll$` broadcast via spy; `ConversationComponent` spec for Tiledesk error path.
|
|
29
|
-
|
|
30
|
-
# 5.1.33-rc7
|
|
31
|
-
- **added**: added more URL source types in kb_json_sources
|
|
32
|
-
|
|
33
|
-
# 5.1.33-rc5
|
|
34
|
-
- **added**: cssSource tiledeskSettings property to manage and override widget style
|
|
35
|
-
|
|
36
|
-
# 5.1.33-rc4
|
|
37
|
-
- **bug fixed**: bug fixed extractUrlsFromText
|
|
38
|
-
|
|
39
|
-
# 5.1.32-rc18
|
|
40
|
-
- **bug fixed**: bug fix css kb_json_sources
|
|
41
|
-
|
|
42
|
-
# 5.1.32-rc17
|
|
43
|
-
- **bug fixed**: empty message in preview URLs
|
|
44
|
-
|
|
45
|
-
# 5.1.32-rc16
|
|
46
|
-
- **added**: added chat-json-sources to preview URLs
|
|
47
|
-
|
|
48
|
-
# 5.1.32-rc15
|
|
49
|
-
- **changed**: redemptionMs: 800
|
|
50
|
-
|
|
51
|
-
# 5.1.32-rc14
|
|
52
|
-
- **changed**: minor ui fixed
|
|
10
|
+
# 5.2.1
|
|
11
|
+
- **bug fixed**: prevent avatar display when audio stream is active in conversation content
|
|
12
|
+
- **changed**: refined message margin logic and updated widget/firebase configuration for local development
|
|
13
|
+
- **changed**: simplified textarea background color and removed unused image in conversation footer
|
|
14
|
+
- **changed**: updated `remoteConfigUrl` settings for widget configuration
|
|
15
|
+
- **changed**: switched Docker builder stage base image to `node:20.12.2-bookworm-slim`
|
|
16
|
+
- **changed**: upgraded Angular and build tool dependencies to align with version 5.2.1
|
|
17
|
+
- **changed**: cleaned up and enhanced unit tests for conversation and audio components
|
|
18
|
+
- **added**: integrated Playwright for end-to-end testing
|
|
19
|
+
- **added**: comprehensive accessibility documentation for the Tiledesk Web Widget
|
|
20
|
+
|
|
21
|
+
# 5.2.0
|
|
53
22
|
|
|
54
23
|
# 5.1.32-rc13
|
|
55
24
|
- **added**: VAD speech state events (`speechStart$`, `speechEnd$`) to improve UI/state transitions around user speech
|
|
@@ -59,69 +28,23 @@
|
|
|
59
28
|
|
|
60
29
|
|
|
61
30
|
|
|
62
|
-
# 5.1.
|
|
63
|
-
- **
|
|
64
|
-
- **chore**: version bump to `5.1.32-rc12`
|
|
65
|
-
|
|
66
|
-
# 5.1.32-rc11
|
|
67
|
-
- **added**: global TTS stop — `TtsAudioPlaybackCoordinator.stopAll()` + `stopAllPlayback$` to abort current and queued TTS playback and reveal full message text
|
|
68
|
-
- **changed**: stop TTS playback when closing stream audio
|
|
69
|
-
- **chore**: version bump to `5.1.32-rc11`
|
|
70
|
-
|
|
71
|
-
# 5.1.32-rc10
|
|
72
|
-
- **added**: TTS playback state (`isTTSPlaying$`) to coordinate voice UI and suppress mic segment emission while the bot is speaking
|
|
73
|
-
- **changed**: stream spectrum theme color turns grey while TTS is playing
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
# 5.1.32-rc9
|
|
77
|
-
- **added**: mic-triggered TTS interruption — when VAD detects user speech, stop current TTS playback, clear the queue, and reveal the full message text
|
|
78
|
-
- **added**: global TTS stop API (`TtsAudioPlaybackCoordinator.stopAll()` + `stopAllPlayback$`) to stop current + queued TTS playback from UI/events (e.g. close stream)
|
|
79
|
-
- **changed**: `chat-audio-sync` TTS playback now streams audio via authenticated POST to `message.metadata.src`, sending `voiceSettings` + `text` and `streaming: true`
|
|
80
|
-
- **changed**: stream UI spectrum — removed circular orb and stretched the spectrum line to fill the `#streamAudioAlert` width with 10px side padding
|
|
81
|
-
- **changed**: conversation content layout while streaming — adjusted received bubble left margin and loading spinner margins for full-size mode
|
|
31
|
+
# 5.1.35
|
|
32
|
+
- **bug fixed**: updated url preview, added displayed fields
|
|
82
33
|
|
|
34
|
+
# 5.1.34
|
|
35
|
+
- **bug fixed**: if last message is ulr_preview shows previous message buttons
|
|
83
36
|
|
|
84
|
-
# 5.1.
|
|
85
|
-
- **
|
|
37
|
+
# 5.1.33
|
|
38
|
+
- **bug fixed**: widget not loaded because blob block loading in lauch.js
|
|
86
39
|
|
|
87
|
-
# 5.1.
|
|
88
|
-
- **
|
|
89
|
-
- **added**: TTS playback coordinator queue — ensures TTS messages play sequentially without interrupting the previous one
|
|
90
|
-
- **changed**: `chat-audio-sync` — updated TTS audio handling to support streaming playback and improved autoplay/animation timing
|
|
91
|
-
- **changed**: iframe loader (`launch.js`, `launch_template.js`) — streamlined loading logic and improved error handling, with fixes for localhost environments
|
|
92
|
-
|
|
93
|
-
# 5.1.32-rc4
|
|
94
|
-
- **added**: “Close stream” control (`.close-stream-button`) — content and sheet bottom offset in fullscreen using `--chat-footer-stream-button-height` only while the stream is listening (`isStreamAudioActive`); variables in `_variables.scss`.
|
|
95
|
-
- **added**: `VoiceService.discardCurrentRecordingSegment()` — when a message arrives from another sender during streaming, the current WebM segment is discarded (no upload) without stopping mic/VAD; `interruptStreamDueToPeerMessage()` in the footer no longer clears `isStreamAudioActive`.
|
|
96
|
-
- **changed**: `#streamAudioAlert` — band above the footer with a frosted-glass look (`backdrop-filter`, semi-transparent `color-mix`).
|
|
97
|
-
|
|
98
|
-
# 5.1.32-rc3
|
|
99
|
-
- **changed**: `nginx.conf` (Docker image) — explicit MIME types for `.mjs`, `.wasm`, `.onnx` and `default_type` at `http` level (avoids `text/plain` on ONNX/VAD modules behind containerized deploys).
|
|
100
|
-
- **chore**: removed deprecated Amazon beta/prod deploy scripts from the repository.
|
|
101
|
-
|
|
102
|
-
# 5.1.32-rc2
|
|
103
|
-
- **bug fixed**: minor streaming icon UI fixed
|
|
104
|
-
- **changed**: Refactor stream audio button UI in the conversation footer (layout / classes).
|
|
105
|
-
|
|
106
|
-
# 5.1.32-rc1
|
|
107
|
-
- **added**: Voice pipeline — VAD (`@ricky0123/vad-web`) with ONNX Runtime WASM served from `/assets/onnx` (`copy-onnx-wasm`), `VoiceService` with `audioSegment$` (WebM segments) and optional STT/TTS via unified OpenAI provider using `HttpClient`, transcript / error fields on segment payloads.
|
|
108
|
-
- **added**: Stream audio UI in conversation footer — toggle, real-time volume stream and animated waveform (`volume$`); mic session lifecycle wired to upload segments on speech end.
|
|
109
|
-
- **added**: `MessageModel.isJustRecived` — set when ingesting messages (MQTT/Firebase `addCommandMessage` for `command.type === "message"`, and default for non-command messages in `addedMessage` / `addedNew`) to distinguish “new in session” vs history.
|
|
110
|
-
- **added**: `chat-audio-sync` for TTS messages — karaoke-style word sync to audio, full `message` input, typography aligned with text bubbles; skips animation when `isJustRecived === false`; after playback ends sets `message.isJustRecived = false` so replays show full text without re-animating.
|
|
111
|
-
- **bug fixed**: `AnalyserNode.getByteFrequencyData` TypeScript error — `Uint8Array` created from an explicit `ArrayBuffer` for correct DOM typings.
|
|
112
|
-
- **bug fixed**: `isStreamAudioActive` no longer derived from per-frame mic level (`volume > 1`), which caused the stream button / active state to flash continuously while listening.
|
|
40
|
+
# 5.1.31
|
|
41
|
+
- **bug fixed**: bug fix disabled user-typing with human and user-typing with human is not available
|
|
113
42
|
|
|
114
43
|
# 5.1.30
|
|
115
44
|
- **bug fixed**: startHidden is not working properly
|
|
116
45
|
|
|
117
|
-
# 5.1.
|
|
118
|
-
- **bug fixed**:
|
|
119
|
-
|
|
120
|
-
# 5.1.30-rc2
|
|
121
|
-
- **bug fixed**: bug fix disabled user-typing with human
|
|
122
|
-
|
|
123
|
-
# 5.1.30-rc1
|
|
124
|
-
- **bug fixed**: startHidden is not working properly
|
|
46
|
+
# 5.1.28
|
|
47
|
+
- **bug fixed**: header option menu is deactivated on mobile
|
|
125
48
|
|
|
126
49
|
# 5.1.28
|
|
127
50
|
- **bug fixed**: fixed Bot/Human conversation detection by correctly classifying bot replies
|
|
@@ -133,22 +56,8 @@
|
|
|
133
56
|
- **changed**: Set the default autoStart value to false
|
|
134
57
|
- **added**: Added the open widget loading spinner
|
|
135
58
|
- **changed**: Load the widget without authentication and display the speech bubble
|
|
136
|
-
|
|
137
|
-
# 5.1.27-rc3
|
|
138
|
-
- **bug fixed**: fixed Bot/Human conversation detection by correctly classifying bot replies
|
|
139
|
-
|
|
140
|
-
# 5.1.27-rc2
|
|
141
|
-
- **bug fixed**: centralized fullscreen management on mobile and handled the case of the closed widget that remained fullscreen
|
|
142
|
-
|
|
143
|
-
# 5.1.27-rc1
|
|
144
|
-
- **added**: closeChatInConversation parameters
|
|
145
|
-
- **added**: close chat button under textarea footer component
|
|
146
|
-
|
|
147
|
-
# 5.1.26-rc6
|
|
148
59
|
- **changed**: mobile always opens fullscreen and ignores legacy stored size”.
|
|
149
60
|
- **changed**: changed user-typing
|
|
150
|
-
|
|
151
|
-
# 5.1.26-rc5
|
|
152
61
|
- **changed**: Hide the resize-widget button when on mobile
|
|
153
62
|
- **added**: added "I'm thinking" when the bot responds
|
|
154
63
|
|
|
@@ -210,11 +119,6 @@
|
|
|
210
119
|
- **bug-fixed**: check showEmojiFooterButton to enable/disable emojii
|
|
211
120
|
- **bug-fixed**: markdown is fired as an emojii and blocked by isEmojii check fn
|
|
212
121
|
|
|
213
|
-
# 5.1.7-rc7
|
|
214
|
-
- **bug-fixed**: button new_conversation always appear. added subscription to conversationAdded
|
|
215
|
-
|
|
216
|
-
# 5.1.7-rc6
|
|
217
|
-
- **added**: Added MAX_ATTACHMENT_ERROR error message when uploading a file larger than 10 MB
|
|
218
122
|
|
|
219
123
|
# 5.1.7-rc5
|
|
220
124
|
- **bug-fixed**: bug fixed BUTTON STYLES
|
package/Dockerfile
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
### STAGE 1: Build ###
|
|
2
2
|
|
|
3
3
|
# We label our stage as ‘builder’
|
|
4
|
-
FROM --platform=$BUILDPLATFORM node:20.12.2-
|
|
4
|
+
FROM --platform=$BUILDPLATFORM node:20.12.2-bookworm-slim AS builder
|
|
5
5
|
|
|
6
6
|
COPY package.json package-lock.json ./
|
|
7
7
|
|
|
8
8
|
## Storing node modules on a separate layer will prevent unnecessary npm installs at each build
|
|
9
9
|
|
|
10
|
-
RUN npm ci && mkdir /ng-app && mv ./node_modules ./ng-app
|
|
10
|
+
RUN npm install -g npm@10.9.2 && npm ci && mkdir /ng-app && mv ./node_modules ./ng-app
|
|
11
11
|
|
|
12
12
|
WORKDIR /ng-app
|
|
13
13
|
|
|
@@ -15,9 +15,9 @@ COPY . .
|
|
|
15
15
|
|
|
16
16
|
## Build the angular app in production mode and store the artifacts in dist folder
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
RUN npx ng build --configuration="prod" --output-path=dist --base-href=./ --output-hashing=none
|
|
20
19
|
|
|
20
|
+
|
|
21
21
|
### STAGE 2: Setup ###
|
|
22
22
|
FROM --platform=$BUILDPLATFORM nginx:1.14.1-alpine
|
|
23
23
|
|
|
@@ -32,4 +32,4 @@ COPY --from=builder /ng-app/dist/browser /usr/share/nginx/html
|
|
|
32
32
|
|
|
33
33
|
RUN echo "Chat21 Web Widget Started!!"
|
|
34
34
|
|
|
35
|
-
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/widget-config-template.json > /usr/share/nginx/html/widget-config.json && exec nginx -g 'daemon off;'"]
|
|
35
|
+
CMD ["/bin/sh", "-c", "envsubst < /usr/share/nginx/html/widget-config-template.json > /usr/share/nginx/html/widget-config.json && exec nginx -g 'daemon off;'"]
|
package/README.md
CHANGED
|
@@ -67,7 +67,7 @@ export const environment = {
|
|
|
67
67
|
production: true,
|
|
68
68
|
version: require('../../package.json').version,
|
|
69
69
|
remoteConfig: false, // for performance don't load settings from remote
|
|
70
|
-
remoteConfigUrl: '/widget-config.json',
|
|
70
|
+
remoteConfigUrl: '/widget-config-aws-stage.json',
|
|
71
71
|
loadRemoteTranslations: true,
|
|
72
72
|
remoteTranslationsUrl: 'https://<YOUR_REMOTE_TRANSLATIONS_URL>/',
|
|
73
73
|
chatEngine: "mqtt", // OR YOUR CUSTOM CHAT ENGINE
|