Skip to content

Commit 00d4822

Browse files
authoredMay 4, 2021
feat(project): added command sms & refactored project (caioagiani#26)
* feat(project): added command sms & refactored project * chore(package): updated versions
1 parent 32f2418 commit 00d4822

20 files changed

+145
-59
lines changed
 

‎.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
MOBIZON_URL_SRV=https://api.mobizon.com.br
2+
MOBIZON_API_KEY=

‎.eslintrc.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
module.exports = {
22
parser: '@typescript-eslint/parser',
33
extends: [
4-
'plugin:react/recommended',
54
'plugin:@typescript-eslint/recommended',
6-
'prettier/@typescript-eslint',
5+
'prettier',
76
'plugin:prettier/recommended',
87
],
98
settings: {
@@ -16,7 +15,7 @@ module.exports = {
1615
node: true,
1716
es6: true,
1817
},
19-
plugins: ['@typescript-eslint', 'react', 'prettier'],
18+
plugins: ['@typescript-eslint', 'prettier'],
2019
parserOptions: {
2120
ecmaFeatures: {
2221
jsx: true,
@@ -25,7 +24,6 @@ module.exports = {
2524
sourceType: 'module',
2625
},
2726
rules: {
28-
'react/prop-types': 'off',
2927
'prettier/prettier': 'error',
3028
'@typescript-eslint/no-unused-vars': 'off',
3129
'@typescript-eslint/explicit-function-return-type': 'off',

‎.github/workflows/lint.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Lint
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
eslint:
9+
name: eslint
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v2
13+
- name: install node v12
14+
uses: actions/setup-node@v2
15+
with:
16+
node-version: 12
17+
- name: npm install
18+
run: npm install
19+
- name: eslint
20+
uses: icrawl/action-eslint@v1
21+
env:
22+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
23+
with:
24+
job-name: eslint

‎.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
.env
2+
13
dist
24
node_modules
35

@@ -9,4 +11,4 @@ public/images/*
911
src/data/session.json
1012
!src/data/.gitkeep
1113

12-
src/config/integrantes.json
14+
src/config/integrantes.json

‎.prettierrc

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
"semi": true,
44
"singleQuote": true,
55
"tabWidth": 2,
6-
"trailingComma": "es5"
7-
}
6+
"trailingComma": "all"
7+
}

‎ambient.d.ts

-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
// declare module 'whatsapp-web.js';
21
declare module 'qrcode-terminal';

‎package.json

+8-7
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,26 @@
4646
"dev": "ts-node-dev --respawn --transpile-only --ignore-watch node_modules --ignore-watch src/data -r dotenv/config src/index.ts"
4747
},
4848
"dependencies": {
49+
"@types/node": "^15.0.1",
4950
"axios": "^0.21.1",
5051
"express": "^4.17.1",
52+
"mobizon-node": "^0.3.1",
5153
"node-base64-image": "^2.0.1",
5254
"puppeteer": "^8.0.0",
5355
"qr-image": "^3.2.0",
5456
"qrcode-terminal": "^0.12.0",
55-
"whatsapp-web.js": "^1.12.4"
57+
"whatsapp-web.js": "^1.12.6"
5658
},
5759
"devDependencies": {
5860
"@types/axios": "0.14.0",
5961
"@types/puppeteer": "5.4.3",
60-
"@typescript-eslint/eslint-plugin": "4.19.0",
61-
"@typescript-eslint/parser": "4.19.0",
62+
"@typescript-eslint/eslint-plugin": "4.22.1",
63+
"@typescript-eslint/parser": "4.22.1",
6264
"dotenv": "8.2.0",
63-
"eslint": "7.24.0",
64-
"eslint-config-prettier": "8.1.0",
65+
"eslint": "7.25.0",
66+
"eslint-config-prettier": "8.3.0",
6567
"eslint-loader": "4.0.2",
66-
"eslint-plugin-prettier": "3.3.1",
67-
"eslint-plugin-react": "7.22.0",
68+
"eslint-plugin-prettier": "3.4.0",
6869
"prettier": "2.2.1",
6970
"ts-node-dev": "1.1.6",
7071
"typescript": "4.2.4"

‎src/app/commands/CepCommand.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ export default class EconomyCommand {
1717

1818
try {
1919
const { data }: IResponse = await axios.get<IServerData>(
20-
`https://brasilapi.com.br/api/cep/v1/${setCep}`
20+
`https://brasilapi.com.br/api/cep/v1/${setCep}`,
2121
);
2222

2323
return msg.reply(
24-
`*CEP*: ${data.cep}\n*Logradouro*: ${data.street}\n*Cidade*: ${data.city}\n*Bairro*: ${data.neighborhood}\n*UF*: ${data.state}`
24+
`*CEP*: ${data.cep}\n*Logradouro*: ${data.street}\n*Cidade*: ${data.city}\n*Bairro*: ${data.neighborhood}\n*UF*: ${data.state}`,
2525
);
2626
} catch (error) {
2727
return msg.reply(`CEP não localizado!`);

‎src/app/commands/EconomyCommand.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default class EconomyCommand {
99
chat.sendStateTyping();
1010

1111
const { data } = await axios.get(
12-
'https://economia.awesomeapi.com.br/all/USD-BRL,BTC-BRL,EUR-BRL'
12+
'https://economia.awesomeapi.com.br/all/USD-BRL,BTC-BRL,EUR-BRL',
1313
);
1414

1515
const type = (currency: ICurrency) => {
@@ -18,8 +18,8 @@ export default class EconomyCommand {
1818

1919
return msg.reply(
2020
`Cotação atual: 💎💰🤑💹 \n${type(data.USD)} ${type(data.EUR)} ${type(
21-
data.BTC
22-
)}`
21+
data.BTC,
22+
)}`,
2323
);
2424
}
2525
}

‎src/app/commands/ProfileCommand.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { client, MessageMedia } from '../../server';
1+
import { client, MessageMedia } from '../../services/whatsapp';
22
import { encode } from 'node-base64-image';
33
import type { Message } from 'whatsapp-web.js';
44

@@ -19,10 +19,10 @@ export default class ProfileCommand {
1919
return msg.reply('Comando apenas para grupos!');
2020
}
2121

22-
msg.reply('Stalkeando este contato...');
23-
2422
if (!contact) return msg.reply('Contato não localizado.');
2523

24+
msg.reply('Stalkeando este contato...');
25+
2626
const url_i = await client.getProfilePicUrl(contact.number);
2727

2828
if (!url_i) return msg.reply('Imagem não foi localizada.');

‎src/app/commands/QuoteCommand.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { client } from '../../server';
1+
import { client } from '../../services/whatsapp';
22
import { company } from '../../config/integrantes.json';
33
import type { Message, GroupChat } from 'whatsapp-web.js';
44

@@ -19,7 +19,7 @@ export default class QuoteCommand {
1919
if (valores.numero == contato) {
2020
if (!valores.admin) {
2121
return msg.reply(
22-
'Ops, você não tem permissão para executar este comando!'
22+
'Ops, você não tem permissão para executar este comando!',
2323
);
2424
}
2525

@@ -28,7 +28,7 @@ export default class QuoteCommand {
2828

2929
for (const participant of chat.participants) {
3030
const contact = await client.getContactById(
31-
participant.id._serialized
31+
participant.id._serialized,
3232
);
3333

3434
mentions.push(contact);

‎src/app/commands/SmsCommand.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import type { Message } from 'whatsapp-web.js';
2+
import mobizon from '../../services/mobizon';
3+
4+
export default class ProfileCommand {
5+
mention: string;
6+
constructor(mention: string) {
7+
this.mention = mention;
8+
}
9+
10+
async execute(msg: Message) {
11+
const chat = await msg.getChat();
12+
13+
const [contact] = await msg.getMentions();
14+
15+
chat.sendStateTyping();
16+
17+
if (!chat.isGroup) {
18+
return msg.reply('Comando apenas para grupos!');
19+
}
20+
21+
if (!contact) return msg.reply('Contato não localizado.');
22+
23+
const sendSms = await mobizon.sendSms({
24+
recipient: contact.number,
25+
from: '',
26+
text: 'Sms enviado via BOT.',
27+
});
28+
29+
if (sendSms.code !== 0) {
30+
return msg.reply('Oops, houve um erro ao enviar SMS, tente novamente.');
31+
}
32+
33+
return msg.reply('SMS enviado com sucesso!');
34+
}
35+
}

‎src/app/commands/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export { default as EconomyCommand } from './EconomyCommand';
22
export { default as QuoteCommand } from './QuoteCommand';
33
export { default as CepCommand } from './CepCommand';
44
export { default as ProfileCommand } from './ProfileCommand';
5+
export { default as SmsCommand } from './SmsCommand';

‎src/app/interfaces/Cep.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
1-
interface IResponse {
1+
export interface IResponse {
22
data: IServerData;
33
}
44

5-
interface IServerData {
5+
export interface IServerData {
66
cep: string;
77
state: string;
88
city: string;
99
neighborhood: string;
1010
street: string;
1111
}
12-
13-
export { IResponse, IServerData };

‎src/app/interfaces/Currency.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
interface ICurrency {
1+
export interface ICurrency {
22
code: string;
33
codein: string;
44
name: string;
@@ -11,5 +11,3 @@ interface ICurrency {
1111
timestamp: string;
1212
create_date: string;
1313
}
14-
15-
export { ICurrency };

‎src/app/utils/CommandDispatcher.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Command from './Command';
22

3-
export default class CommandDispatcher {
3+
class CommandDispatcher {
44
private commandsHandlers: Map<string, Command<any>> = new Map();
55

66
async register(name: string, command: Command<any>) {
@@ -20,3 +20,5 @@ export default class CommandDispatcher {
2020
}
2121
}
2222
}
23+
24+
export const commandDispatcher = new CommandDispatcher();

‎src/index.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
1-
import { client } from './server';
1+
import { client } from './services/whatsapp';
22
import {
33
EconomyCommand,
44
QuoteCommand,
55
CepCommand,
66
ProfileCommand,
7+
SmsCommand,
78
} from './app/commands';
8-
import CommandDispatcher from './app/utils/CommandDispatcher';
9+
import { commandDispatcher } from './app/utils/CommandDispatcher';
910
import type { Message } from 'whatsapp-web.js';
1011

11-
const dispatcher = new CommandDispatcher();
12+
client.on('message', (message: Message) => {
13+
const economyCommand = new EconomyCommand();
14+
const quoteCommand = new QuoteCommand();
15+
const cepCommand = new CepCommand(message.body);
16+
const profileCommand = new ProfileCommand(message.body);
17+
const smsCommand = new SmsCommand(message.body);
1218

13-
client.on('message', async (message: Message) => {
14-
dispatcher.register('cotacao', new EconomyCommand());
15-
dispatcher.register('mencionar', new QuoteCommand());
16-
dispatcher.register('cep', new CepCommand(message.body));
17-
dispatcher.register('perfil', new ProfileCommand(message.body));
19+
commandDispatcher.register('cotacao', economyCommand);
20+
commandDispatcher.register('mencionar', quoteCommand);
21+
commandDispatcher.register('cep', cepCommand);
22+
commandDispatcher.register('perfil', profileCommand);
23+
commandDispatcher.register('sms', smsCommand);
1824

1925
if (message.body.startsWith('!')) {
20-
dispatcher.dispatch(message.body.slice(1), message);
26+
commandDispatcher.dispatch(message.body.slice(1), message);
2127
}
2228
});

‎src/services/mobizon.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { mobizon } from 'mobizon-node';
2+
3+
mobizon.setConfig({
4+
apiServer: process.env.MOBIZON_URL_SRV,
5+
apiKey: process.env.MOBIZON_API_KEY,
6+
format: 'json',
7+
});
8+
9+
export default mobizon;

‎src/server.ts ‎src/services/whatsapp.ts

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
import { Client, MessageMedia } from 'whatsapp-web.js';
2-
import qrcode from 'qrcode-terminal';
3-
import fs from 'fs';
4-
import dir from 'path';
2+
import { generate } from 'qrcode-terminal';
3+
import { existsSync, writeFile, unlink } from 'fs';
4+
import { resolve } from 'path';
55

66
interface INotification {
77
reply: (args: string) => void;
88
recipientIds: any[];
99
}
1010

11-
const sessionFile = dir.resolve('src', 'data', 'session.json');
11+
const sessionFile = resolve('src', 'data', 'session.json');
1212

13-
const session = fs.existsSync(sessionFile) ? require(sessionFile) : null;
13+
const session = existsSync(sessionFile) ? require(sessionFile) : null;
1414

1515
const client = new Client({
1616
puppeteer: {
1717
headless: true,
1818
args: ['--no-sandbox'],
1919
},
2020
session,
21-
});
21+
} as any);
2222

2323
client.on('qr', (qr: string) => {
24-
qrcode.generate(qr, { small: true });
24+
generate(qr, { small: true });
2525
});
2626

2727
client.on('authenticated', (session: any) => {
28-
fs.writeFile(sessionFile, JSON.stringify(session), (err) => {
28+
writeFile(sessionFile, JSON.stringify(session), (err) => {
2929
if (err) console.log(err);
3030
});
3131
});
@@ -35,19 +35,22 @@ client.on('ready', async () => {
3535

3636
const { pushname } = client.info;
3737

38-
client.sendMessage('5511987454933@c.us', `[${pushname}] - WhatsApp Online`);
38+
client.sendMessage(
39+
'5511963928063@c.us',
40+
`[${pushname}] - WhatsApp Online\n\n[x] Star on project: https://github.com/caioagiani/whatsapp-bot`,
41+
);
3942
});
4043

4144
client.on('auth_failure', () => {
42-
fs.unlink(sessionFile, () => {
45+
unlink(sessionFile, () => {
4346
console.log('Autenticação falhou, tente novamente.');
4447
process.exit(1);
4548
});
4649
});
4750

4851
client.on('disconnected', () => {
49-
fs.unlink(sessionFile, () =>
50-
console.log('Sessão WhatsApp perdeu a conexão, tente novamente.')
52+
unlink(sessionFile, () =>
53+
console.log('Sessão WhatsApp perdeu a conexão, tente novamente.'),
5154
);
5255
});
5356

‎tsconfig.json

+12-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
{
22
"compilerOptions": {
3-
"outDir": "dist",
4-
"target": "ES6",
5-
"module": "CommonJS",
3+
"module": "commonjs",
4+
"declaration": true,
5+
"removeComments": true,
6+
"emitDecoratorMetadata": true,
7+
"experimentalDecorators": true,
8+
"allowSyntheticDefaultImports": true,
9+
"target": "es2017",
10+
"sourceMap": true,
11+
"outDir": "./dist",
12+
"baseUrl": "./",
13+
"incremental": true,
614
"resolveJsonModule": true,
7-
"esModuleInterop": true
15+
"allowJs": true
816
}
917
}

0 commit comments

Comments
 (0)
Please sign in to comment.