Skip to content

Commit

Permalink
feat: dowload file
Browse files Browse the repository at this point in the history
  • Loading branch information
jonalan7 committed Jul 4, 2022
1 parent 1e38bec commit 85ca4ed
Show file tree
Hide file tree
Showing 15 changed files with 328 additions and 47 deletions.
64 changes: 47 additions & 17 deletions README.md
Expand Up @@ -74,6 +74,8 @@ If you want to work in free mode, using only the bot, dry the necessary informat
```javascript

const hydraBot = require('hydra-bot');
const mime = require('mime-types');
const fs = require('fs');

(async () => {

Expand Down Expand Up @@ -123,6 +125,16 @@ const hydraBot = require('hydra-bot');
if (!newMsg.result.isSentByMe) {
// message received!
console.log('NewMessageReceived: ', newMsg.result);
// dowload files
if (newMsg.result.isMedia === true || newMsg.result.isMMS === true) {
const buffer = await client.decryptFile(newMsg.result);
// At this point you can do whatever you want with the buffer
// Most likely you want to write it into a file
const fileName = `some-file-name.${mime.extension(newMsg.result.mimetype)}`;
fs.writeFile(fileName, buffer, (err) => {
console.log(err);
});
}
}
// when is it sent
if (!!newMsg.result.isSentByMe) {
Expand All @@ -142,25 +154,43 @@ const hydraBot = require('hydra-bot');
})();
```
## Downloading Files

Puppeteer takes care of the file downloading. The decryption is being done as
fast as possible (outruns native methods). Supports big files!

```javascript
import fs = require('fs');
import mime = require('mime-types');

ev.on('newMessage', async (newMsg) => {
if (message.isMedia === true || message.isMMS === true) {
const buffer = await client.decryptFile(message);
// At this point you can do whatever you want with the buffer
// Most likely you want to write it into a file
const fileName = `some-file-name.${mime.extension(message.mimetype)}`;
await fs.writeFile(fileName, buffer, (err) => {
...
const hydraBot = require('hydra-bot');
const fs = require('fs');
const mime = require('mime-types');

(async () => {
let client;
// start bot service
const ev = await hydraBot.initServer();
// return connection information
ev.on('connection', async (conn) => {
// Was connected to whatsapp chat
if (conn.connect) {
client = conn.client;
}
});
}
});
ev.on('newMessage', async (newMsg) => {
// when is received
if (!newMsg.result.isSentByMe) {
// message received!
console.log('NewMessageReceived: ', newMsg.result);
// dowload files
if (newMsg.result.isMedia === true || newMsg.result.isMMS === true) {
const buffer = await client.decryptFile(newMsg.result);
// At this point you can do whatever you want with the buffer
// Most likely you want to write it into a file
const fileName = `some-file-name.${mime.extension(newMsg.result.mimetype)}`;
fs.writeFile(fileName, buffer, (err) => {
console.log(err);
});
}
}
});
})();
```
## Optional create parameters (the bot in raw form, without using a Web Services)
```javascript
Expand Down Expand Up @@ -292,9 +322,9 @@ if you want to receive a callback on a specific url, pass the url parameter in t

### Methods GET

|Type| Route to browser | Description | Body |
|----| ---------------- | ----------------------------------------------------------------|--------------------------------------------------------------|
|GET | `/get_all_contacts` | Retrieve contacts | `EMPTY` |
| Type | Route to browser | Description | Body |
|------|---------------------|-------------------|---------|
| GET | `/get_all_contacts` | Retrieve contacts | `EMPTY` |

## Basic send options functions (more features still under development)
You must be logged in to use these functions!
Expand Down
38 changes: 38 additions & 0 deletions docs/getting-started/downloading_files.md
@@ -0,0 +1,38 @@
## Downloading Files
Puppeteer takes care of the file downloading. The decryption is being done as fast as possible (outruns native methods). Supports big files!

```javascript
const hydraBot = require('hydra-bot');
const fs = require('fs');
const mime = require('mime-types');

(async () => {
let client;
// start bot service
const ev = await hydraBot.initServer();
// return connection information
ev.on('connection', async (conn) => {
// Was connected to whatsapp chat
if (conn.connect) {
client = conn.client;
}
});
ev.on('newMessage', async (newMsg) => {
// when is received
if (!newMsg.result.isSentByMe) {
// message received!
console.log('NewMessageReceived: ', newMsg.result);
// dowload files
if (newMsg.result.isMedia === true || newMsg.result.isMMS === true) {
const buffer = await client.decryptFile(newMsg.result);
// At this point you can do whatever you want with the buffer
// Most likely you want to write it into a file
const fileName = `some-file-name.${mime.extension(newMsg.result.mimetype)}`;
fs.writeFile(fileName, buffer, (err) => {
console.log(err);
});
}
}
});
})();
```
19 changes: 16 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -56,6 +56,7 @@
"author": "Jonalan",
"license": "ISC",
"dependencies": {
"atob": "^2.1.2",
"axios": "^0.27.2",
"boxen": "^5.0.1",
"chalk": "^4.0.0",
Expand All @@ -64,6 +65,7 @@
"crypto-js": "^4.1.1",
"ejs": "^3.1.8",
"express": "^4.18.1",
"futoin-hkdf": "^1.5.1",
"knex": "^0.95.4",
"latest-version": "^5.1.0",
"mime-types": "^2.1.35",
Expand Down
26 changes: 26 additions & 0 deletions src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion src/package.json
@@ -1 +1,5 @@
{}
{
"devDependencies": {
"@types/atob": "^2.1.2"
}
}
8 changes: 6 additions & 2 deletions src/webpack/api/browser.ts
Expand Up @@ -18,14 +18,18 @@ export async function initBrowser(Browser: Browser): Promise<Page | boolean> {
waitUntil: 'domcontentloaded',
});
wpage.on('pageerror', ({ message }) => {
const erroLog = message.includes('RegisterEffect is not a function');
if (erroLog) {
const erroLogType1 = message.includes(
'RegisterEffect is not a function'
);
const erroLogType2 = message.includes('[Report Only]');
if (erroLogType1 || erroLogType2) {
wpage.evaluate(() => {
localStorage.clear();
window.location.reload();
});
}
});

Browser.userAgent();
return wpage;
} catch {
Expand Down
12 changes: 11 additions & 1 deletion src/webpack/api/init.ts
Expand Up @@ -4,7 +4,7 @@ import { Browser, Page } from 'puppeteer';
import { webPack } from '../inject/webpack';
import { CallbackOnStatus } from './layes/callback-on.layes';
import { onMode } from '../model/enum';
import { checkingCloses } from '../help';
import { checkingCloses, sleep } from '../help';
import { checkUpdates } from './check-up-to-date';

const ev = new CallbackOnStatus();
Expand Down Expand Up @@ -68,6 +68,16 @@ export async function initServer(

const page: boolean | Page = await initBrowser(wpage);
if (typeof page !== 'boolean') {
ev.statusFind = {
erro: false,
page: page,
statusFind: 'page',
onType: onMode.connection,
session: mergeOptionsDefault.session,
};

await sleep(100);

ev.statusFind = {
erro: false,
text: 'Website accessed successfully',
Expand Down
31 changes: 11 additions & 20 deletions src/webpack/api/layes/listener.layes.ts
@@ -1,11 +1,11 @@
import { EventEmitter } from 'events';
import { onMode } from '../../model/enum/';
import { Page, Browser } from 'puppeteer';
import { scraping } from './scraping.layes';
import { Whatsapp } from './whatsapp';
import { CreateOptions } from '../../model/interface';
import { sleep } from '../../help';

export class ListenerLayer extends scraping {
export class ListenerLayer extends Whatsapp {
constructor(
public page: Page,
public browser: Browser,
Expand Down Expand Up @@ -63,24 +63,15 @@ export class ListenerLayer extends scraping {

await this.page
.evaluate(() => {
if (!window.interfaceChange.exposed) {
window.API.interfaceChange((e: any) => {
window.interfaceChange(e);
});
window.interfaceChange.exposed = true;
}
if (!window.newMessage.exposed) {
window.API.newMessage((e: any) => {
window.newMessage(e);
});
window.newMessage.exposed = true;
}
if (!window.newOnAck.exposed) {
window.API.newOnAck((e: any) => {
window.newOnAck(e);
});
window.newOnAck.exposed = true;
}
window.API.interfaceChange((e: any) => {
window.interfaceChange(e);
});
window.API.newMessage((e: any) => {
window.newMessage(e);
});
window.API.newOnAck((e: any) => {
window.newOnAck(e);
});
})
.catch(() => {});
this.listener(onMode.interfaceChange);
Expand Down
54 changes: 54 additions & 0 deletions src/webpack/api/layes/whatsapp.ts
@@ -0,0 +1,54 @@
import { scraping } from './scraping.layes';
import { magix, makeOptions, puppeteerConfig, sleep } from '../../help';
import axios from 'axios';
import { Page, Browser } from 'puppeteer';
import { CreateOptions } from '../../model/interface';

export class Whatsapp extends scraping {
constructor(
public page: Page,
public browser: Browser,
public options: CreateOptions,
public ev: any
) {
super(page, browser, options, ev);
}

/**
* Decrypts message file
* @param message Message object
* @returns Decrypted file buffer (null otherwise)
*/
public async decryptFile(message:any) {
const options = makeOptions(puppeteerConfig.useragentOverride);
message.clientUrl =
message.clientUrl !== undefined
? message.clientUrl
: message.deprecatedMms3Url;

if (!message.clientUrl) {
throw new Error(
'message is missing critical data needed to download the file.'
);
}

let haventGottenImageYet: boolean = true,
res: any;
try {
while (haventGottenImageYet) {
res = await axios.get(message.clientUrl.trim(), options);
if (res.status == 200) {
haventGottenImageYet = false;
} else {
await sleep(2000);
}
}
} catch (error) {
console.error(error);
throw 'Error trying to download the file.';
}
const buff = Buffer.from(res.data, 'binary');
return magix(buff, message.mediaKey, message.type.toUpperCase(), message.size);
}

}

0 comments on commit 85ca4ed

Please sign in to comment.