Skip to content

Commit

Permalink
feat(project): added command sms & refactored project (#26)
Browse files Browse the repository at this point in the history
* feat(project): added command sms & refactored project
* chore(package): updated versions
  • Loading branch information
caioagiani authored May 4, 2021
1 parent 32f2418 commit 00d4822
Show file tree
Hide file tree
Showing 20 changed files with 145 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
MOBIZON_URL_SRV=https://api.mobizon.com.br
MOBIZON_API_KEY=
6 changes: 2 additions & 4 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
module.exports = {
parser: '@typescript-eslint/parser',
extends: [
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'prettier/@typescript-eslint',
'prettier',
'plugin:prettier/recommended',
],
settings: {
Expand All @@ -16,7 +15,7 @@ module.exports = {
node: true,
es6: true,
},
plugins: ['@typescript-eslint', 'react', 'prettier'],
plugins: ['@typescript-eslint', 'prettier'],
parserOptions: {
ecmaFeatures: {
jsx: true,
Expand All @@ -25,7 +24,6 @@ module.exports = {
sourceType: 'module',
},
rules: {
'react/prop-types': 'off',
'prettier/prettier': 'error',
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
Expand Down
24 changes: 24 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Lint

on:
push:
pull_request:

jobs:
eslint:
name: eslint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: install node v12
uses: actions/setup-node@v2
with:
node-version: 12
- name: npm install
run: npm install
- name: eslint
uses: icrawl/action-eslint@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
job-name: eslint
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.env

dist
node_modules

Expand All @@ -9,4 +11,4 @@ public/images/*
src/data/session.json
!src/data/.gitkeep

src/config/integrantes.json
src/config/integrantes.json
4 changes: 2 additions & 2 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}
"trailingComma": "all"
}
1 change: 0 additions & 1 deletion ambient.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
// declare module 'whatsapp-web.js';
declare module 'qrcode-terminal';
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,25 +46,26 @@
"dev": "ts-node-dev --respawn --transpile-only --ignore-watch node_modules --ignore-watch src/data -r dotenv/config src/index.ts"
},
"dependencies": {
"@types/node": "^15.0.1",
"axios": "^0.21.1",
"express": "^4.17.1",
"mobizon-node": "^0.3.1",
"node-base64-image": "^2.0.1",
"puppeteer": "^8.0.0",
"qr-image": "^3.2.0",
"qrcode-terminal": "^0.12.0",
"whatsapp-web.js": "^1.12.4"
"whatsapp-web.js": "^1.12.6"
},
"devDependencies": {
"@types/axios": "0.14.0",
"@types/puppeteer": "5.4.3",
"@typescript-eslint/eslint-plugin": "4.19.0",
"@typescript-eslint/parser": "4.19.0",
"@typescript-eslint/eslint-plugin": "4.22.1",
"@typescript-eslint/parser": "4.22.1",
"dotenv": "8.2.0",
"eslint": "7.24.0",
"eslint-config-prettier": "8.1.0",
"eslint": "7.25.0",
"eslint-config-prettier": "8.3.0",
"eslint-loader": "4.0.2",
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-react": "7.22.0",
"eslint-plugin-prettier": "3.4.0",
"prettier": "2.2.1",
"ts-node-dev": "1.1.6",
"typescript": "4.2.4"
Expand Down
4 changes: 2 additions & 2 deletions src/app/commands/CepCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ export default class EconomyCommand {

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

return msg.reply(
`*CEP*: ${data.cep}\n*Logradouro*: ${data.street}\n*Cidade*: ${data.city}\n*Bairro*: ${data.neighborhood}\n*UF*: ${data.state}`
`*CEP*: ${data.cep}\n*Logradouro*: ${data.street}\n*Cidade*: ${data.city}\n*Bairro*: ${data.neighborhood}\n*UF*: ${data.state}`,
);
} catch (error) {
return msg.reply(`CEP não localizado!`);
Expand Down
6 changes: 3 additions & 3 deletions src/app/commands/EconomyCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default class EconomyCommand {
chat.sendStateTyping();

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

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

return msg.reply(
`Cotação atual: 💎💰🤑💹 \n${type(data.USD)} ${type(data.EUR)} ${type(
data.BTC
)}`
data.BTC,
)}`,
);
}
}
6 changes: 3 additions & 3 deletions src/app/commands/ProfileCommand.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { client, MessageMedia } from '../../server';
import { client, MessageMedia } from '../../services/whatsapp';
import { encode } from 'node-base64-image';
import type { Message } from 'whatsapp-web.js';

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

msg.reply('Stalkeando este contato...');

if (!contact) return msg.reply('Contato não localizado.');

msg.reply('Stalkeando este contato...');

const url_i = await client.getProfilePicUrl(contact.number);

if (!url_i) return msg.reply('Imagem não foi localizada.');
Expand Down
6 changes: 3 additions & 3 deletions src/app/commands/QuoteCommand.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { client } from '../../server';
import { client } from '../../services/whatsapp';
import { company } from '../../config/integrantes.json';
import type { Message, GroupChat } from 'whatsapp-web.js';

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

Expand All @@ -28,7 +28,7 @@ export default class QuoteCommand {

for (const participant of chat.participants) {
const contact = await client.getContactById(
participant.id._serialized
participant.id._serialized,
);

mentions.push(contact);
Expand Down
35 changes: 35 additions & 0 deletions src/app/commands/SmsCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Message } from 'whatsapp-web.js';
import mobizon from '../../services/mobizon';

export default class ProfileCommand {
mention: string;
constructor(mention: string) {
this.mention = mention;
}

async execute(msg: Message) {
const chat = await msg.getChat();

const [contact] = await msg.getMentions();

chat.sendStateTyping();

if (!chat.isGroup) {
return msg.reply('Comando apenas para grupos!');
}

if (!contact) return msg.reply('Contato não localizado.');

const sendSms = await mobizon.sendSms({
recipient: contact.number,
from: '',
text: 'Sms enviado via BOT.',
});

if (sendSms.code !== 0) {
return msg.reply('Oops, houve um erro ao enviar SMS, tente novamente.');
}

return msg.reply('SMS enviado com sucesso!');
}
}
1 change: 1 addition & 0 deletions src/app/commands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default as EconomyCommand } from './EconomyCommand';
export { default as QuoteCommand } from './QuoteCommand';
export { default as CepCommand } from './CepCommand';
export { default as ProfileCommand } from './ProfileCommand';
export { default as SmsCommand } from './SmsCommand';
6 changes: 2 additions & 4 deletions src/app/interfaces/Cep.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
interface IResponse {
export interface IResponse {
data: IServerData;
}

interface IServerData {
export interface IServerData {
cep: string;
state: string;
city: string;
neighborhood: string;
street: string;
}

export { IResponse, IServerData };
4 changes: 1 addition & 3 deletions src/app/interfaces/Currency.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
interface ICurrency {
export interface ICurrency {
code: string;
codein: string;
name: string;
Expand All @@ -11,5 +11,3 @@ interface ICurrency {
timestamp: string;
create_date: string;
}

export { ICurrency };
4 changes: 3 additions & 1 deletion src/app/utils/CommandDispatcher.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Command from './Command';

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

async register(name: string, command: Command<any>) {
Expand All @@ -20,3 +20,5 @@ export default class CommandDispatcher {
}
}
}

export const commandDispatcher = new CommandDispatcher();
24 changes: 15 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { client } from './server';
import { client } from './services/whatsapp';
import {
EconomyCommand,
QuoteCommand,
CepCommand,
ProfileCommand,
SmsCommand,
} from './app/commands';
import CommandDispatcher from './app/utils/CommandDispatcher';
import { commandDispatcher } from './app/utils/CommandDispatcher';
import type { Message } from 'whatsapp-web.js';

const dispatcher = new CommandDispatcher();
client.on('message', (message: Message) => {
const economyCommand = new EconomyCommand();
const quoteCommand = new QuoteCommand();
const cepCommand = new CepCommand(message.body);
const profileCommand = new ProfileCommand(message.body);
const smsCommand = new SmsCommand(message.body);

client.on('message', async (message: Message) => {
dispatcher.register('cotacao', new EconomyCommand());
dispatcher.register('mencionar', new QuoteCommand());
dispatcher.register('cep', new CepCommand(message.body));
dispatcher.register('perfil', new ProfileCommand(message.body));
commandDispatcher.register('cotacao', economyCommand);
commandDispatcher.register('mencionar', quoteCommand);
commandDispatcher.register('cep', cepCommand);
commandDispatcher.register('perfil', profileCommand);
commandDispatcher.register('sms', smsCommand);

if (message.body.startsWith('!')) {
dispatcher.dispatch(message.body.slice(1), message);
commandDispatcher.dispatch(message.body.slice(1), message);
}
});
9 changes: 9 additions & 0 deletions src/services/mobizon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { mobizon } from 'mobizon-node';

mobizon.setConfig({
apiServer: process.env.MOBIZON_URL_SRV,
apiKey: process.env.MOBIZON_API_KEY,
format: 'json',
});

export default mobizon;
27 changes: 15 additions & 12 deletions src/server.ts → src/services/whatsapp.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import { Client, MessageMedia } from 'whatsapp-web.js';
import qrcode from 'qrcode-terminal';
import fs from 'fs';
import dir from 'path';
import { generate } from 'qrcode-terminal';
import { existsSync, writeFile, unlink } from 'fs';
import { resolve } from 'path';

interface INotification {
reply: (args: string) => void;
recipientIds: any[];
}

const sessionFile = dir.resolve('src', 'data', 'session.json');
const sessionFile = resolve('src', 'data', 'session.json');

const session = fs.existsSync(sessionFile) ? require(sessionFile) : null;
const session = existsSync(sessionFile) ? require(sessionFile) : null;

const client = new Client({
puppeteer: {
headless: true,
args: ['--no-sandbox'],
},
session,
});
} as any);

client.on('qr', (qr: string) => {
qrcode.generate(qr, { small: true });
generate(qr, { small: true });
});

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

const { pushname } = client.info;

client.sendMessage('[email protected]', `[${pushname}] - WhatsApp Online`);
client.sendMessage(
'[email protected]',
`[${pushname}] - WhatsApp Online\n\n[x] Star on project: https://github.com/caioagiani/whatsapp-bot`,
);
});

client.on('auth_failure', () => {
fs.unlink(sessionFile, () => {
unlink(sessionFile, () => {
console.log('Autenticação falhou, tente novamente.');
process.exit(1);
});
});

client.on('disconnected', () => {
fs.unlink(sessionFile, () =>
console.log('Sessão WhatsApp perdeu a conexão, tente novamente.')
unlink(sessionFile, () =>
console.log('Sessão WhatsApp perdeu a conexão, tente novamente.'),
);
});

Expand Down
Loading

0 comments on commit 00d4822

Please sign in to comment.