atendeticket 2.1.13 → 2.1.16

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/TODO.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## Completed Tasks
2
+ - [x] Update installPrompts.js to ask 10 specific questions in order
3
+ - [x] Update installNode.js to install Node.js 20.x from nodesource
4
+ - [x] Update installCertbot.js to install via snap
5
+ - [x] Fix deploy_email variable in appInstaller.js
6
+ - [x] Update setupSSL.js to accept email parameter and run for both domains
7
+ - [x] Implement delete.js action according to task commands
8
+ - [x] Implement changeDomain.js action according to task commands
9
+ - [x] Update backend setEnv.js to match simplified .env format
10
+ - [x] Update all variable names in appInstaller.js to match new prompts
11
+ - [x] Create copyProjectFiles.js to copy AtendeTicket.zip to deploy user directory
12
+ - [x] Add copyProjectFiles step to installation flow after user creation
13
+
14
+ ## Pending Tasks
15
+ - [ ] Verify all other installers match the task requirements
16
+ - [ ] Test the complete installation flow
17
+ - [ ] Add proper prompting for instancia name in delete and changeDomain actions
18
+ =======
1
19
  # TODO List for Installer Script
2
20
 
3
21
  ## Completed Tasks
@@ -8,6 +26,11 @@
8
26
  - [x] Update setupSSL.js to accept email parameter and run for both domains
9
27
  - [x] Implement delete.js action according to task commands
10
28
  - [x] Implement changeDomain.js action according to task commands
29
+ - [x] Update backend setEnv.js to match simplified .env format
30
+ - [x] Update all variable names in appInstaller.js to match new prompts
31
+ - [x] Create copyProjectFiles.js to copy AtendeTicket.zip to deploy user directory
32
+ - [x] Add copyProjectFiles step to installation flow after user creation
33
+ - [x] Fix appInstaller.js file corruption and add copyProjectFiles call
11
34
 
12
35
  ## Pending Tasks
13
36
  - [ ] Verify all other installers match the task requirements
package/appInstaller.js CHANGED
@@ -1,299 +1 @@
1
- const { mainMenuPrompt } = require('./prompts/mainMenu');
2
- const { installPrompts } = require('./prompts/installPrompts');
3
- const { domainPrompt } = require('./prompts/domainPrompts');
4
- const { updatePrompts } = require('./prompts/updatePrompts');
5
-
6
- const { updateSystem, installNode, installDocker, installPM2, installNginx, installCertbot, createUser } = require('./installers/system');
7
- const { createDatabase, createRedis, setEnv: setBackendEnv, installDeps: installBackendDeps, build: buildBackend, migrate, seed, startPM2: startBackendPM2, setupNginx: setupBackendNginx } = require('./installers/backend');
8
- const { setEnv: setFrontendEnv, installDeps: installFrontendDeps, build: buildFrontend, startPM2: startFrontendPM2, setupNginx: setupFrontendNginx } = require('./installers/frontend');
9
- const { setupSSL } = require('./ssl/setupSSL');
10
- const { delete: deleteAction } = require('./actions/delete');
11
- const { block } = require('./actions/block');
12
- const { unblock } = require('./actions/unblock');
13
- const { changeDomain } = require('./actions/changeDomain');
14
- const { update } = require('./actions/update');
15
-
16
- const { info, success } = require('./core/logger');
17
-
18
- async function runInstaller() {
19
- info('Bem-vindo ao instalador do AtendeTicket!');
20
-
21
- const mainMenu = await mainMenuPrompt();
22
-
23
- if (mainMenu.action === 'install') {
24
- const answers = await installPrompts();
25
-
26
- // Generate JWT secrets
27
- const jwt_secret = require('crypto').randomBytes(64).toString('base64');
28
- const jwt_refresh_secret = require('crypto').randomBytes(64).toString('base64');
29
-
30
- // Configurações automáticas do Redis
31
- const redis_host = "localhost";
32
- const redis_password = answers.mysql_root_password;
33
- const redis_uri = `redis://:${redis_password}@${redis_host}:${answers.redisPort}`;
34
-
35
- // Sistema
36
- await updateSystem();
37
- await installNode();
38
- await installDocker();
39
- await installPM2();
40
- await installNginx();
41
- await installCertbot();
42
- await createUser(answers.mysql_root_password);
43
-
44
- // Backend
45
- await createDatabase(answers.instancia_add, answers.mysql_root_password);
46
- await createRedis(answers.instancia_add, answers.redis_port, answers.mysql_root_password);
47
- await setBackendEnv(
48
- 'production', // node_env
49
- answers.backend_url,
50
- answers.frontend_url,
51
- answers.backend_port,
52
- 'localhost', // db_host
53
- answers.instancia_add, // db_user
54
- answers.mysql_root_password, // db_pass
55
- answers.instancia_add, // db_name
56
- 5432, // db_port
57
- 'postgres', // db_dialect
58
- jwt_secret,
59
- jwt_refresh_secret,
60
- redis_uri,
61
- answers.max_user, // user_limit
62
- answers.max_whats // connections_limit
63
- );
64
- await installBackendDeps();
65
- await buildBackend();
66
- await migrate();
67
- await seed();
68
- await startBackendPM2();
69
- await setupBackendNginx(answers.backendUrl.replace(/^https?:\/\//, ''));
70
-
71
- // Frontend
72
- await setFrontendEnv(
73
- answers.backend_url,
74
- 24, // hours_close_tickets_auto
75
- 'https', // backend_protocol
76
- answers.backend_url.replace(/^https?:\/\//, ''), // backend_host
77
- answers.backend_port, // backend_port_param
78
- 'pt-br', // locale
79
- 'America/Sao_Paulo', // timezone
80
- '55XXXXXXXXXXX', // number_support
81
- '2813216208828642', // facebook_app_id
82
- true, // require_business_management
83
- false, // certificates
84
- true, // https
85
- 'F:\\bkpidx\\workflow\\backend\\certs\\localhost.pem', // ssl_crt_file
86
- 'F:\\bkpidx\\workflow\\backend\\certs\\localhost-key.pem', // ssl_key_file
87
- '2813216208828642', // react_app_facebook_app_id
88
- true, // react_app_require_business_management
89
- false, // generate_sourcemap
90
- false // disable_eslint_plugin
91
- );
92
- await installFrontendDeps();
93
- await buildFrontend();
94
- await startFrontendPM2();
95
- await setupFrontendNginx(answers.frontend_url.replace(/^https?:\/\//, ''));
96
-
97
- // SSL
98
- const backend_domain = answers.backend_url.replace(/^https?:\/\//, '');
99
- const frontend_domain = answers.frontend_url.replace(/^https?:\/\//, '');
100
- await setupSSL(backend_domain, frontend_domain, answers.deploy_email);
101
-
102
- success('Instalação completa do Multizap!');
103
- }
104
-
105
- if (mainMenu.action === 'update') {
106
- const answers = await updatePrompts();
107
-
108
- if (answers.updateSystem) await updateSystem();
109
- if (answers.updateBackend) {
110
- await installBackendDeps();
111
- await buildBackend();
112
- await migrate();
113
- await seed();
114
- await startBackendPM2();
115
- }
116
- if (answers.updateFrontend) {
117
- await installFrontendDeps();
118
- await buildFrontend();
119
- await startFrontendPM2();
120
- }
121
-
122
- success('Atualização concluída!');
123
- }
124
-
125
- if (mainMenu.action === 'delete') {
126
- await deleteAction();
127
- success('Instância deletada com sucesso!');
128
- }
129
-
130
- if (mainMenu.action === 'block') {
131
- await block();
132
- success('Instância bloqueada com sucesso!');
133
- }
134
-
135
- if (mainMenu.action === 'unblock') {
136
- await unblock();
137
- success('Instância desbloqueada com sucesso!');
138
- }
139
-
140
- if (mainMenu.action === 'changeDomain') {
141
- await changeDomain();
142
- success('Domínio alterado com sucesso!');
143
- }
144
-
145
- if (mainMenu.action === 'update') {
146
- await update();
147
- success('Atualização concluída!');
148
- }
149
- }
150
-
151
- async function handleMenu(choice) {
152
- if (choice.action === 'install') {
153
- const answers = await installPrompts();
154
-
155
- // Generate JWT secrets
156
- const jwt_secret = require('crypto').randomBytes(64).toString('base64');
157
- const jwt_refresh_secret = require('crypto').randomBytes(64).toString('base64');
158
-
159
- // Configurações automáticas do Redis
160
- const redis_host = "localhost";
161
- const redis_password = answers.mysql_root_password;
162
- const redis_uri = `redis://:${redis_password}@${redis_host}:${answers.redisPort}`;
163
-
164
- // Sistema
165
- await updateSystem();
166
- await installNode();
167
- await installDocker();
168
- await installPM2();
169
- await installNginx();
170
- await installCertbot();
171
- await createUser(answers.mysql_root_password);
172
-
173
- // Backend
174
- await createDatabase(answers.instancia_add, answers.mysql_root_password);
175
- await createRedis(answers.instancia_add, answers.redisPort, answers.mysql_root_password);
176
- await setBackendEnv(
177
- '', // node_env
178
- answers.backendUrl,
179
- answers.frontendUrl,
180
- 443, // proxy_port
181
- answers.backendPort,
182
- 'localhost', // db_host
183
- 'postgres', // db_dialect
184
- answers.instancia_add, // db_user
185
- answers.mysql_root_password, // db_pass
186
- answers.instancia_add, // db_name
187
- 5432, // db_port
188
- 'senha_master', // master_key
189
- 1, // import_fallback_file
190
- 1000, // timeout_to_import_message
191
- 3, // app_trialexpiration
192
- jwt_secret,
193
- jwt_refresh_secret,
194
- redis_uri,
195
- 1, // redis_opt_limiter_max
196
- 3000, // redis_opt_limiter_duration
197
- 8, // flow_menu_cooldown_sec
198
- answers.max_user, // user_limit
199
- answers.max_whats, // connections_limit
200
- true, // closed_send_by_me
201
- 'whaticket', // verify_token
202
- '', // mp_access_token
203
- '2813216208828642', // facebook_app_id
204
- '8233912aeade366dd8e2ebef6be256b6', // facebook_app_secret
205
- 'smtp.gmail.com', // smtp_host
206
- '587', // smtp_port
207
- 'false', // smtp_secure
208
- 'seuemail@gmail.com', // smtp_user
209
- 'suasenha', // smtp_pass
210
- 'Redefinição de senha <seuemail@gmail.com>' // smtp_from
211
- );
212
- await installBackendDeps();
213
- await buildBackend();
214
- await migrate();
215
- await seed();
216
- await startBackendPM2();
217
- await setupBackendNginx(answers.backendUrl.replace(/^https?:\/\//, ''));
218
-
219
- // Frontend
220
- await setFrontendEnv(
221
- answers.backendUrl,
222
- 24, // hours_close_tickets_auto
223
- 'https', // backend_protocol
224
- answers.backendUrl.replace(/^https?:\/\//, ''), // backend_host
225
- answers.backendPort, // backend_port_param
226
- 'pt-br', // locale
227
- 'America/Sao_Paulo', // timezone
228
- '55XXXXXXXXXXX', // number_support
229
- '2813216208828642', // facebook_app_id
230
- true, // require_business_management
231
- false, // certificates
232
- true, // https
233
- 'F:\\bkpidx\\workflow\\backend\\certs\\localhost.pem', // ssl_crt_file
234
- 'F:\\bkpidx\\workflow\\backend\\certs\\localhost-key.pem', // ssl_key_file
235
- '2813216208828642', // react_app_facebook_app_id
236
- true, // react_app_require_business_management
237
- false, // generate_sourcemap
238
- false // disable_eslint_plugin
239
- );
240
- await installFrontendDeps();
241
- await buildFrontend();
242
- await startFrontendPM2();
243
- await setupFrontendNginx(answers.frontendUrl.replace(/^https?:\/\//, ''));
244
-
245
- // SSL
246
- const backend_domain = answers.backendUrl.replace(/^https?:\/\//, '');
247
- const frontend_domain = answers.frontendUrl.replace(/^https?:\/\//, '');
248
- await setupSSL(backend_domain, frontend_domain, answers.deployEmail);
249
-
250
- success('Instalação completa do Multizap!');
251
- }
252
-
253
- if (choice.action === 'update') {
254
- const answers = await updatePrompts();
255
-
256
- if (answers.updateSystem) await updateSystem();
257
- if (answers.updateBackend) {
258
- await installBackendDeps();
259
- await buildBackend();
260
- await migrate();
261
- await seed();
262
- await startBackendPM2();
263
- }
264
- if (answers.updateFrontend) {
265
- await installFrontendDeps();
266
- await buildFrontend();
267
- await startFrontendPM2();
268
- }
269
-
270
- success('Atualização concluída!');
271
- }
272
-
273
- if (choice.action === 'delete') {
274
- await deleteAction();
275
- success('Instância deletada com sucesso!');
276
- }
277
-
278
- if (choice.action === 'block') {
279
- await block();
280
- success('Instância bloqueada com sucesso!');
281
- }
282
-
283
- if (choice.action === 'unblock') {
284
- await unblock();
285
- success('Instância desbloqueada com sucesso!');
286
- }
287
-
288
- if (choice.action === 'changeDomain') {
289
- await changeDomain();
290
- success('Domínio alterado com sucesso!');
291
- }
292
-
293
- if (choice.action === 'update') {
294
- await update();
295
- success('Atualização concluída!');
296
- }
297
- }
298
-
299
- module.exports = { runInstaller, handleMenu };
1
+ const { updateSystem, installNode, installDocker, installPM2, installNginx, installCertbot, createUser, copyProjectFiles } = require('./installers/system');
@@ -0,0 +1,5 @@
1
+ portaldozap.com.br
2
+
3
+ Produto exclusivo da Site Connect
4
+
5
+ (41) 99209-8329
Binary file
@@ -0,0 +1,10 @@
1
+ Multizap Flow 4.2.5
2
+
3
+ https://portaldozap.com.br
4
+
5
+ https://www.youtube.com/@siteconnect
6
+
7
+ Instalar command:
8
+
9
+ ```bash
10
+ sudo apt install -y git && git clone https://github.com/lipedevv/multizapflow4.2.5.git && sudo chmod -R 777 multizapflow4.2.5 && cd multizapflow4.2.5 && sudo ./instalar_primaria
@@ -0,0 +1,3 @@
1
+ deploy_password=
2
+ mysql_root_password=
3
+ db_pass=3PDTleNftG3hfREtysleqHx61bgyKO89z2wIQ2Guw7M=
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+
3
+ # reset shell colors
4
+ tput init
5
+
6
+ # https://stackoverflow.com/questions/59895/how-to-get-the-source-directory-of-a-bash-script-from-within-the-script-itself
7
+ SOURCE="${BASH_SOURCE[0]}"
8
+ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
9
+ PROJECT_ROOT="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
10
+ SOURCE="$(readlink "$SOURCE")"
11
+ [[ $SOURCE != /* ]] && SOURCE="$PROJECT_ROOT/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
12
+ done
13
+ PROJECT_ROOT="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
14
+
15
+ # required imports
16
+ source "${PROJECT_ROOT}"/variables/manifest.sh
17
+ source "${PROJECT_ROOT}"/utils/manifest.sh
18
+ source "${PROJECT_ROOT}"/lib/manifest.sh
19
+
20
+ # user configs file
21
+ if [[ ! -e "${PROJECT_ROOT}"/config ]]; then
22
+ cat << EOF > "${PROJECT_ROOT}"/config
23
+ deploy_password=${deploy_password}
24
+ mysql_root_password=${mysql_root_password}
25
+ db_pass=${db_pass}
26
+ EOF
27
+ fi
28
+
29
+ # this file has passwords
30
+ sudo su - root <<EOF
31
+ chown root:root "${PROJECT_ROOT}"/config
32
+ chmod 700 "${PROJECT_ROOT}"/config
33
+ EOF
34
+ source "${PROJECT_ROOT}"/config
35
+
36
+ # interactive CLI
37
+ inquiry_options
38
+
39
+ # dependencies related
40
+ #system_update
41
+ #system_node_install
42
+ #system_pm2_install
43
+ #system_docker_install
44
+ #system_puppeteer_dependencies
45
+ #system_snapd_install
46
+ #system_nginx_install
47
+ #system_certbot_install
48
+
49
+ # system config
50
+ #system_create_user
51
+
52
+ # backend related
53
+ system_create_folder
54
+ system_mv_folder
55
+ system_unzip_Multizap
56
+ backend_set_env
57
+ backend_redis_create
58
+ backend_node_dependencies
59
+ backend_node_build
60
+ backend_db_migrate
61
+ backend_db_seed
62
+ backend_start_pm2
63
+ backend_nginx_setup
64
+
65
+ # frontend related
66
+ frontend_set_env
67
+ frontend_node_dependencies
68
+ frontend_node_build
69
+ frontend_start_pm2
70
+ frontend_nginx_setup
71
+
72
+ # network related
73
+ #system_nginx_conf
74
+ system_nginx_restart
75
+ system_certbot_setup
@@ -0,0 +1,220 @@
1
+ #!/bin/bash
2
+
3
+ # reset shell colors
4
+ tput init
5
+
6
+ # https://stackoverflow.com/questions/59895/how-to-get-the-source-directory-of-a-bash-script-from-within-the-script-itself
7
+ SOURCE="${BASH_SOURCE[0]}"
8
+ while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
9
+ PROJECT_ROOT="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
10
+ SOURCE="$(readlink "$SOURCE")"
11
+ [[ $SOURCE != /* ]] && SOURCE="$PROJECT_ROOT/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
12
+ done
13
+ PROJECT_ROOT="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )"
14
+
15
+ sed -i "/#\$nrconf{restart} = 'i';/s/.*/\$nrconf{restart} = 'a';/" /etc/needrestart/needrestart.conf
16
+
17
+ # required imports
18
+ source "${PROJECT_ROOT}"/variables/manifest.sh
19
+ source "${PROJECT_ROOT}"/utils/manifest.sh
20
+ source "${PROJECT_ROOT}"/lib/manifest.sh
21
+
22
+ # user configs file
23
+ if [[ ! -e "${PROJECT_ROOT}"/config ]]; then
24
+ cat << EOF > "${PROJECT_ROOT}"/config
25
+ deploy_password=${deploy_password}
26
+ mysql_root_password=${mysql_root_password}
27
+ db_pass=${db_pass}
28
+ EOF
29
+ fi
30
+
31
+ # this file has passwords
32
+ sudo su - root <<EOF
33
+ chown root:root "${PROJECT_ROOT}"/config
34
+ chmod 700 "${PROJECT_ROOT}"/config
35
+ EOF
36
+ source "${PROJECT_ROOT}"/config
37
+
38
+ # interactive CLI
39
+ inquiry_options
40
+
41
+ # Generate JWT secrets if not already set
42
+ if [ -z "$jwt_secret" ] || [ -z "$jwt_refresh_secret" ]; then
43
+ print_banner
44
+ printf "${WHITE} 💻 Gerando segredos JWT...${GRAY_LIGHT}"
45
+ printf "\n\n"
46
+
47
+ jwt_secret=$(openssl rand -base64 64 | tr -d '\n')
48
+ jwt_refresh_secret=$(openssl rand -base64 64 | tr -d '\n')
49
+
50
+ # Save to config file
51
+ echo "jwt_secret=${jwt_secret}" >> "${PROJECT_ROOT}"/config
52
+ echo "jwt_refresh_secret=${jwt_refresh_secret}" >> "${PROJECT_ROOT}"/config
53
+
54
+ printf "${GREEN} ✅ Segredos JWT gerados automaticamente${GRAY_LIGHT}\n"
55
+ sleep 2
56
+ fi
57
+
58
+ # Configurações automáticas do Redis
59
+ redis_host="localhost"
60
+ redis_password="${mysql_root_password}"
61
+
62
+ printf "\n${GREEN} ✅ Redis configurado automaticamente:${GRAY_LIGHT}"
63
+ printf "\n${GREEN} Host: localhost | Senha: mesma do banco${GRAY_LIGHT}\n"
64
+ sleep 2
65
+
66
+ print_banner
67
+ printf "${WHITE} 🚀 Iniciando instalação completa do Multizap...${GRAY_LIGHT}"
68
+ printf "\n\n"
69
+ printf "${WHITE} 📝 Configurações:${GRAY_LIGHT}"
70
+ printf "\n"
71
+ printf "${WHITE} 🏢 Instância: ${instancia_add}${GRAY_LIGHT}"
72
+ printf "\n"
73
+ printf "${WHITE} 🌐 Frontend: ${frontend_url}:${frontend_port}${GRAY_LIGHT}"
74
+ printf "\n"
75
+ printf "${WHITE} 🔧 Backend: ${backend_url}:${backend_port}${GRAY_LIGHT}"
76
+ printf "\n"
77
+ printf "${WHITE} 🗄️ Redis: ${redis_host}:${redis_port} (Automático)${GRAY_LIGHT}"
78
+ printf "\n"
79
+ printf "${WHITE} 👥 Usuários: ${max_user} | Conexões: ${max_whats}${GRAY_LIGHT}"
80
+ printf "\n\n"
81
+
82
+ sleep 3
83
+
84
+ # dependencies related
85
+ printf "${WHITE} 📦 Instalando dependências do sistema...${GRAY_LIGHT}\n"
86
+ system_update
87
+ system_node_install
88
+ system_docker_install
89
+ system_puppeteer_dependencies
90
+ system_pm2_install
91
+ system_snapd_install
92
+ system_nginx_install
93
+ system_certbot_install
94
+
95
+ # system config
96
+ printf "${WHITE} 🔧 Configurando sistema...${GRAY_LIGHT}\n"
97
+ system_create_user
98
+
99
+ # backend related
100
+ printf "${WHITE} 🛠️ Configurando backend...${GRAY_LIGHT}\n"
101
+ system_create_folder
102
+ system_mv_folder
103
+ system_unzip_Multizap
104
+ backend_set_env
105
+ backend_redis_create
106
+ backend_node_dependencies
107
+ backend_node_build
108
+ backend_db_migrate
109
+ backend_db_seed
110
+ backend_start_pm2
111
+ backend_nginx_setup
112
+
113
+ # frontend related
114
+ printf "${WHITE} 🎨 Configurando frontend...${GRAY_LIGHT}\n"
115
+ frontend_set_env
116
+ frontend_node_dependencies
117
+ frontend_node_build
118
+ frontend_start_pm2
119
+ frontend_nginx_setup
120
+
121
+ # network related
122
+ printf "${WHITE} 🌐 Configurando rede...${GRAY_LIGHT}\n"
123
+ system_nginx_conf
124
+ system_nginx_restart
125
+ system_certbot_setup
126
+
127
+ # Final setup and verification
128
+ print_banner
129
+ printf "${WHITE} 🔍 Verificando serviços...${GRAY_LIGHT}"
130
+ printf "\n\n"
131
+
132
+ sleep 2
133
+
134
+ # Verify services
135
+ printf "${WHITE} 🔄 Verificando PM2...${GRAY_LIGHT}\n"
136
+ sudo su - deploy <<EOF
137
+ echo "📊 Listando processos PM2..."
138
+ pm2 list
139
+
140
+ echo "🔍 Verificando backend..."
141
+ sleep 5
142
+ if curl -f http://localhost:${backend_port}/ >/dev/null 2>&1; then
143
+ echo "✅ Backend respondendo na porta ${backend_port}"
144
+ else
145
+ echo "⚠️ Backend não respondeu imediatamente, aguardando..."
146
+ sleep 10
147
+ curl -f http://localhost:${backend_port}/ && echo "✅ Backend respondendo" || echo "❌ Backend não responde"
148
+ fi
149
+
150
+ echo "🔍 Verificando frontend..."
151
+ if curl -f http://localhost:${frontend_port}/ >/dev/null 2>&1; then
152
+ echo "✅ Frontend respondendo na porta ${frontend_port}"
153
+ else
154
+ echo "⚠️ Frontend não respondeu imediatamente"
155
+ fi
156
+ EOF
157
+
158
+ # Verify Redis
159
+ printf "${WHITE} 🔄 Verificando Redis...${GRAY_LIGHT}\n"
160
+ sudo su - root <<EOF
161
+ echo "🐳 Verificando container Redis..."
162
+ if docker ps | grep -q "redis-${instancia_add}"; then
163
+ echo "✅ Container Redis está rodando"
164
+ else
165
+ echo "❌ Container Redis não está rodando"
166
+ exit 1
167
+ fi
168
+
169
+ echo "🔗 Testando conexão com Redis..."
170
+ if docker exec redis-${instancia_add} redis-cli -a ${redis_password} ping | grep -q "PONG"; then
171
+ echo "✅ Conexão Redis OK"
172
+ echo "📊 Configuração Redis:"
173
+ echo " 🏠 Host: localhost"
174
+ echo " 🔑 Senha: mesma do banco"
175
+ echo " 📍 Porta: ${redis_port}"
176
+ else
177
+ echo "❌ Falha na conexão Redis"
178
+ exit 1
179
+ fi
180
+ EOF
181
+
182
+ sleep 2
183
+
184
+ print_banner
185
+ printf "${GREEN} ✅ Instalação do Multizap concluída com sucesso!${GRAY_LIGHT}"
186
+ printf "\n\n"
187
+ printf "${WHITE} 📊 Resumo da instalação:${GRAY_LIGHT}"
188
+ printf "\n"
189
+ printf "${WHITE} 🏢 Instância: ${instancia_add}${GRAY_LIGHT}"
190
+ printf "\n"
191
+ printf "${WHITE} 🌐 Frontend: ${frontend_url}${GRAY_LIGHT}"
192
+ printf "\n"
193
+ printf "${WHITE} 🔧 Backend: ${backend_url}${GRAY_LIGHT}"
194
+ printf "\n"
195
+ printf "${WHITE} 🗄️ Redis: ${redis_host}:${redis_port} (Automático)${GRAY_LIGHT}"
196
+ printf "\n"
197
+ printf "${WHITE} 👥 Limite de usuários: ${max_user}${GRAY_LIGHT}"
198
+ printf "\n"
199
+ printf "${WHITE} 📞 Limite de conexões: ${max_whats}${GRAY_LIGHT}"
200
+ printf "\n\n"
201
+ printf "${WHITE} 🔧 Comandos úteis:${GRAY_LIGHT}"
202
+ printf "\n"
203
+ printf "${WHITE} Ver logs: pm2 logs ${instancia_add}-backend${GRAY_LIGHT}"
204
+ printf "\n"
205
+ printf "${WHITE} Reiniciar: pm2 restart ${instancia_add}-backend${GRAY_LIGHT}"
206
+ printf "\n"
207
+ printf "${WHITE} Status: pm2 status${GRAY_LIGHT}"
208
+ printf "\n"
209
+ printf "${WHITE} Redis: docker logs redis-${instancia_add}${GRAY_LIGHT}"
210
+ printf "\n\n"
211
+ printf "${WHITE} 🎯 Próximos passos:${GRAY_LIGHT}"
212
+ printf "\n"
213
+ printf "${WHITE} 1. Acesse ${frontend_url}${GRAY_LIGHT}"
214
+ printf "\n"
215
+ printf "${WHITE} 2. Configure o WhatsApp no painel${GRAY_LIGHT}"
216
+ printf "\n"
217
+ printf "${WHITE} 3. Teste o agendamento de mensagens (Redis)${GRAY_LIGHT}"
218
+ printf "\n\n"
219
+
220
+ sleep 3