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 +23 -0
- package/appInstaller.js +1 -299
- package/instalador_antigo/LICENSE +5 -0
- package/instalador_antigo/Multizap.zip +0 -0
- package/instalador_antigo/README.md +10 -0
- package/instalador_antigo/config +3 -0
- package/instalador_antigo/instalar_nova_instancia +75 -0
- package/instalador_antigo/instalar_primaria +220 -0
- package/instalador_antigo/lib/_backend.sh +453 -0
- package/instalador_antigo/lib/_frontend.sh +342 -0
- package/instalador_antigo/lib/_inquiry.sh +247 -0
- package/instalador_antigo/lib/_system.sh +676 -0
- package/instalador_antigo/lib/manifest.sh +6 -0
- package/instalador_antigo/utils/_banner.sh +45 -0
- package/instalador_antigo/utils/manifest.sh +3 -0
- package/instalador_antigo/variables/_app.sh +15 -0
- package/instalador_antigo/variables/_background.sh +6 -0
- package/instalador_antigo/variables/_fonts.sh +16 -0
- package/instalador_antigo/variables/_general.sh +5 -0
- package/instalador_antigo/variables/manifest.sh +6 -0
- package/installers/system/certbotSetup.js +16 -0
- package/installers/system/copyProjectFiles.js +20 -0
- package/installers/system/index.js +12 -2
- package/package.json +1 -1
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 {
|
|
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');
|
|
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,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
|