├── .dockerignore ├── .eslintrc.yml ├── .github ├── FUNDING.yml ├── dependabot.yml └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── HandleMsg.js ├── LICENSE ├── README.md ├── bin └── ffmpeg.exe ├── checkapinobg.js ├── data └── .none ├── ecosystem.config.cjs ├── index.js ├── lib ├── api.js ├── canvas.js ├── cekResi.js ├── index.js ├── kataKotor.js ├── list.js ├── location.js ├── menu.js ├── note.js ├── resep.js ├── schedule.js ├── scraper.js ├── sewa.js ├── shortener.js └── tebak.js ├── media └── tes.txt ├── package.json ├── patches └── fluent-ffmpeg+2.1.2.patch ├── restart.cmd ├── settings ├── api.json.example ├── katakasar.json ├── nsfwquery.json └── setting.json ├── src ├── font │ ├── ChakraPetch-Bold.ttf │ └── ChakraPetch-Regular.ttf ├── json │ ├── genshinbuild.json │ └── surah.json ├── mov │ └── wasted.mov ├── png │ ├── ava.png │ ├── bg.png │ ├── bgnight.png │ └── group.png ├── sfx │ ├── astaghfirullah.mp3 │ ├── balebale.mp3 │ ├── callambulance.mp3 │ ├── headshot.mp3 │ ├── kekw.mp3 │ ├── kuinginmarah.mp3 │ ├── kumenangis.mp3 │ ├── letsgo.mp3 │ ├── salam.mp3 │ ├── vacation.mp3 │ └── wtf.mp3 └── txt │ ├── dare.txt │ ├── skripsi.txt │ └── truth.txt └── utils ├── fetcher.js ├── index.js ├── options.js └── resizeImage.js /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | browser: true 3 | es2021: true 4 | extends: 'eslint:recommended' 5 | parserOptions: 6 | ecmaVersion: 12 7 | sourceType: module 8 | rules: {} 9 | globals: 10 | LOCAL_DATE_OPTIONS: readonly 11 | isLolApiActive: writable 12 | readMore: readonly 13 | color: readonly 14 | simi: writable 15 | q3: readonly 16 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['https://saweria.co/dngda', 'https://trakteer.id/dngda'] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "npm" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '27 1 * * 3' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 37 | # Learn more: 38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 39 | 40 | steps: 41 | - name: Checkout repository 42 | uses: actions/checkout@v2 43 | 44 | # Initializes the CodeQL tools for scanning. 45 | - name: Initialize CodeQL 46 | uses: github/codeql-action/init@v1 47 | with: 48 | languages: ${{ matrix.language }} 49 | # If you wish to specify custom queries, you can do so here or in a config file. 50 | # By default, queries listed here will override any specified in a config file. 51 | # Prefix the list here with "+" to use these queries and those in the config file. 52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 53 | 54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 55 | # If this step fails, then you should remove it and run the build manually (see below) 56 | - name: Autobuild 57 | uses: github/codeql-action/autobuild@v1 58 | 59 | # ℹ️ Command-line programs to run using the OS shell. 60 | # 📚 https://git.io/JvXDl 61 | 62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 63 | # and modify them (or add more) to build your code if your project 64 | # uses a compiled language 65 | 66 | #- run: | 67 | # make bootstrap 68 | # make release 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v1 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Dempedency directory 2 | node_modules 3 | # Dot files 4 | .idea 5 | .node-persist 6 | # Log files 7 | debug.log 8 | # Session files 9 | *.data.json 10 | # Workspace files 11 | *.code-workspace 12 | # Lock files 13 | package-lock.json 14 | # Data files 15 | data/* 16 | media/* 17 | logs/* 18 | # Api files 19 | settings/api.json 20 | 21 | # managed 22 | **.data.json 23 | **.node-persist** 24 | # end managed 25 | 26 | # temp 27 | test*.js 28 | tmp -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 |

5 | 6 |
7 | UNMAINTAINED - Multipurpose WhatsApp Bot using open-wa/wa-automate-nodejs library!


8 |

9 |

Made with ❤️ by

10 |

11 | 12 |

13 |

14 | 15 | 16 | 17 | 18 |
CodeFactor SonarCloud 19 |
20 | 21 |

22 | 23 | ## Getting Started 24 | 25 | This project require NodeJS v12 26 | 27 | ### Install 28 | Clone this project 29 | 30 | ```bash 31 | > git clone https://github.com/dngda/bot-whatsapp 32 | > cd bot-whatsapp 33 | ``` 34 | 35 | You need to install Libreoffice to use doctopdf command 36 | 37 | Install the dependencies: 38 | 39 | ```bash 40 | > npm install 41 | ``` 42 | Change all apiKey on [this section](https://github.com/dngda/bot-whatsapp/blob/main/settings/api.json.example) then *rename to api.json* 43 | 44 | ### Usage 45 | Run the Whatsapp bot 46 | 47 | ```bash 48 | > npm start 49 | ``` 50 | 51 | After running it you need to scan the QR 52 | 53 | ### Information 54 | - Change ownerNumber on [this section](https://github.com/dngda/bot-whatsapp/blob/main/settings/setting.json#L2) 55 | - Change groupLimit on [this section](https://github.com/dngda/bot-whatsapp/blob/main/settings/setting.json#L3) 56 | - Change memberLimit on [this section](https://github.com/dngda/bot-whatsapp/blob/main/settings/setting.json#L4) 57 | - Change prefix on [this section](https://github.com/dngda/bot-whatsapp/blob/main/settings/setting.json#L5) 58 | - Change menu on [this section](https://github.com/dngda/bot-whatsapp/blob/main/lib/menu.js#L34) 59 | - Add kata kasar on [this section](https://github.com/dngda/bot-whatsapp/blob/main/settings/katakasar.json) 60 | - Create Saweria account and get SaweriaOverlay on [this website](https://saweria.co) 61 | 62 | - Get Api NoBackground on [this website](https://www.remove.bg/) 63 | - Get Api LolHuman on [this website](https://lolhuman.herokuapp.com) 64 | - Get Api Fariaz on [this website](https://rest.farzain.com) 65 | - Get Api Genius on [this website](https://genius.com/developers) 66 | - Get Api Itech on [this website](https://api.i-tech.id) 67 | - Get Api Ocr on [this website](https://ocr.space/OCRAPI) 68 | --- 69 | 70 | ## Features 71 | Operasi kalkulator gunakan prefix (=) 72 | (cth: =10+2+4) 73 | 74 | Informasi 75 | - donate or donasi 76 | - ping or speed 77 | - owner 78 | - stat 79 | 80 | Converter 81 | - getimage or toimg 82 | -> Mengubah sticker menjadi gambar. 83 | - sticker or stiker or s 84 | -> Mengubah gambar/video menjadi sticker. 85 | - stickergiphy 86 | -> Mengubah url giphy menjadi sticker. 87 | - doctopdf or pdf 88 | -> Mengubah dokumen menjadi pdf. 89 | - qrcode or qr 90 | -> Membuat QRcode dari text. 91 | - tts or say 92 | -> Mengubah text menjadi suara Google. 93 | - shortlink 94 | -> Pemendek url menggunakan tinyurl. 95 | - translate 96 | -> Google translate text. 97 | - memefy 98 | -> Menambahkan text pada gambar. 99 | - tomp3 100 | -> Convert video ke audio. 101 | - hilih 102 | -> Mengubah text vokal menjadi huruf i. 103 | - ssweb 104 | -> Screenshot url website. 105 | - flip 106 | -> Balik gambar scr horizontal/vertikal. 107 | 108 | Downloader 109 | - tiktokmp3 110 | -> Download musik dari link tiktok. 111 | - tiktok 112 | -> Download tiktok tanpa watermark. 113 | - ytmp3 114 | -> Download mp3 dari link youtube. 115 | - ytmp4 116 | -> Download mp4 dari link youtube. 117 | 118 | Audio Converter 119 | -> Menambahkan efek suara pada audio. 120 | - nightcore 121 | - deepslow 122 | - samarkan 123 | - vibrato 124 | - earrape 125 | - reverse 126 | - robot 127 | - cf 128 | -> Custom complex filter (Expert user only) 129 | 130 | Islam 131 | - listsurah 132 | -> Daftar surah yang tersedia. 133 | - infosurah 134 | -> Info surah yang diinginkan. 135 | - jsholat 136 | -> Jadwal sholat sesuai daerah. 137 | - alaudio 138 | -> Audio dari surah yg diinginkan. 139 | - tafsir 140 | -> Tafsir surah yg diinginkan. 141 | - surah 142 | -> Menampilkan ayat dari surah yang diinginkan. 143 | 144 | Random 145 | -> Random berarti acak. 146 | - katabijak 147 | - skripsi 148 | - pantun 149 | - fakta 150 | - quote 151 | - anime 152 | - memes 153 | 154 | Search 155 | - pinterest or pin 156 | -> Search gambar dari pinterest. 157 | - gimages or gimg 158 | -> Search gambar dari Google. 159 | - whatanime 160 | -> Mencoba menebak anime dari gambar. 161 | - artinama 162 | -> Primbon arti nama, hanya hiburan. 163 | - sreddit 164 | -> Search gambar dari Subreddit. 165 | - lirik 166 | -> Search lirik lagu. 167 | - play 168 | -> Search lagu dari Youtube. 169 | - kbbi 170 | -> Search arti kata dalam KBBI. 171 | - yt 172 | -> Search Youtube. 173 | 174 | Hiburan 175 | - tebakgambar 176 | -> Main tebak gambar. 177 | - apakah 178 | -> Puja kerang ajaib!!! 179 | - sfx 180 | -> Mengirimkan audio yg tersedia. 181 | - ToD 182 | -> Group only. Truth or dare? 183 | 184 | Info 185 | - cekcovid 186 | -> Cek sebaran covid sesuai lokasi. 187 | - crjogja 188 | -> Radar cuaca lokasi Jogja. 189 | - cuaca 190 | -> Informasi cuaca sesuai daerah. 191 | - resi 192 | -> Cek resi barang sesuai kurir. 193 | 194 | Anti Toxic 195 | -> Group only. Anti kata kasar. 196 | - antikasar 197 | - klasemen 198 | - reset 199 | 200 | More Useful 201 | - tagall or alle 202 | -> Group only. Tag seluruh member. 203 | - join or sewa 204 | -> Sewa bot untuk join group kalau slot tersedia. 205 | - remind 206 | -> Kirimkan pesan ulang sesuai waktu yg ditentukan. 207 | - list 208 | -> Membuat list atau daftar yg disimpan di bot. 209 | - note 210 | -> Membuat note atau catatan yg disimpan di bot. 211 | - bye 212 | -> Group only. Keluarkan bot. 213 | - del 214 | -> Hapus pesan bot. 215 | 216 | 217 | --- 218 | 219 | ## Troubleshooting 220 | Make sure all the necessary dependencies are installed: https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md 221 | 222 | Fix Stuck on linux, install google chrome stable: 223 | ```bash 224 | > wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb 225 | > sudo apt install ./google-chrome-stable_current_amd64.deb 226 | ``` 227 | 228 | ## Thanks to 229 | - [Open-WA-Automate](https://github.com/open-wa/wa-automate-nodejs) 230 | - [YogaSakti](https://github.com/YogaSakti/imageToSticker) 231 | - [MhankBarBar](https://github.com/MhankBarBar/whatsapp-bot) 232 | - [ArugaZ](https://github.com/ArugaZ/whatsapp-bot) 233 | - [Aziz0404](https://github.com/nuraziz0404/botwa) 234 | - [Gimenz](https://github.com/Gimenz) 235 | -------------------------------------------------------------------------------- /bin/ffmpeg.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dngda/bot-whatsapp/b633a2b7dce42450fa39082c3ccd9e402c6083de/bin/ffmpeg.exe -------------------------------------------------------------------------------- /checkapinobg.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ Author: SeroBot Team 3 | * @ Create Time: 2021-02-14 20:26:02 4 | * @ Modified by: Danang Dwiyoga A (https://github.com/dngda/) 5 | * @ Modified time: 2021-06-21 00:42:43 6 | * @ Description: Cek api bos 7 | */ 8 | 9 | import request from 'request' 10 | import fs from 'fs' 11 | const { apiNoBg } = JSON.parse(fs.readFileSync('./settings/api.json')) 12 | 13 | apiNoBg.forEach(api => { 14 | request.get({ 15 | url: 'https://api.remove.bg/v1.0/account', 16 | headers: { 17 | 'X-Api-Key': api 18 | }, 19 | encoding: null 20 | }, function (_error, _response, body) { 21 | console.log(api, JSON.stringify(JSON.parse(body).data.attributes.api, null, 2)) 22 | }) 23 | }) -------------------------------------------------------------------------------- /data/.none: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /ecosystem.config.cjs: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line no-undef 2 | module.exports = { 3 | apps: [{ 4 | name: "Bot WhatsApp", 5 | script: "./index.js", 6 | args: ["--color"], 7 | error_file: './logs/pm2/err.log', 8 | combine_logs: true, 9 | cron_restart: '30 */12 * * *' 10 | }] 11 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ Author: SeroBot Team 3 | * @ Create Time: 2021-01-02 20:31:13 4 | * @ Modified by: Danang Dwiyoga A (https://github.com/dngda/) 5 | * @ Modified time: 2021-08-05 16:43:46 6 | * @ Description: 7 | */ 8 | 9 | import { createReadFileSync, initGlobalVariable } from './utils/index.js' 10 | import StealthPlugin from 'puppeteer-extra-plugin-stealth' 11 | import { create, Client, decryptMedia } from '@open-wa/wa-automate' 12 | import { canvas, schedule, sewa } from './lib/index.js' 13 | import chromeLauncher from 'chrome-launcher' 14 | import { scheduleJob } from 'node-schedule' 15 | import { HandleMsg } from './HandleMsg.js' 16 | import { spawn } from 'child_process' 17 | import options from './utils/options.js' 18 | import puppeteer from 'puppeteer-extra' 19 | import moment from 'moment-timezone' 20 | import PQueue from 'p-queue' 21 | import figlet from 'figlet' 22 | import fs from 'fs-extra' 23 | const path = chromeLauncher.Launcher.getInstallations()[0] 24 | const jobList = JSON.parse(createReadFileSync('./data/schedule.json')) 25 | const setting = JSON.parse(createReadFileSync('./settings/setting.json')) 26 | moment.tz.setDefault('Asia/Jakarta').locale('id') 27 | initGlobalVariable() 28 | 29 | let { 30 | ownerNumber, 31 | groupLimit, 32 | prefix 33 | } = setting 34 | 35 | const queue = new PQueue({ concurrency: 4, timeout: 3000, throwOnTimeout: true }) 36 | queue.on('next', () => { 37 | if (queue.size > 0 || queue.pending > 0) console.log(color('[==>>]', 'red'), `In-process: ${queue.pending} In-queue: ${queue.size}`) 38 | }) 39 | 40 | const start = async (client = new Client()) => { 41 | try { 42 | console.log(color(figlet.textSync('----------------', { horizontalLayout: 'default' }))) 43 | console.log(color(figlet.textSync(' SeroBot', { font: 'Ghost', horizontalLayout: 'default' }))) 44 | console.log(color(figlet.textSync('----------------', { horizontalLayout: 'default' }))) 45 | console.log(color('[DEV]'), color('Danang', 'yellow')) 46 | console.log(color('[~>>]'), color('BOT Started!', 'green')) 47 | console.log(color('[>..]'), color('Owner Commands: /menuowner', 'green')) 48 | client.sendText(ownerNumber, `✅ Bot Started!`) 49 | 50 | puppeteer.use(StealthPlugin()) 51 | const browser = await puppeteer.launch({ 52 | executablePath: path, 53 | headless: true, 54 | args: [ 55 | '--single-process', 56 | '--no-zygote', 57 | '--renderer-process-limit=1', 58 | '--no-first-run', 59 | '--no-sandbox', 60 | '--disable-setuid-sandbox', 61 | '--ignore-certificate-errors' 62 | ] 63 | }).catch(e => console.log(e)) 64 | 65 | // process unread message 66 | client.getAllUnreadMessages().then(async unreadMessages => { 67 | for (let message of unreadMessages) { 68 | if (!message.isGroupMsg) await queue.add(() => HandleMsg(message, browser, client)).catch(err => { 69 | console.log((err.name === 'TimeoutError') ? `${color('[==>>]', 'red')} Error task process timeout!` : err) 70 | if (queue.isPaused) queue.start() 71 | }) 72 | } 73 | }) 74 | 75 | // ketika seseorang mengirim pesan 76 | client.onMessage(async message => { 77 | client.setPresence(true) 78 | client.getAmountOfLoadedMessages() // menghapus pesan cache jika sudah 3000 pesan. 79 | .then((msg) => { 80 | if (msg >= 3000) { 81 | console.log('[CLNT]', color(`Loaded Message Reach ${msg}, cuting message cache...`, 'yellow')) 82 | client.cutMsgCache() 83 | } 84 | }) 85 | await queue.add(() => HandleMsg(message, browser, client)).catch(err => { 86 | console.log((err.name === 'TimeoutError') ? `${color('[==>>]', 'red')} Error task process timeout!` : err) 87 | if (queue.isPaused) queue.start() 88 | }) 89 | 90 | if (queue.isPaused) queue.start() 91 | }).catch(err => { 92 | console.log(err) 93 | }) 94 | 95 | // Load Scheduled Job 96 | // client, from, quotedId, content, date, isQuoted 97 | 98 | try { 99 | jobList.jobs.forEach(async (job) => { 100 | schedule.loadJob(client, job.from, job.quotedId, job.content, job.date, job.isQuoted).catch(e => console.log(e)) 101 | }) 102 | console.log(color('[LOGS]', 'grey'), `${jobList.jobs.length} ScheduledJobs Loaded`) 103 | 104 | // check sewa every 4 hours 105 | scheduleJob('0 */4 * * *', () => { 106 | console.log(color('[LOGS]', 'grey'), `Checking sewa expiring...`) 107 | sewa.checkExpireSewa(client).catch(e => console.log(e)) 108 | }) 109 | 110 | // Clear chat every day at 01:01 111 | scheduleJob('1 1 * * *', async () => { 112 | const chats = await client.getAllChats() 113 | client.sendText(ownerNumber, `Processed auto clear with ${chats.length} chat!`) 114 | let deleted = 0, cleared = 0 115 | for (let chat of chats) { 116 | if (!chat.isGroup && chat.id !== ownerNumber) { 117 | await client.deleteChat(chat.id) 118 | deleted += 1 119 | } 120 | if (chat.id === ownerNumber || chat.isGroup) { 121 | await client.clearChat(chat.id) 122 | cleared += 1 123 | } 124 | } 125 | client.sendText(ownerNumber, `Chat deleted : ${deleted}\nChat cleared : ${cleared}`) 126 | }) 127 | } catch (e) { 128 | console.log(e) 129 | } 130 | 131 | // Listen saweria 132 | // sewa.listenSaweria(client, browser).catch(e => console.log(e)) 133 | 134 | // ketika bot diinvite ke dalam group 135 | client.onAddedToGroup(async chat => { 136 | console.log(color('[==>>]', 'red'), `Someone is adding bot to group, lol~ groupId: ${chat.groupMetadata.id}`) 137 | client.getAllGroups().then((groups) => { 138 | // kondisi ketika batas group bot telah tercapai, ubah di file settings/setting.json 139 | console.log(color('[==>>]', 'red'), `Group total: ${groups.length}. groupLimit: ${groupLimit}`) 140 | if (groups.length > groupLimit) { 141 | console.log(color('[==>>]', 'red'), `So this is exceeding the group limit.`) 142 | client.sendText(chat.groupMetadata.id, 143 | `Mohon maaf, untuk mencegah overload, group pada bot dibatasi.\n` + 144 | `Total group: ${groups.length}/${groupLimit}\n` + 145 | `Chat /owner untuk sewa. harga 10k masa aktif 1 bulan.\n` //+ 146 | // `Mau sewa otomatis? Buka link berikut:\n` + 147 | // `Saweria: https://saweria.co/dngda \n` + 148 | // `*Masukkan hanya link group kalian dalam kolom "Pesan" di website saweria*` 149 | ) 150 | setTimeout(() => { 151 | client.leaveGroup(chat.groupMetadata.id) 152 | client.deleteChat(chat.groupMetadata.id) 153 | }, 3000) 154 | } else { 155 | client.simulateTyping(chat.groupMetadata.id, true).then(async () => { 156 | client.sendText(chat.groupMetadata.id, `Hai guys 👋 perkenalkan saya SeroBot. Untuk melihat perintah atau menu yang tersedia pada bot, kirim *${prefix}menu*. Tapi sebelumnya pahami dulu *${prefix}tnc*`) 157 | }) 158 | } 159 | }) 160 | }) 161 | 162 | client.onIncomingCall(async call => { 163 | // ketika seseorang menelpon nomor bot 164 | if (!call.isGroup || !call.participants.length > 1) { 165 | console.log(color('[==>>]', 'red'), `Someone is calling bot, lol~ id: ${call.peerJid}`) 166 | client.sendText(call.peerJid, `⛔ Maaf tidak bisa menerima panggilan.\n🤖 Ini robot, bukan manusia. Maaf bot akan block otomatis!\n💬 Chat https://wa.me/${ownerNumber.replace('@c.us', '')}?text=Halo!%20Tolong%20buka%20block%20saya%20pada%20Serobot`) 167 | setTimeout(() => { 168 | client.contactBlock(call.peerJid) 169 | }, 3000) 170 | } 171 | }) 172 | 173 | // Mempertahankan sesi agar tetap nyala 174 | client.onStateChanged((state) => { 175 | console.log(color('[~>>>]', 'red'), state) 176 | if (state === 'CONFLICT' || state === 'UNLAUNCHED') client.forceRefocus().then(() => queue.start()) 177 | }).catch((err) => { 178 | console.log(err) 179 | }) 180 | 181 | // ketika seseorang masuk/keluar dari group 182 | const host = await client.getHostNumber() + '@c.us' 183 | client.onGlobalParticipantsChanged(async event => { 184 | const welcome = JSON.parse(createReadFileSync('./data/welcome.json')) 185 | const isWelcome = welcome.includes(event.chat) 186 | const profile = await client.getProfilePicFromServer(event.who) 187 | const who = await client.getContact(event.who) 188 | const pushname = who.pushname || who.verifiedName || who.formattedName 189 | const chat = await client.getChatById(event.chat) 190 | const hasByProperty = Object.prototype.hasOwnProperty.call(event, 'by') 191 | // kondisi ketika seseorang diinvite/join group lewat link 192 | if (event.action === 'add' && event.who !== host && isWelcome && hasByProperty) { 193 | const welcomeData = await canvas.welcome( 194 | profile, 195 | chat.contact.profilePicThumbObj.eurl, 196 | pushname, 197 | chat.contact.name || chat.formattedTitle, 198 | chat.groupMetadata.participants.length).catch(err => console.log(color('[ERR>]', 'red'), err)) 199 | await client.sendImage(event.chat, welcomeData, 'welcome.png', `Halo semua!👋✨ Anggota kita nambah satu nih\n-> @${event.who.replace(/@c\.us/g, '')}`) 200 | 201 | } 202 | // kondisi ketika seseorang dikick/keluar dari group 203 | if (event.action === 'remove' && event.who !== host && isWelcome) { 204 | await client.sendText(event.chat, `⚙ Eh ada yang keluar ya? Dadahhh ${pushname} 👋✨`) 205 | } 206 | // Saat host keluar 207 | if (event.action === 'remove' && event.who == host) { 208 | const ngegas = JSON.parse(createReadFileSync('./data/ngegaskick.json')) 209 | const antiLinkGroup = JSON.parse(createReadFileSync('./data/antilinkgroup.json')) 210 | const antiLink = JSON.parse(createReadFileSync('./data/antilink.json')) 211 | let _id = event.chat 212 | let pos = ngegas.indexOf(_id) 213 | if (pos !== -1) { 214 | ngegas.splice(pos, 1) 215 | fs.writeFileSync('./data/ngegaskick.json', JSON.stringify(ngegas)) 216 | } 217 | let posi = welcome.indexOf(_id) 218 | if (posi !== -1) { 219 | welcome.splice(posi, 1) 220 | fs.writeFileSync('./data/welcome.json', JSON.stringify(welcome)) 221 | } 222 | let posa = antiLinkGroup.indexOf(_id) 223 | if (posa !== -1) { 224 | antiLinkGroup.splice(posa, 1) 225 | fs.writeFileSync('./data/antilinkgroup.json', JSON.stringify(antiLinkGroup)) 226 | } 227 | let posd = antiLink.indexOf(_id) 228 | if (posd !== -1) { 229 | antiLink.splice(posd, 1) 230 | fs.writeFileSync('./data/antilink.json', JSON.stringify(antiLink)) 231 | } 232 | } 233 | }).catch(e => { 234 | console.log(color('[ERR>]', 'red'), e) 235 | }) 236 | 237 | client.getPage().on('error', () => { 238 | client.sendText(ownerNumber, `⌛ Page Error! Server bot akan direstart!`) 239 | spawn('pm2 reload all') 240 | }) 241 | 242 | client.onMessageDeleted(async message => { 243 | try { 244 | const antiDelete = JSON.parse(createReadFileSync('./data/antidelete.json')) 245 | const isAntiDelete = antiDelete.includes(message.from) 246 | if (message.author != host && isAntiDelete) { 247 | await client.sendTextWithMentions(message.from, 248 | `‼️〘 ANTI DELETE 〙‼️\n` + 249 | `${q3}Who :${q3} @${message.author.replace('@c.us', '')}\n` + 250 | `${q3}When :${q3} ${moment(message.t * 1000).format('DD MMM HH:mm:ss')}\n` + 251 | `${q3}Type :${q3} ${message.type.replace(/^\w/, (c) => c.toUpperCase())}` + 252 | `${message.type == 'chat' ? `\n${q3}Content :${q3}\n\n${message.body}` : ``}` 253 | ) 254 | if (['image', 'video', 'ptt', 'audio', 'document'].includes(message.type)) { 255 | const mediaData = await decryptMedia(message) 256 | await client.sendFile(message.from, `data:${message.mimetype};base64,${mediaData.toString('base64')}`, '', message.caption) 257 | } 258 | if (message.type == 'sticker') { 259 | const mediaData = await decryptMedia(message) 260 | await client.sendImageAsSticker(message.from, mediaData, { pack: 'Anti delete by', author: 'SeroBot', keepScale: true }) 261 | } 262 | } 263 | } catch (err) { 264 | console.log(color('[ERR>]', 'red'), err) 265 | } 266 | }).catch(e => { 267 | console.log(color('[ERR>]', 'red'), e) 268 | }) 269 | 270 | } catch (err) { 271 | console.log(color('[ERR>]', 'red'), err) 272 | } 273 | } 274 | 275 | //create session 276 | create(options(true, start)) 277 | .then(client => start(client)) 278 | .catch(err => new Error(err)) 279 | -------------------------------------------------------------------------------- /lib/api.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @ Author: AirMineral Team 3 | * @ Create Time: 2021-05-31 22:33:11 4 | * @ Modified by: Danang Dwiyoga A (https://github.com/dngda/) 5 | * @ Modified time: 2021-07-19 11:01:14 6 | * @ Description: Tempat consume api 7 | */ 8 | 9 | import axios from 'axios' 10 | import { load } from 'cheerio' 11 | import fs from 'fs-extra' 12 | import lodash from 'lodash' 13 | import { Agent } from 'https' 14 | const { sample } = lodash 15 | import yts from 'yt-search' 16 | const agent = new Agent({ 17 | rejectUnauthorized: false 18 | }) 19 | const { get } = axios 20 | const { readFileSync } = fs 21 | 22 | // eslint-disable-next-line no-unused-vars 23 | const { apiFarzain, apiItech, apiZeks, apiLol, apiGenius, apiOcr } = JSON.parse(readFileSync('./settings/api.json')) 24 | 25 | const quote = () => new Promise((resolve, reject) => { 26 | let slash = sample(["quotes", "quotes2", "quotes3"]) 27 | get(`https://api.i-tech.id/tools/${slash}?key=${apiItech}`) 28 | .then((res) => { 29 | let text = '' 30 | let hasAuthorProperty = Object.prototype.hasOwnProperty.call(res.data, 'author') 31 | if (hasAuthorProperty) { 32 | text = `Author: ${res.data.author}\n\nQuote: ${res.data.result}` 33 | } else { 34 | text = res.data.result 35 | } 36 | resolve(text) 37 | }) 38 | .catch((err) => { 39 | reject(err) 40 | }) 41 | }) 42 | 43 | const ytsearch = (query) => new Promise((resolve, reject) => { 44 | yts(query) 45 | .then((res) => { 46 | let data = res.all.slice(0, 5) 47 | resolve(data) 48 | }).catch((err) => { 49 | reject(err) 50 | }) 51 | }) 52 | 53 | const artinama = (nama) => new Promise((resolve, reject) => { 54 | get(`https://api.zeks.xyz/api/artinama?apikey=${apiZeks}&nama=${encodeURIComponent(nama)}`) 55 | .then((res) => { 56 | resolve(res.data.result) 57 | }) 58 | .catch((err) => { 59 | reject(err) 60 | }) 61 | }) 62 | 63 | const lyric = (query) => new Promise((resolve, reject) => { 64 | get(`https://api.genius.com/search?q=${encodeURIComponent(query)}&access_token=${apiGenius}`) 65 | .then(res => { 66 | if (res.data.meta.status != 200) reject(res.data.meta.status + res.data.meta.message) 67 | const { hits } = res.data.response 68 | if (hits[0]) { 69 | get(hits[0].result.url).then(resu => { 70 | const $ = load(resu.data) 71 | let lyrics = $('div[class="lyrics"]').text().trim() 72 | if (!lyrics) { 73 | lyrics = '' 74 | $('div[class^="Lyrics__Container"]').each((i, elem) => { 75 | if ($(elem).text().length !== 0) { 76 | let snippet = $(elem).html() 77 | .replace(/
/g, '\n') 78 | .replace(/<(?!\s*br\s*\/?)[^>]+>/gi, '') 79 | lyrics += $('