@chat21/chat21-web-widget 5.0.66 → 5.0.68

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.
Files changed (26) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +1 -1
  3. package/src/app/app.component.ts +12 -9
  4. package/src/app/app.module.ts +6 -1
  5. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.html +10 -0
  6. package/src/app/component/conversation-detail/conversation-content/conversation-content.component.scss +4 -0
  7. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.html +11 -1
  8. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.scss +8 -0
  9. package/src/app/component/conversation-detail/conversation-emojii/conversation-emojii.component.ts +24 -2
  10. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.html +6 -5
  11. package/src/app/component/conversation-detail/conversation-footer/conversation-footer.component.ts +12 -5
  12. package/src/app/component/conversation-detail/conversation-preview/conversation-preview.component.ts +3 -2
  13. package/src/app/component/message/audio/audio.component.html +20 -0
  14. package/src/app/component/message/audio/audio.component.scss +122 -0
  15. package/src/app/component/message/audio/audio.component.spec.ts +23 -0
  16. package/src/app/component/message/audio/audio.component.ts +123 -0
  17. package/src/app/component/message/bubble-message/bubble-message.component.html +5 -0
  18. package/src/app/component/message/bubble-message/bubble-message.component.ts +2 -1
  19. package/src/app/component/message/carousel/carousel.component.html +29 -0
  20. package/src/app/component/message/carousel/carousel.component.scss +257 -0
  21. package/src/app/component/message/carousel/carousel.component.spec.ts +23 -0
  22. package/src/app/component/message/carousel/carousel.component.ts +111 -0
  23. package/src/app/providers/global-settings.service.ts +1 -1
  24. package/src/chat21-core/providers/firebase/firebase-conversation-handler.ts +53 -48
  25. package/src/chat21-core/providers/mqtt/mqtt-conversation-handler.ts +61 -54
  26. package/src/chat21-core/utils/utils-message.ts +14 -7
@@ -0,0 +1,257 @@
1
+ @import 'src/app/sass/variables';
2
+
3
+ :host {
4
+ --backgroundColor: #{var(--blue)};
5
+ --textColor: #{var(--bck-msg-sent)};
6
+ --hoverBackgroundColor: #{var(--bck-msg-sent)};
7
+ --hoverTextColor: #{var(--blue)};
8
+ --buttonFontSize: #{var(--button-in-msg-font-size)};
9
+ --max-width: #{var(--button-in-msg-max-width)};
10
+
11
+ --cardWidth: 240px;
12
+ }
13
+
14
+
15
+ .wrapper {
16
+ // max-width: 1100px;
17
+ width: 100%;
18
+ position: relative;
19
+ display: flex;
20
+
21
+ overflow: scroll;
22
+ gap: 10px;
23
+ margin: 0;
24
+ width: 100%;
25
+ font-size: 14px;
26
+ margin: 0 25px;
27
+ }
28
+ .wrapper .cards-scroll-spacer{
29
+ -ms-flex-negative: 0;
30
+ content: "";
31
+ flex-shrink: 0;
32
+ width: 17px;
33
+ }
34
+ .wrapper div.arrow {
35
+ top: 50%;
36
+ height: 40px;
37
+ width: 40px;
38
+ cursor: pointer;
39
+ font-size: 1.25rem;
40
+ position: absolute;
41
+ text-align: center;
42
+ line-height: 50px;
43
+ background: #fff;
44
+ border-radius: 50%;
45
+ box-shadow: 0 3px 6px rgba(0,0,0,0.23);
46
+ transform: translateY(-50%);
47
+ transition: transform 0.1s linear;
48
+
49
+ display: flex;
50
+ justify-content: center;
51
+ align-items: center;
52
+ }
53
+ .wrapper div.arrow:active{
54
+ transform: translateY(-50%) scale(0.85);
55
+ }
56
+ .wrapper div.arrow:first-child{
57
+ left: 5px;
58
+ }
59
+ .wrapper div.arrow:last-child{
60
+ // right: -22px;
61
+ // right: 22px;
62
+ left: calc(var(--cardWidth) - -15px);
63
+ }
64
+ .wrapper .carousel{
65
+ display: grid;
66
+ grid-auto-flow: column;
67
+ grid-auto-columns: calc((100% / 3) - 12px);
68
+ align-items: start;
69
+ overflow: hidden;
70
+ // scroll-snap-type: x mandatory;
71
+ gap: 16px;
72
+ border-radius: 8px;
73
+ scroll-behavior: smooth;
74
+ scrollbar-width: none;
75
+
76
+ // display: flex;
77
+ // align-items: flex-start;
78
+ }
79
+ .carousel::-webkit-scrollbar {
80
+ display: none;
81
+ }
82
+ .carousel.no-transition {
83
+ scroll-behavior: auto;
84
+ }
85
+ .carousel.dragging {
86
+ scroll-snap-type: none;
87
+ scroll-behavior: auto;
88
+ }
89
+ .carousel.dragging .card {
90
+ cursor: grab;
91
+ user-select: none;
92
+ }
93
+ .carousel :where(.card, .card-imgage) {
94
+ display: flex;
95
+ justify-content: center;
96
+ align-items: center;
97
+ }
98
+ .carousel .card {
99
+ scroll-snap-align: start;
100
+ width: var(--cardWidth);
101
+ background: rgb(255, 255, 255);
102
+ box-shadow: 0 3px 6px rgba(0,0,0,0.23);
103
+ cursor: pointer;
104
+ // padding-bottom: 15px;
105
+ flex-direction: column;
106
+ border-radius: 8px;
107
+ border: 1px solid;
108
+ border-color: rgb(219, 225, 232);
109
+ }
110
+
111
+ .carousel .card-image {
112
+ height: 170px;
113
+ width: var(--cardWidth);
114
+ }
115
+
116
+ img {
117
+ height: 100%;
118
+ -o-object-fit: cover;
119
+ object-fit: cover;
120
+
121
+ background: transparent!important;
122
+ display: block;
123
+ max-width: 100% !important;
124
+ border-radius: 8px 8px 0px 0px;
125
+ }
126
+
127
+ .carousel .card-content{
128
+ -webkit-box-orient: vertical;
129
+ -webkit-box-direction: normal;
130
+ display: -webkit-box;
131
+ display: -ms-flexbox;
132
+ display: flex;
133
+ -ms-flex-direction: column;
134
+ flex-direction: column;
135
+ padding: 0 20px 30px;
136
+
137
+ .card-title{
138
+ word-wrap: break-word;
139
+ font-size: 16px;
140
+ font-weight: 600;
141
+ line-height: 20px;
142
+ margin-top: 12px;
143
+ white-space: pre-wrap;
144
+ width: 100%;
145
+ }
146
+
147
+ .card-description{
148
+ word-wrap: break-word;
149
+ font-size: 16px;
150
+ line-height: 20px;
151
+ margin-top: 12px;
152
+ white-space: pre-wrap;
153
+ }
154
+ }
155
+
156
+ .carousel .buttons{
157
+ -webkit-box-orient: vertical;
158
+ -webkit-box-direction: normal;
159
+ display: -webkit-box;
160
+ display: -ms-flexbox;
161
+ display: flex;
162
+ -ms-flex-direction: column;
163
+ flex-direction: column;
164
+ width: 100%;
165
+
166
+
167
+ .single-button{
168
+ // border-top-color: rgb(219, 225, 232);
169
+
170
+ -webkit-box-align: center;
171
+ -ms-flex-align: center;
172
+ align-items: center;
173
+ justify-content: center;
174
+ border-top: 1px solid var(--textColor);
175
+ cursor: pointer;
176
+ display: -webkit-box;
177
+ display: -ms-flexbox;
178
+ display: flex;
179
+ font-weight: 600;
180
+ height: 45px;
181
+ padding: 0 10px;
182
+ -webkit-transition: all .3s;
183
+ transition: all .3s;
184
+
185
+ color: var(--textColor);
186
+ background: var(--backgroundColor);
187
+ font-family: 'Muli', sans-serif;
188
+ font-size: var(--buttonFontSize);
189
+
190
+
191
+ div{
192
+ overflow: hidden!important;
193
+ text-align: center;
194
+ text-overflow: ellipsis;
195
+ white-space: nowrap;
196
+ width: 100%;
197
+ }
198
+
199
+ &:focus,
200
+ &:hover {
201
+ color: var(--hoverTextColor);
202
+ background: var(--hoverBackgroundColor);
203
+ transform: scale(1.05);
204
+ .icon-button-action {
205
+ svg {
206
+ fill: var(--hoverTextColor);
207
+ }
208
+ }
209
+ }
210
+ &:after {
211
+ content: "";
212
+ position: absolute;
213
+ width: 0;
214
+ height: 0;
215
+ top: 50%;
216
+ left: 50%;
217
+ transform-style: flat;
218
+ transform: translate3d(-50%,-50%,0);
219
+ background: rgba(white,.2);
220
+ border-radius: 100%;
221
+ transition: width .5s ease, height .5s ease;
222
+ }
223
+
224
+
225
+ }
226
+
227
+ .single-button:last-child{
228
+ border-radius: 0px 0px 8px 8px;
229
+ }
230
+ }
231
+ // .card .card-image img {
232
+ // width: 140px;
233
+ // height: 140px;
234
+ // border-radius: 50%;
235
+ // object-fit: cover;
236
+ // border: 4px solid #fff;
237
+ // }
238
+ .carousel .card h2 {
239
+ font-weight: 500;
240
+ font-size: 1.56rem;
241
+ margin: 30px 0 5px;
242
+ }
243
+ .carousel .card span {
244
+ color: #6A6D78;
245
+ font-size: 1.31rem;
246
+ }
247
+ @media screen and (max-width: 900px) {
248
+ .wrapper .carousel {
249
+ grid-auto-columns: calc((100% / 2) - 9px);
250
+ }
251
+ }
252
+ @media screen and (max-width: 600px) {
253
+ .wrapper .carousel {
254
+ // grid-auto-columns: 100%;
255
+ grid-auto-columns: 75%;
256
+ }
257
+ }
@@ -0,0 +1,23 @@
1
+ import { ComponentFixture, TestBed } from '@angular/core/testing';
2
+
3
+ import { CarouselComponent } from './carousel.component';
4
+
5
+ describe('CarouselComponent', () => {
6
+ let component: CarouselComponent;
7
+ let fixture: ComponentFixture<CarouselComponent>;
8
+
9
+ beforeEach(async () => {
10
+ await TestBed.configureTestingModule({
11
+ declarations: [ CarouselComponent ]
12
+ })
13
+ .compileComponents();
14
+
15
+ fixture = TestBed.createComponent(CarouselComponent);
16
+ component = fixture.componentInstance;
17
+ fixture.detectChanges();
18
+ });
19
+
20
+ it('should create', () => {
21
+ expect(component).toBeTruthy();
22
+ });
23
+ });
@@ -0,0 +1,111 @@
1
+ import { Component, ElementRef, EventEmitter, Input, OnInit, Output, SimpleChange, SimpleChanges, ViewChildren } from '@angular/core';
2
+ import { MessageModel } from 'src/chat21-core/models/message';
3
+
4
+ @Component({
5
+ selector: 'chat-carousel',
6
+ templateUrl: './carousel.component.html',
7
+ styleUrls: ['./carousel.component.scss']
8
+ })
9
+ export class CarouselComponent implements OnInit{
10
+
11
+ // ========= begin:: Input/Output values ============//
12
+ @Input() message: MessageModel;
13
+ @Input() stylesMap: Map<string, string>;
14
+ @Output() onAttachmentButtonClicked = new EventEmitter<any>();
15
+ @Output() onElementRendered = new EventEmitter<{element: string, status: boolean}>()
16
+ // ========= end:: Input/Output values ============//
17
+ gallery: any[]
18
+
19
+ wrapper: HTMLElement;
20
+ carousel: HTMLElement;
21
+ firstCardWidth: number;
22
+ activeElement: number = 1;
23
+
24
+ fontSize: string;
25
+ backgroundColor: string;
26
+ textColor: string;
27
+ hoverBackgroundColor: string;
28
+ hoverTextColor: string;
29
+
30
+ constructor(private elementRef: ElementRef) { }
31
+
32
+ ngOnInit() {
33
+ console.log('[CAROUSEL-MESSAGE] hello', this.message)
34
+
35
+
36
+ this.wrapper = this.elementRef.nativeElement.querySelector('.wrapper')
37
+ this.carousel = this.elementRef.nativeElement.querySelector('.carousel')
38
+
39
+
40
+ // this.firstCardWidth = (this.elementRef.nativeElement.querySelector(".card") as HTMLElement).offsetWidth
41
+ console.log('carrrrrrrrr', this.wrapper, this.elementRef.nativeElement.querySelector(".card"))
42
+ // Get the number of cards that can fit in the carousel at once
43
+ let cardPerView = Math.round(this.carousel.offsetWidth / this.firstCardWidth);
44
+
45
+ // Insert copies of the last few cards to beginning of carousel for infinite scrolling
46
+ // const carouselChildrens = [...this.carousel.children];
47
+ // carouselChildrens.slice(-cardPerView).reverse().forEach(card => {
48
+ // this.carousel.insertAdjacentHTML("afterbegin", card.outerHTML);
49
+ // });
50
+ // // Insert copies of the first few cards to end of carousel for infinite scrolling
51
+ // carouselChildrens.slice(0, cardPerView).forEach(card => {
52
+ // this.carousel.insertAdjacentHTML("beforeend", card.outerHTML);
53
+ // });
54
+
55
+ // Scroll the carousel at appropriate postition to hide first few duplicate cards on Firefox
56
+ this.carousel.classList.add("no-transition");
57
+ this.carousel.scrollLeft = this.carousel.offsetWidth;
58
+ this.carousel.classList.remove("no-transition");
59
+
60
+
61
+ console.log('[CAROUSEL-MESSAGE] cardPerView -->', cardPerView, this.carousel.querySelectorAll('.card') )
62
+
63
+ let currentItem = 0
64
+ // Store items as an array of objects
65
+ const items = this.carousel.querySelectorAll('.card')
66
+
67
+ this.carousel.addEventListener("scroll", function(el){
68
+ // console.log('elementttt', el)
69
+ // Find item closest to the goal
70
+ // currentItem = items.reduce((prev, curr) => {
71
+ // return (Math.abs(curr.offsetY - scrollY - goal) < Math.abs(prev.offsetY - scrollY - goal) ? curr : prev); // return the closest to the goal
72
+ // });
73
+ });
74
+
75
+ }
76
+
77
+ ngOnChanges(changes: SimpleChanges){
78
+ if(this.message && this.message.attributes && this.message.attributes?.attachment && this.message.attributes?.attachment?.gallery){
79
+ this.gallery = this.message.attributes.attachment.gallery
80
+ console.log('carrrrrrrrr', this.wrapper, this.elementRef.nativeElement.querySelector(".card"))
81
+
82
+ }
83
+
84
+ if(this.stylesMap){
85
+ if(this.stylesMap.has('buttonFontSize')) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--buttonFontSize', this.stylesMap.has('buttonFontSize'));
86
+ if(this.stylesMap.has('buttonBackgroundColor')) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--backgroundColor', this.stylesMap.has('buttonBackgroundColor'));
87
+ if(this.stylesMap.has('buttonTextColor')) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--textColor', this.stylesMap.has('buttonTextColor'));
88
+ if(this.stylesMap.has('buttonHoverBackgroundColor')) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverBackgroundColor', this.stylesMap.has('buttonHoverBackgroundColor'));
89
+ if(this.stylesMap.has('buttonHoverTextColor')) this.elementRef.nativeElement.querySelector('.action').style.setProperty('--hoverTextColor', this.stylesMap.has('buttonHoverTextColor'));
90
+ }
91
+
92
+
93
+ }
94
+
95
+ goTo(direction: 'next' | 'previous' ){
96
+ let width = (this.carousel.querySelector(".card") as HTMLElement).offsetWidth
97
+ let gap = Math.round( 16 / 2)
98
+ let cardPerView = Math.round(this.carousel.offsetWidth / width);
99
+
100
+ console.log('go to -->', direction, width, cardPerView, this.carousel.offsetWidth)
101
+
102
+ this.carousel.scrollLeft += direction == "previous" ? -(width+gap) : width+gap;
103
+ // this.activeElement += direction == "previous" ? -1 : 1;
104
+
105
+ // this.carousel.classList.add("no-transition");
106
+ // this.carousel.scrollLeft += width;
107
+ // this.carousel.classList.remove("no-transition");
108
+
109
+
110
+ }
111
+ }
@@ -997,7 +997,7 @@ export class GlobalSettingsService {
997
997
  TEMP = tiledeskSettings['participants'];
998
998
  // this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > participants:: ', TEMP]);
999
999
  if (TEMP !== undefined) {
1000
- globals.participants = TEMP.split(',').map(key => { return key.trim()});;
1000
+ globals.participants = TEMP.split(',').map(key => { return key.trim()});
1001
1001
  }
1002
1002
  TEMP = tiledeskSettings['whatsappNumber'];
1003
1003
  // this.logger.debug('[GLOBAL-SET] setVariablesFromSettings > whatsappNumber:: ', TEMP]);
@@ -105,14 +105,14 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
105
105
  this.logger.debug('[FIREBASEConversationHandlerSERVICE] urlNodeFirebase *****', this.urlNodeFirebase);
106
106
  const firebaseMessages = this.firebase.database().ref(this.urlNodeFirebase);
107
107
  this.ref = firebaseMessages.orderByChild('timestamp').limitToLast(100);
108
- this.ref.on('child_added', (childSnapshot) => {
108
+ this.ref.on('child_added', async (childSnapshot) => {
109
109
  that.logger.debug('[FIREBASEConversationHandlerSERVICE] >>>>>>>>>>>>>> child_added: ', childSnapshot.val())
110
110
  const msg: MessageModel = childSnapshot.val();
111
111
  msg.uid = childSnapshot.key;
112
112
 
113
113
  if (msg.attributes && msg.attributes.commands) {
114
114
  this.logger.debug('[FIREBASEConversationHandlerSERVICE] splitted message::::', msg)
115
- that.addCommandMessage(msg)
115
+ await that.addCommandMessage(msg)
116
116
  } else {
117
117
  this.logger.debug('[FIREBASEConversationHandlerSERVICE] NOT splitted message::::', msg)
118
118
  that.addedNew(msg)
@@ -255,6 +255,7 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
255
255
 
256
256
 
257
257
 
258
+
258
259
  this.addRepalceMessageInArray(msg.uid, msg);
259
260
  this.messageAdded.next(msg);
260
261
  } else {
@@ -468,59 +469,63 @@ export class FirebaseConversationHandler extends ConversationHandlerService {
468
469
  }
469
470
 
470
471
 
471
- private addCommandMessage(msg: MessageModel){
472
+ private async addCommandMessage(msg: MessageModel): Promise<boolean> {
472
473
  const that = this;
473
474
  const commands = msg.attributes.commands;
474
475
  let i=0;
475
- function execute(command){
476
- if(command.type === "message"){
477
- that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> type="message"', command, i)
478
- if (i >= 2) {
479
-
480
- //check if previus wait message type has time value, otherwize set to 1000ms
481
- !commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time
482
- command.message.timestamp = commands[i-2].message.timestamp + commands[i-1].time;
483
-
484
- /** CHECK IF MESSAGE IS JUST RECEIVED: IF false, set next message time (if object exist) to 0 -> this allow to show it immediately */
485
- if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
486
- let previewsTimeMsg = msg.timestamp;
487
- commands[i-2]? previewsTimeMsg = commands[i-2].message.timestamp : null;
488
- command.message.timestamp = previewsTimeMsg + 100
489
- commands[i+1]? commands[i+1].time = 0 : null
490
- }
491
- } else { /**MANAGE FIRST MESSAGE */
492
- command.message.timestamp = msg.timestamp;
493
- if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
494
- commands[i+1]? commands[i+1].time = 0 : null
495
- }
496
- }
497
- that.generateMessageObject(msg, command.message, function () {
498
- i += 1
499
- if (i < commands.length) {
500
- execute(commands[i])
476
+ return new Promise((resolve, reject)=>{
477
+ function execute(command){
478
+ if(command.type === "message"){
479
+ that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> type="message"', command, i)
480
+ if (i >= 2) {
481
+
482
+ //check if previus wait message type has time value, otherwize set to 1000ms
483
+ !commands[i-1].time? commands[i-1].time= 1000 : commands[i-1].time
484
+ command.message.timestamp = commands[i-2].message.timestamp + commands[i-1].time;
485
+
486
+ /** CHECK IF MESSAGE IS JUST RECEIVED: IF false, set next message time (if object exist) to 0 -> this allow to show it immediately */
487
+ if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
488
+ let previewsTimeMsg = msg.timestamp;
489
+ commands[i-2]? previewsTimeMsg = commands[i-2].message.timestamp : null;
490
+ command.message.timestamp = previewsTimeMsg + 100
491
+ commands[i+1]? commands[i+1].time = 0 : null
492
+ }
493
+ } else { /**MANAGE FIRST MESSAGE */
494
+ command.message.timestamp = msg.timestamp;
495
+ if(!isJustRecived(that.startTime.getTime(), msg.timestamp)){
496
+ commands[i+1]? commands[i+1].time = 0 : null
497
+ }
501
498
  }
502
- else {
503
- that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (wait), exit')
499
+ that.generateMessageObject(msg, command.message, function () {
500
+ i += 1
501
+ if (i < commands.length) {
502
+ execute(commands[i])
503
+ }
504
+ else {
505
+ that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (wait), exit')
506
+ resolve(true)
507
+ }
508
+ })
509
+ }else if(command.type === "wait"){
510
+ that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> type="wait"', command, i, commands.length)
511
+ //publish waiting event to simulate user typing
512
+ if(isJustRecived(that.startTime.getTime(), msg.timestamp)){
513
+ that.messageWait.next({uid: that.conversationWith, uidUserTypingNow: msg.sender, nameUserTypingNow: msg.sender_fullname, waitTime: command.time, command: command})
504
514
  }
505
- })
506
- }else if(command.type === "wait"){
507
- that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> type="wait"', command, i, commands.length)
508
- //publish waiting event to simulate user typing
509
- if(isJustRecived(that.startTime.getTime(), msg.timestamp)){
510
- that.messageWait.next({uid: that.conversationWith, uidUserTypingNow: msg.sender, nameUserTypingNow: msg.sender_fullname, waitTime: command.time, command: command})
515
+ setTimeout(function() {
516
+ i += 1
517
+ if (i < commands.length) {
518
+ execute(commands[i])
519
+ }
520
+ else {
521
+ that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
522
+ resolve(true)
523
+ }
524
+ },command.time)
511
525
  }
512
- setTimeout(function() {
513
- i += 1
514
- if (i < commands.length) {
515
- execute(commands[i])
516
- }
517
- else {
518
- that.logger.debug('[FIREBASEConversationHandlerSERVICE] addCommandMessage --> last command executed (send message), exit')
519
- }
520
- },command.time)
521
526
  }
522
- }
523
- execute(commands[0]) //START render first message
527
+ execute(commands[0]) //START render first message
528
+ })
524
529
  }
525
530
 
526
531
  private generateMessageObject(message, command_message, callback) {