├── .github ├── dependabot.yml └── workflows │ └── python-package.yml ├── .gitignore ├── LICENSE ├── README.md ├── docs └── README.md ├── examples ├── createGroupAndSendMessage.py ├── data │ └── rates.png ├── lastMessages.py ├── partherMethods │ ├── CreateInstance.py │ ├── DeleteInstanceAccount.py │ └── GetInstances.py ├── receiveNotification.py ├── sendPictureByLink.py ├── sendPictureByUpload.py ├── sendPoll.py ├── sendTextMessage.py ├── serviceMethods.py ├── setSettings.py ├── statusesMethods │ ├── deleteStatus.py │ ├── getStatuses.py │ ├── sendMediaStatus.py │ ├── sendTextStatus.py │ └── sendVoiceStatus.py └── uploadFileAndSendFileByUrl.py ├── requirements.txt ├── setup.py ├── tests ├── __init__.py └── test_methods.py └── whatsapp_api_client_python ├── API.py ├── __init__.py ├── response.py └── tools ├── __init__.py ├── account.py ├── device.py ├── groups.py ├── journals.py ├── marking.py ├── partner.py ├── queues.py ├── receiving.py ├── sending.py ├── serviceMethods.py ├── statuses.py └── webhooks.py /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "pip" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | allow: 8 | - dependency-type: "all" 9 | -------------------------------------------------------------------------------- /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | name: Python package 2 | 3 | on: 4 | push: 5 | branches: 6 | - "master" 7 | pull_request: 8 | branches: 9 | - "master" 10 | 11 | jobs: 12 | build: 13 | name: ${{ matrix.python-version }} 14 | runs-on: ubuntu-20.04 15 | strategy: 16 | matrix: 17 | python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11", "3.12" ] 18 | 19 | steps: 20 | - uses: actions/checkout@v3 21 | - name: Set up Python ${{ matrix.python-version }} 22 | uses: actions/setup-python@v4 23 | with: 24 | python-version: ${{ matrix.python-version }} 25 | - name: Install dependencies 26 | run: | 27 | python -m pip install --upgrade pip 28 | pip install ruff pytest 29 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 30 | - name: Lint with ruff 31 | run: | 32 | # stop the build if there are Python syntax errors or undefined names 33 | ruff check --output-format=github --select=E9,F63,F7,F82 --target-version=py37 . 34 | # default set of ruff rules with GitHub Annotations 35 | ruff check --output-format=github --target-version=py37 . 36 | - name: Test with pytest 37 | run: | 38 | pytest 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ 161 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-NoDerivatives 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | 56 | ======================================================================= 57 | 58 | Creative Commons Attribution-NoDerivatives 4.0 International Public 59 | License 60 | 61 | By exercising the Licensed Rights (defined below), You accept and agree 62 | to be bound by the terms and conditions of this Creative Commons 63 | Attribution-NoDerivatives 4.0 International Public License ("Public 64 | License"). To the extent this Public License may be interpreted as a 65 | contract, You are granted the Licensed Rights in consideration of Your 66 | acceptance of these terms and conditions, and the Licensor grants You 67 | such rights in consideration of benefits the Licensor receives from 68 | making the Licensed Material available under these terms and 69 | conditions. 70 | 71 | 72 | Section 1 -- Definitions. 73 | 74 | a. Adapted Material means material subject to Copyright and Similar 75 | Rights that is derived from or based upon the Licensed Material 76 | and in which the Licensed Material is translated, altered, 77 | arranged, transformed, or otherwise modified in a manner requiring 78 | permission under the Copyright and Similar Rights held by the 79 | Licensor. For purposes of this Public License, where the Licensed 80 | Material is a musical work, performance, or sound recording, 81 | Adapted Material is always produced where the Licensed Material is 82 | synched in timed relation with a moving image. 83 | 84 | b. Copyright and Similar Rights means copyright and/or similar rights 85 | closely related to copyright including, without limitation, 86 | performance, broadcast, sound recording, and Sui Generis Database 87 | Rights, without regard to how the rights are labeled or 88 | categorized. For purposes of this Public License, the rights 89 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 90 | Rights. 91 | 92 | c. Effective Technological Measures means those measures that, in the 93 | absence of proper authority, may not be circumvented under laws 94 | fulfilling obligations under Article 11 of the WIPO Copyright 95 | Treaty adopted on December 20, 1996, and/or similar international 96 | agreements. 97 | 98 | d. Exceptions and Limitations means fair use, fair dealing, and/or 99 | any other exception or limitation to Copyright and Similar Rights 100 | that applies to Your use of the Licensed Material. 101 | 102 | e. Licensed Material means the artistic or literary work, database, 103 | or other material to which the Licensor applied this Public 104 | License. 105 | 106 | f. Licensed Rights means the rights granted to You subject to the 107 | terms and conditions of this Public License, which are limited to 108 | all Copyright and Similar Rights that apply to Your use of the 109 | Licensed Material and that the Licensor has authority to license. 110 | 111 | g. Licensor means the individual(s) or entity(ies) granting rights 112 | under this Public License. 113 | 114 | h. Share means to provide material to the public by any means or 115 | process that requires permission under the Licensed Rights, such 116 | as reproduction, public display, public performance, distribution, 117 | dissemination, communication, or importation, and to make material 118 | available to the public including in ways that members of the 119 | public may access the material from a place and at a time 120 | individually chosen by them. 121 | 122 | i. Sui Generis Database Rights means rights other than copyright 123 | resulting from Directive 96/9/EC of the European Parliament and of 124 | the Council of 11 March 1996 on the legal protection of databases, 125 | as amended and/or succeeded, as well as other essentially 126 | equivalent rights anywhere in the world. 127 | 128 | j. You means the individual or entity exercising the Licensed Rights 129 | under this Public License. Your has a corresponding meaning. 130 | 131 | 132 | Section 2 -- Scope. 133 | 134 | a. License grant. 135 | 136 | 1. Subject to the terms and conditions of this Public License, 137 | the Licensor hereby grants You a worldwide, royalty-free, 138 | non-sublicensable, non-exclusive, irrevocable license to 139 | exercise the Licensed Rights in the Licensed Material to: 140 | 141 | a. reproduce and Share the Licensed Material, in whole or 142 | in part; and 143 | 144 | b. produce and reproduce, but not Share, Adapted Material. 145 | 146 | 2. Exceptions and Limitations. For the avoidance of doubt, where 147 | Exceptions and Limitations apply to Your use, this Public 148 | License does not apply, and You do not need to comply with 149 | its terms and conditions. 150 | 151 | 3. Term. The term of this Public License is specified in Section 152 | 6(a). 153 | 154 | 4. Media and formats; technical modifications allowed. The 155 | Licensor authorizes You to exercise the Licensed Rights in 156 | all media and formats whether now known or hereafter created, 157 | and to make technical modifications necessary to do so. The 158 | Licensor waives and/or agrees not to assert any right or 159 | authority to forbid You from making technical modifications 160 | necessary to exercise the Licensed Rights, including 161 | technical modifications necessary to circumvent Effective 162 | Technological Measures. For purposes of this Public License, 163 | simply making modifications authorized by this Section 2(a) 164 | (4) never produces Adapted Material. 165 | 166 | 5. Downstream recipients. 167 | 168 | a. Offer from the Licensor -- Licensed Material. Every 169 | recipient of the Licensed Material automatically 170 | receives an offer from the Licensor to exercise the 171 | Licensed Rights under the terms and conditions of this 172 | Public License. 173 | 174 | b. No downstream restrictions. You may not offer or impose 175 | any additional or different terms or conditions on, or 176 | apply any Effective Technological Measures to, the 177 | Licensed Material if doing so restricts exercise of the 178 | Licensed Rights by any recipient of the Licensed 179 | Material. 180 | 181 | 6. No endorsement. Nothing in this Public License constitutes or 182 | may be construed as permission to assert or imply that You 183 | are, or that Your use of the Licensed Material is, connected 184 | with, or sponsored, endorsed, or granted official status by, 185 | the Licensor or others designated to receive attribution as 186 | provided in Section 3(a)(1)(A)(i). 187 | 188 | b. Other rights. 189 | 190 | 1. Moral rights, such as the right of integrity, are not 191 | licensed under this Public License, nor are publicity, 192 | privacy, and/or other similar personality rights; however, to 193 | the extent possible, the Licensor waives and/or agrees not to 194 | assert any such rights held by the Licensor to the limited 195 | extent necessary to allow You to exercise the Licensed 196 | Rights, but not otherwise. 197 | 198 | 2. Patent and trademark rights are not licensed under this 199 | Public License. 200 | 201 | 3. To the extent possible, the Licensor waives any right to 202 | collect royalties from You for the exercise of the Licensed 203 | Rights, whether directly or through a collecting society 204 | under any voluntary or waivable statutory or compulsory 205 | licensing scheme. In all other cases the Licensor expressly 206 | reserves any right to collect such royalties. 207 | 208 | 209 | Section 3 -- License Conditions. 210 | 211 | Your exercise of the Licensed Rights is expressly made subject to the 212 | following conditions. 213 | 214 | a. Attribution. 215 | 216 | 1. If You Share the Licensed Material, You must: 217 | 218 | a. retain the following if it is supplied by the Licensor 219 | with the Licensed Material: 220 | 221 | i. identification of the creator(s) of the Licensed 222 | Material and any others designated to receive 223 | attribution, in any reasonable manner requested by 224 | the Licensor (including by pseudonym if 225 | designated); 226 | 227 | ii. a copyright notice; 228 | 229 | iii. a notice that refers to this Public License; 230 | 231 | iv. a notice that refers to the disclaimer of 232 | warranties; 233 | 234 | v. a URI or hyperlink to the Licensed Material to the 235 | extent reasonably practicable; 236 | 237 | b. indicate if You modified the Licensed Material and 238 | retain an indication of any previous modifications; and 239 | 240 | c. indicate the Licensed Material is licensed under this 241 | Public License, and include the text of, or the URI or 242 | hyperlink to, this Public License. 243 | 244 | For the avoidance of doubt, You do not have permission under 245 | this Public License to Share Adapted Material. 246 | 247 | 2. You may satisfy the conditions in Section 3(a)(1) in any 248 | reasonable manner based on the medium, means, and context in 249 | which You Share the Licensed Material. For example, it may be 250 | reasonable to satisfy the conditions by providing a URI or 251 | hyperlink to a resource that includes the required 252 | information. 253 | 254 | 3. If requested by the Licensor, You must remove any of the 255 | information required by Section 3(a)(1)(A) to the extent 256 | reasonably practicable. 257 | 258 | 259 | Section 4 -- Sui Generis Database Rights. 260 | 261 | Where the Licensed Rights include Sui Generis Database Rights that 262 | apply to Your use of the Licensed Material: 263 | 264 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 265 | to extract, reuse, reproduce, and Share all or a substantial 266 | portion of the contents of the database, provided You do not Share 267 | Adapted Material; 268 | 269 | b. if You include all or a substantial portion of the database 270 | contents in a database in which You have Sui Generis Database 271 | Rights, then the database in which You have Sui Generis Database 272 | Rights (but not its individual contents) is Adapted Material; and 273 | 274 | c. You must comply with the conditions in Section 3(a) if You Share 275 | all or a substantial portion of the contents of the database. 276 | 277 | For the avoidance of doubt, this Section 4 supplements and does not 278 | replace Your obligations under this Public License where the Licensed 279 | Rights include other Copyright and Similar Rights. 280 | 281 | 282 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 283 | 284 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 285 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 286 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 287 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 288 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 289 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 290 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 291 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 292 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 293 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 294 | 295 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 296 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 297 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 298 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 299 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 300 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 301 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 302 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 303 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 304 | 305 | c. The disclaimer of warranties and limitation of liability provided 306 | above shall be interpreted in a manner that, to the extent 307 | possible, most closely approximates an absolute disclaimer and 308 | waiver of all liability. 309 | 310 | 311 | Section 6 -- Term and Termination. 312 | 313 | a. This Public License applies for the term of the Copyright and 314 | Similar Rights licensed here. However, if You fail to comply with 315 | this Public License, then Your rights under this Public License 316 | terminate automatically. 317 | 318 | b. Where Your right to use the Licensed Material has terminated under 319 | Section 6(a), it reinstates: 320 | 321 | 1. automatically as of the date the violation is cured, provided 322 | it is cured within 30 days of Your discovery of the 323 | violation; or 324 | 325 | 2. upon express reinstatement by the Licensor. 326 | 327 | For the avoidance of doubt, this Section 6(b) does not affect any 328 | right the Licensor may have to seek remedies for Your violations 329 | of this Public License. 330 | 331 | c. For the avoidance of doubt, the Licensor may also offer the 332 | Licensed Material under separate terms or conditions or stop 333 | distributing the Licensed Material at any time; however, doing so 334 | will not terminate this Public License. 335 | 336 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 337 | License. 338 | 339 | 340 | Section 7 -- Other Terms and Conditions. 341 | 342 | a. The Licensor shall not be bound by any additional or different 343 | terms or conditions communicated by You unless expressly agreed. 344 | 345 | b. Any arrangements, understandings, or agreements regarding the 346 | Licensed Material not stated herein are separate from and 347 | independent of the terms and conditions of this Public License. 348 | 349 | 350 | Section 8 -- Interpretation. 351 | 352 | a. For the avoidance of doubt, this Public License does not, and 353 | shall not be interpreted to, reduce, limit, restrict, or impose 354 | conditions on any use of the Licensed Material that could lawfully 355 | be made without permission under this Public License. 356 | 357 | b. To the extent possible, if any provision of this Public License is 358 | deemed unenforceable, it shall be automatically reformed to the 359 | minimum extent necessary to make it enforceable. If the provision 360 | cannot be reformed, it shall be severed from this Public License 361 | without affecting the enforceability of the remaining terms and 362 | conditions. 363 | 364 | c. No term or condition of this Public License will be waived and no 365 | failure to comply consented to unless expressly agreed to by the 366 | Licensor. 367 | 368 | d. Nothing in this Public License constitutes or may be interpreted 369 | as a limitation upon, or waiver of, any privileges and immunities 370 | that apply to the Licensor or You, including from the legal 371 | processes of any jurisdiction or authority. 372 | 373 | ======================================================================= 374 | 375 | Creative Commons is not a party to its public 376 | licenses. Notwithstanding, Creative Commons may elect to apply one of 377 | its public licenses to material it publishes and in those instances 378 | will be considered the “Licensor.” The text of the Creative Commons 379 | public licenses is dedicated to the public domain under the CC0 Public 380 | Domain Dedication. Except for the limited purpose of indicating that 381 | material is shared under a Creative Commons public license or as 382 | otherwise permitted by the Creative Commons policies published at 383 | creativecommons.org/policies, Creative Commons does not authorize the 384 | use of the trademark "Creative Commons" or any other trademark or logo 385 | of Creative Commons without its prior written consent including, 386 | without limitation, in connection with any unauthorized modifications 387 | to any of its public licenses or any other arrangements, 388 | understandings, or agreements concerning use of licensed material. For 389 | the avoidance of doubt, this paragraph does not form part of the 390 | public licenses. 391 | 392 | Creative Commons may be contacted at creativecommons.org. 393 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # whatsapp-api-client-python 2 | 3 | ![](https://img.shields.io/badge/license-CC%20BY--ND%204.0-green) 4 | ![](https://img.shields.io/pypi/status/whatsapp-api-client-python) 5 | ![](https://img.shields.io/pypi/pyversions/whatsapp-api-client-python) 6 | ![](https://img.shields.io/github/actions/workflow/status/green-api/whatsapp-api-client-python/python-package.yml) 7 | ![](https://img.shields.io/pypi/dm/whatsapp-api-client-python) 8 | 9 | ## Support links 10 | 11 | [![Support](https://img.shields.io/badge/support@green--api.com-D14836?style=for-the-badge&logo=gmail&logoColor=white)](mailto:support@greenapi.com) 12 | [![Support](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/greenapi_support_eng_bot) 13 | [![Support](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://wa.me/77273122366) 14 | 15 | ## Guides & News 16 | 17 | [![Guides](https://img.shields.io/badge/YouTube-%23FF0000.svg?style=for-the-badge&logo=YouTube&logoColor=white)](https://www.youtube.com/@greenapi-en) 18 | [![News](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/green_api) 19 | [![News](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://whatsapp.com/channel/0029VaLj6J4LNSa2B5Jx6s3h) 20 | 21 | - [Документация на русском языке](https://github.com/green-api/whatsapp-api-client-python/blob/master/docs/README.md). 22 | 23 | whatsapp-api-client-python is a library for integration with WhatsApp messenger using the API 24 | service [green-api.com](https://green-api.com/en/). You should get a registration token and an account ID in 25 | your [personal cabinet](https://console.green-api.com/) to use the library. There is a free developer account tariff. 26 | 27 | ## API 28 | 29 | The documentation for the REST API can be found at the [link](https://green-api.com/en/docs/). The library is a wrapper 30 | for the REST API, so the documentation at the link above also applies. 31 | 32 | ## Authorization 33 | 34 | To send a message or perform other GREEN API methods, the WhatsApp account in the phone app must be authorized. To 35 | authorize the account, go to your [cabinet](https://console.green-api.com/) and scan the QR code using the WhatsApp app. 36 | 37 | ## Installation 38 | 39 | ```shell 40 | python -m pip install whatsapp-api-client-python 41 | ``` 42 | 43 | ## Import 44 | 45 | ``` 46 | from whatsapp_api_client_python import API 47 | ``` 48 | 49 | ## Examples 50 | 51 | ### How to initialize an object 52 | 53 | ``` 54 | greenAPI = API.GreenAPI( 55 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 56 | ) 57 | ``` 58 | 59 | ### Sending a text message to a WhatsApp number 60 | 61 | Link to example: [sendTextMessage.py]( 62 | https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendTextMessage.py 63 | ). 64 | 65 | ``` 66 | response = greenAPI.sending.sendMessage("11001234567@c.us", "Message text") 67 | 68 | print(response.data) 69 | ``` 70 | 71 | ### Sending an image via URL 72 | 73 | Link to example: [sendPictureByLink.py]( 74 | https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendPictureByLink.py 75 | ). 76 | 77 | ``` 78 | response = greenAPI.sending.sendFileByUrl( 79 | "11001234567@c.us", 80 | "https://download.samplelib.com/png/sample-clouds2-400x300.png", 81 | "sample-clouds2-400x300.png", 82 | "Sample PNG" 83 | ) 84 | 85 | print(response.data) 86 | ``` 87 | 88 | ### Sending an image by uploading from the disk 89 | 90 | Link to example: [sendPictureByUpload.py]( 91 | https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendPictureByUpload.py 92 | ). 93 | 94 | ``` 95 | response = greenAPI.sending.sendFileByUpload( 96 | "11001234567@c.us", 97 | "data/rates.png", 98 | "rates.png", 99 | "Available rates" 100 | ) 101 | 102 | print(response.data) 103 | ``` 104 | 105 | ### Group creation and sending a message to the group 106 | 107 | **Attention**. If one tries to create a group with a non-existent number, WhatsApp may block the sender's number. The 108 | number in the example is non-existent. 109 | 110 | Link to example: [createGroupAndSendMessage.py]( 111 | https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/createGroupAndSendMessage.py 112 | ). 113 | 114 | ``` 115 | create_group_response = greenAPI.groups.createGroup( 116 | "Group Name", ["11001234567@c.us"] 117 | ) 118 | if create_group_response.code == 200: 119 | send_message_response = greenAPI.sending.sendMessage( 120 | create_group_response.data["chatId"], "Message text" 121 | ) 122 | ``` 123 | 124 | ### Receive incoming messages by HTTP API 125 | 126 | Link to example: [receiveNotification.py]( 127 | https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/receiveNotification.py 128 | ). 129 | 130 | The general concept of receiving data in the GREEN API is described [here]( 131 | https://green-api.com/en/docs/api/receiving/ 132 | ). To start receiving notifications by the HTTP API you need to execute the library method: 133 | 134 | ``` 135 | greenAPI.webhooks.startReceivingNotifications(onEvent) 136 | ``` 137 | 138 | onEvent - your function which should contain parameters: 139 | 140 | | Parameter | Description | 141 | |-------------|----------------------------------| 142 | | typeWebhook | received notification type (str) | 143 | | body | notification body (dict) | 144 | 145 | Notification body types and formats can be found [here]( 146 | https://green-api.com/en/docs/api/receiving/notifications-format/ 147 | ). 148 | 149 | This method will be called when an incoming notification is received. Next, process notifications according to the 150 | business logic of your system. 151 | 152 | ### Sending a polling message 153 | 154 | Link to example: [sendPoll.py]( 155 | https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendPoll.py 156 | ). 157 | 158 | ``` 159 | response = greenAPI.sending.sendPoll( 160 | "11001234567@c.us", 161 | "Please choose a color:", 162 | [ 163 | {"optionName": "Red"}, 164 | {"optionName": "Green"}, 165 | {"optionName": "Blue"} 166 | ] 167 | ) 168 | 169 | print(response.data) 170 | ``` 171 | 172 | ### Sending a text status 173 | 174 | Link to example: [sendTextStatus.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/statusesMethods/sendTextStatus.py). 175 | 176 | ``` 177 | response = greenAPI.statuses.sendTextStatus( 178 | "I sent this status using Green Api Python SDK!", 179 | "#54c774", 180 | "NORICAN_REGULAR" 181 | ) 182 | 183 | print(response.data) 184 | ``` 185 | 186 | ## Examples list 187 | 188 | | Description | Module | 189 | |----------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| 190 | | Example of sending text | [sendTextMessage.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendTextMessage.py) | 191 | | Example of sending a picture by URL | [sendPictureByLink.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendPictureByLink.py) | 192 | | Example of sending a picture by uploading from the disk | [sendPictureByUpload.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendPictureByUpload.py) | 193 | | Example of a group creation and sending a message to the group | [createGroupAndSendMessage.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/createGroupAndSendMessage.py) | 194 | | Example of incoming webhooks receiving | [receiveNotification.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/receiveNotification.py) | 195 | | Example of sending a polling message | [sendPoll.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/sendPoll.py) | 196 | | Example of sending a text status | [sendTextStatus.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/statusesMethods/sendTextStatus.py) | 197 | | Example of creating instance | [CreateInstance.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/partherMethods/CreateInstance.py) | 198 | 199 | ## The full list of the library methods 200 | 201 | | API method | Description | Documentation link | 202 | |----------------------------------------|--------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------| 203 | | `account.getSettings` | The method is designed to get the current settings of the account | [GetSettings](https://green-api.com/en/docs/api/account/GetSettings/) | 204 | | `account.getWaSettings` | The method is designed to get information about the WhatsApp account | [GetWaSettings](https://green-api.com/en/docs/api/account/GetWaSettings/) | 205 | | `account.setSettings` | The method is designed to set the account settings | [SetSettings](https://green-api.com/en/docs/api/account/SetSettings/) | 206 | | `account.getStateInstance` | The method is designed to get the state of the account | [GetStateInstance](https://green-api.com/en/docs/api/account/GetStateInstance/) | 207 | | `account.getStatusInstance` | The method is designed to get the socket connection state of the account instance with WhatsApp | [GetStatusInstance](https://green-api.com/en/docs/api/account/GetStatusInstance/) | 208 | | `account.reboot` | The method is designed to restart the account | [Reboot](https://green-api.com/en/docs/api/account/Reboot/) | 209 | | `account.logout` | The method is designed to unlogin the account | [Logout](https://green-api.com/en/docs/api/account/Logout/) | 210 | | `account.qr` | The method is designed to get a QR code | [QR](https://green-api.com/en/docs/api/account/QR/) | 211 | | `account.setProfilePicture` | The method is designed to set the avatar of the account | [SetProfilePicture](https://green-api.com/en/docs/api/account/SetProfilePicture/) | 212 | | `account.getAuthorizationCode` | The method is designed to authorize an instance by phone number | [GetAuthorizationCode](https://green-api.com/en/docs/api/account/GetAuthorizationCode/) | 213 | | `device.getDeviceInfo` | The method is designed to get information about the device (phone) on which the WhatsApp Business application is running | [GetDeviceInfo](https://green-api.com/en/docs/api/phone/GetDeviceInfo/) | 214 | | `groups.createGroup` | The method is designed to create a group chat | [CreateGroup](https://green-api.com/en/docs/api/groups/CreateGroup/) | 215 | | `groups.updateGroupName` | The method changes the name of the group chat | [UpdateGroupName](https://green-api.com/en/docs/api/groups/UpdateGroupName/) | 216 | | `groups.getGroupData` | The method gets group chat data | [GetGroupData](https://green-api.com/en/docs/api/groups/GetGroupData/) | 217 | | `groups.addGroupParticipant` | The method adds a participant to the group chat | [AddGroupParticipant](https://green-api.com/en/docs/api/groups/AddGroupParticipant/) | 218 | | `groups.removeGroupParticipant` | The method removes the participant from the group chat | [RemoveGroupParticipant](https://green-api.com/en/docs/api/groups/RemoveGroupParticipant/) | 219 | | `groups.setGroupAdmin` | The method designates a member of a group chat as an administrator | [SetGroupAdmin](https://green-api.com/en/docs/api/groups/SetGroupAdmin/) | 220 | | `groups.removeAdmin` | The method deprives the participant of group chat administration rights | [RemoveAdmin](https://green-api.com/en/docs/api/groups/RemoveAdmin/) | 221 | | `groups.setGroupPicture` | The method sets the avatar of the group | [SetGroupPicture](https://green-api.com/en/docs/api/groups/SetGroupPicture/) | 222 | | `groups.leaveGroup` | The method logs the user of the current account out of the group chat | [LeaveGroup](https://green-api.com/en/docs/api/groups/LeaveGroup/) | 223 | | `statuses.sendTextStatus` | The method is aimed for sending a text status | [SendTextStatus](https://green-api.com/en/docs/api/statuses/SendTextStatus/) | 224 | | `statuses.sendVoiceStatus` | The method is aimed for sending a voice status | [SendVoiceStatus](https://green-api.com/en/docs/api/statuses/SendVoiceStatus/) | 225 | | `statuses.sendMediaStatus` | The method is aimed for sending a pictures or video status | [SendMediaStatus](https://green-api.com/en/docs/api/statuses/SendMediaStatus/) | 226 | | `statuses.deleteStatus` | The method is aimed for deleting a certain status | [DeleteStatus](https://green-api.com/en/docs/api/statuses/DeleteStatus/) | 227 | | `statuses.getStatusStatistic` | The method returns an array of recipients marked sent/delivered/read for a given status | [GetStatusStatistic](https://green-api.com/en/docs/api/statuses/GetStatusStatistic/) | 228 | | `statuses.getOutgoingStatuses` | The method returns the outgoing statuses of the account | [GetOutgoingStatuses](https://green-api.com/en/docs/api/statuses/GetOutgoingStatuses/) | 229 | | `statuses.getIncomingStatuses` | The method returns the incoming statuses of the account | [GetIncomingStatuses](https://green-api.com/en/docs/api/statuses/GetIncomingStatuses/) | 230 | | `journals.getChatHistory` | The method returns the chat message history | [GetChatHistory](https://green-api.com/en/docs/api/journals/GetChatHistory/) | 231 | | `journals.getMessage` | The method returns a chat message | [GetMessage](https://green-api.com/en/docs/api/journals/GetMessage/) | 232 | | `journals.lastIncomingMessages` | The method returns the most recent incoming messages of the account | [LastIncomingMessages](https://green-api.com/en/docs/api/journals/LastIncomingMessages/) | 233 | | `journals.lastOutgoingMessages` | The method returns the last sent messages of the account | [LastOutgoingMessages](https://green-api.com/en/docs/api/journals/LastOutgoingMessages/) | 234 | | `queues.showMessagesQueue` | The method is designed to get the list of messages that are in the queue to be sent | [ShowMessagesQueue](https://green-api.com/en/docs/api/queues/ShowMessagesQueue/) | 235 | | `queues.clearMessagesQueue` | The method is designed to clear the queue of messages to be sent | [ClearMessagesQueue](https://green-api.com/en/docs/api/queues/ClearMessagesQueue/) | 236 | | `marking.readChat` | The method is designed to mark chat messages as read | [ReadChat](https://green-api.com/en/docs/api/marks/ReadChat/) | 237 | | `receiving.receiveNotification` | The method is designed to receive a single incoming notification from the notification queue | [ReceiveNotification](https://green-api.com/en/docs/api/receiving/technology-http-api/ReceiveNotification/) | 238 | | `receiving.deleteNotification` | The method is designed to remove an incoming notification from the notification queue | [DeleteNotification](https://green-api.com/en/docs/api/receiving/technology-http-api/DeleteNotification/) | 239 | | `receiving.downloadFile` | The method is for downloading received and sent files | [DownloadFile](https://green-api.com/en/docs/api/receiving/files/DownloadFile/) | 240 | | `sending.sendMessage` | The method is designed to send a text message to a personal or group chat | [SendMessage](https://green-api.com/en/docs/api/sending/SendMessage/) | 241 | | `sending.sendButtons` | The method is designed to send a message with buttons to a personal or group chat | [SendButtons](https://green-api.com/en/docs/api/sending/SendButtons/) | 242 | | `sending.sendTemplateButtons` | The method is designed to send a message with interactive buttons from the list of templates in a personal or group chat | [SendTemplateButtons](https://green-api.com/en/docs/api/sending/SendTemplateButtons/) | 243 | | `sending.sendListMessage` | The method is designed to send a message with a selection button from a list of values to a personal or group chat | [SendListMessage](https://green-api.com/en/docs/api/sending/SendListMessage/) | 244 | | `sending.sendFileByUpload` | The method is designed to send a file loaded through a form (form-data) | [SendFileByUpload](https://green-api.com/en/docs/api/sending/SendFileByUpload/) | 245 | | `sending.sendFileByUrl` | The method is designed to send a file downloaded via a link | [SendFileByUrl](https://green-api.com/en/docs/api/sending/SendFileByUrl/) | 246 | | `sending.uploadFile` | The method is designed to upload a file to the cloud storage, which can be sent using the sendFileByUrl method | [UploadFile](https://green-api.com/en/docs/api/sending/UploadFile/) | 247 | | `sending.sendLocation` | The method is designed to send a geolocation message | [SendLocation](https://green-api.com/en/docs/api/sending/SendLocation/) | 248 | | `sending.sendContact` | The method is for sending a message with a contact | [SendContact](https://green-api.com/en/docs/api/sending/SendContact/) | 249 | | `sending.sendLink` | The method is designed to send a message with a link that will add an image preview, title and description | [SendLink](https://green-api.com/en/docs/api/sending/SendLink/) | 250 | | `sending.forwardMessages` | The method is designed for forwarding messages to a personal or group chat | [ForwardMessages](https://green-api.com/en/docs/api/sending/ForwardMessages/) | 251 | | `sending.sendPoll` | The method is designed for sending messages with a poll to a private or group chat | [SendPoll](https://green-api.com/en/docs/api/sending/SendPoll/) | 252 | | `serviceMethods.checkWhatsapp` | The method checks if there is a WhatsApp account on the phone number | [CheckWhatsapp](https://green-api.com/en/docs/api/service/CheckWhatsapp/) | 253 | | `serviceMethods.getAvatar` | The method returns the avatar of the correspondent or group chat | [GetAvatar](https://green-api.com/en/docs/api/service/GetAvatar/) | 254 | | `serviceMethods.getContacts` | The method is designed to get a list of contacts of the current account | [GetContacts](https://green-api.com/en/docs/api/service/GetContacts/) | 255 | | `serviceMethods.getContactInfo` | The method is designed to obtain information about the contact | [GetContactInfo](https://green-api.com/en/docs/api/service/GetContactInfo/) | 256 | | `serviceMethods.deleteMessage` | The method deletes the message from chat | [DeleteMessage](https://green-api.com/en/docs/api/service/deleteMessage/) | 257 | | `serviceMethods.editMessage` | The method edits the message in chat | [EditMessage](https://green-api.com/en/docs/api/service/editMessage/) | 258 | | `serviceMethods.archiveChat` | The method archives the chat | [ArchiveChat](https://green-api.com/en/docs/api/service/archiveChat/) | 259 | | `serviceMethods.unarchiveChat` | The method unarchives the chat | [UnarchiveChat](https://green-api.com/en/docs/api/service/unarchiveChat/) | 260 | | `serviceMethods.setDisappearingChat` | The method is designed to change the settings of disappearing messages in chats | [SetDisappearingChat](https://green-api.com/en/docs/api/service/SetDisappearingChat/) | 261 | | `webhooks.startReceivingNotifications` | The method is designed to start receiving new notifications | | 262 | | `webhooks.stopReceivingNotifications` | The method is designed to stop receiving new notifications | | 263 | | `partner.GetInstances` | The method is for getting all the account instances created by the partner. | [GetInstances](https://green-api.com/en/docs/partners/getInstances/) | 264 | | `partner.CreateInstance` | The method is for creating an instance. | [CreateInstance](https://green-api.com/en/docs/partners/createInstance/) | 265 | | `partner.DeleteInstanceAccount` | The method is for deleting an instance. | [DeleteInstanceAccount](https://green-api.com/en/docs/partners/deleteInstanceAccount/) | 266 | 267 | 268 | ## Service methods documentation 269 | 270 | [https://green-api.com/en/docs/api/](https://green-api.com/en/docs/api/). 271 | 272 | ## External products 273 | 274 | - [requests](https://requests.readthedocs.io/en/latest/) - for HTTP requests. 275 | 276 | ## License 277 | 278 | Licensed under [ 279 | Creative Commons Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) 280 | ](https://creativecommons.org/licenses/by-nd/4.0/) terms. 281 | Please see file [LICENSE](https://github.com/green-api/whatsapp-api-client-python/blob/master/LICENSE). 282 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # whatsapp-api-client-python 2 | 3 | ![](https://img.shields.io/badge/license-CC%20BY--ND%204.0-green) 4 | ![](https://img.shields.io/pypi/status/whatsapp-api-client-python) 5 | ![](https://img.shields.io/pypi/pyversions/whatsapp-api-client-python) 6 | ![](https://img.shields.io/github/actions/workflow/status/green-api/whatsapp-api-client-python/python-package.yml) 7 | ![](https://img.shields.io/pypi/dm/whatsapp-api-client-python) 8 | 9 | ## Поддержка 10 | 11 | [![Support](https://img.shields.io/badge/support@green--api.com-D14836?style=for-the-badge&logo=gmail&logoColor=white)](mailto:support@green-api.com) 12 | [![Support](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/greenapi_support_ru_bot) 13 | [![Support](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://wa.me/79993331223) 14 | 15 | ## Руководства и новости 16 | 17 | [![Guides](https://img.shields.io/badge/YouTube-%23FF0000.svg?style=for-the-badge&logo=YouTube&logoColor=white)](https://www.youtube.com/@green-api) 18 | [![News](https://img.shields.io/badge/Telegram-2CA5E0?style=for-the-badge&logo=telegram&logoColor=white)](https://t.me/green_api) 19 | [![News](https://img.shields.io/badge/WhatsApp-25D366?style=for-the-badge&logo=whatsapp&logoColor=white)](https://whatsapp.com/channel/0029VaHUM5TBA1f7cG29nO1C) 20 | 21 | whatsapp-api-client-python - библиотека для интеграции с мессенджером WhatsApp через API 22 | сервиса [green-api.com](https://green-api.com/). Чтобы воспользоваться библиотекой, нужно получить регистрационный токен 23 | и ID аккаунта в [личном кабинете](https://console.green-api.com/). Есть бесплатный тариф аккаунта разработчика. 24 | 25 | ## API 26 | 27 | Документация к REST API находится по [ссылке](https://green-api.com/docs/api/). Библиотека является обёрткой к REST API, 28 | поэтому документация по ссылке выше применима и к самой библиотеке. 29 | 30 | ## Авторизация 31 | 32 | Чтобы отправить сообщение или выполнить другие методы GREEN API, аккаунт WhatsApp в приложении телефона должен быть в 33 | авторизованном состоянии. Для авторизации аккаунта перейдите в [личный кабинет](https://console.green-api.com/) и 34 | сканируйте QR-код с использованием приложения WhatsApp. 35 | 36 | ## Установка 37 | 38 | ```shell 39 | python -m pip install whatsapp-api-client-python 40 | ``` 41 | 42 | ## Импорт 43 | 44 | ``` 45 | from whatsapp_api_client_python import API 46 | ``` 47 | 48 | ## Примеры 49 | 50 | ### Как инициализировать объект 51 | 52 | ``` 53 | greenAPI = API.GreenAPI( 54 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 55 | ) 56 | ``` 57 | 58 | ### Отправка текстового сообщения на номер WhatsApp 59 | 60 | Ссылка на пример: [sendTextMessage.py](../examples/sendTextMessage.py). 61 | 62 | ``` 63 | response = greenAPI.sending.sendMessage("11001234567@c.us", "Message text") 64 | 65 | print(response.data) 66 | ``` 67 | 68 | ### Отправка картинки по URL 69 | 70 | Ссылка на пример: [sendPictureByLink.py](../examples/sendPictureByLink.py). 71 | 72 | ``` 73 | response = greenAPI.sending.sendFileByUrl( 74 | "11001234567@c.us", 75 | "https://download.samplelib.com/png/sample-clouds2-400x300.png", 76 | "sample-clouds2-400x300.png", 77 | "Sample PNG" 78 | ) 79 | 80 | print(response.data) 81 | ``` 82 | 83 | ### Отправка картинки загрузкой с диска 84 | 85 | Ссылка на пример: [sendPictureByUpload.py](../examples/sendPictureByUpload.py). 86 | 87 | ``` 88 | response = greenAPI.sending.sendFileByUpload( 89 | "11001234567@c.us", 90 | "data/rates.png", 91 | "rates.png", 92 | "Available rates" 93 | ) 94 | 95 | print(response.data) 96 | ``` 97 | 98 | ### Создание группы и отправка сообщения в эту группу 99 | 100 | **Важно**. Если попытаться создать группу с несуществующим номером WhatsApp, то может заблокировать номер отправителя. 101 | Номер в примере не существует. 102 | 103 | Ссылка на пример: [createGroupAndSendMessage.py](../examples/createGroupAndSendMessage.py). 104 | 105 | ``` 106 | create_group_response = greenAPI.groups.createGroup( 107 | "Group Name", ["11001234567@c.us"] 108 | ) 109 | if create_group_response.code == 200: 110 | send_message_response = greenAPI.sending.sendMessage( 111 | create_group_response.data["chatId"], "Message text" 112 | ) 113 | ``` 114 | 115 | ### Получение входящих уведомлений через HTTP API 116 | 117 | Ссылка на пример: [receiveNotification.py](../examples/receiveNotification.py). 118 | 119 | Общая концепция получения данных в GREEN API описана [здесь](https://green-api.com/docs/api/receiving/). Для старта 120 | получения уведомлений через HTTP API требуется выполнить метод библиотеки: 121 | 122 | ``` 123 | greenAPI.webhooks.startReceivingNotifications(onEvent) 124 | ``` 125 | 126 | onEvent - ваша функция, которая должен содержать параметры: 127 | 128 | | Параметр | Описание | 129 | |-------------|-----------------------------------| 130 | | typeWebhook | тип полученного уведомления (str) | 131 | | body | тело уведомления (dict) | 132 | 133 | Типы и форматы тел уведомлений находятся [здесь](https://green-api.com/docs/api/receiving/notifications-format/). 134 | 135 | Эта функция будет вызываться при получении входящего уведомления. Далее обрабатываете уведомления согласно бизнес-логике 136 | вашей системы. 137 | 138 | ### Отправка сообщения с опросом 139 | 140 | Ссылка на пример: [sendPoll.py](../examples/sendPoll.py). 141 | 142 | ``` 143 | response = greenAPI.sending.sendPoll( 144 | "11001234567@c.us", 145 | "Please choose a color:", 146 | [ 147 | {"optionName": "Red"}, 148 | {"optionName": "Green"}, 149 | {"optionName": "Blue"} 150 | ] 151 | ) 152 | 153 | print(response.data) 154 | ``` 155 | 156 | ## Отправка текстового статуса 157 | 158 | Ссылка на пример: [sendPoll.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/statusesMethods/sendTextStatus.py). 159 | 160 | ``` 161 | response = greenAPI.statuses.sendTextStatus( 162 | "I sent this status using Green Api Python SDK!", 163 | "#54c774", 164 | "NORICAN_REGULAR" 165 | ) 166 | 167 | print(response.data) 168 | ``` 169 | 170 | ## Список примеров 171 | 172 | | Описание | Модуль | 173 | |------------------------------------------------------|--------------------------------------------------------------------------| 174 | | Пример отправки текста | [sendTextMessage.py](../examples/sendTextMessage.py) | 175 | | Пример отправки картинки по URL | [sendPictureByLink.py](../examples/sendPictureByLink.py) | 176 | | Пример отправки картинки загрузкой с диска | [sendPictureByUpload.py](../examples/sendPictureByUpload.py) | 177 | | Пример создание группы и отправка сообщения в группу | [createGroupAndSendMessage.py](../examples/createGroupAndSendMessage.py) | 178 | | Пример получения входящих уведомлений | [receiveNotification.py](../examples/receiveNotification.py) | 179 | | Пример отправки сообщения с опросом | [sendPoll.py](../examples/sendPoll.py) | 180 | | Пример отправки текстового статуса | [sendTextStatus.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/statusesMethods/sendTextStatus.py) | 181 | | Пример создания инстанса | [CreateInstance.py](https://github.com/green-api/whatsapp-api-client-python/blob/master/examples/partherMethods/CreateInstance.py) | 182 | ## Полный список методов библиотеки 183 | 184 | | Метод API | Описание | Documentation link | 185 | |----------------------------------------|---------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------| 186 | | `account.getSettings` | Метод предназначен для получения текущих настроек аккаунта | [GetSettings](https://green-api.com/docs/api/account/GetSettings/) | 187 | | `account.getWaSettings` | Метод предназначен для получения информации о аккаунте WhatsApp | [GetWaSettings](https://green-api.com/docs/api/account/GetWaSettings/) | 188 | | `account.setSettings` | Метод предназначен для установки настроек аккаунта | [SetSettings](https://green-api.com/docs/api/account/SetSettings/) | 189 | | `account.getStateInstance` | Метод предназначен для получения состояния аккаунта | [GetStateInstance](https://green-api.com/docs/api/account/GetStateInstance/) | 190 | | `account.getStatusInstance` | Метод предназначен для получения состояния сокета соединения инстанса аккаунта с WhatsApp | [GetStatusInstance](https://green-api.com/docs/api/account/GetStatusInstance/) | 191 | | `account.reboot` | Метод предназначен для перезапуска аккаунта | [Reboot](https://green-api.com/docs/api/account/Reboot/) | 192 | | `account.logout` | Метод предназначен для разлогинивания аккаунта | [Logout](https://green-api.com/docs/api/account/Logout/) | 193 | | `account.qr` | Метод предназначен для получения QR-кода | [QR](https://green-api.com/docs/api/account/QR/) | 194 | | `account.setProfilePicture` | Метод предназначен для установки аватара аккаунта | [SetProfilePicture](https://green-api.com/docs/api/account/SetProfilePicture/) | 195 | | `account.getAuthorizationCode` | Метод предназначен для авторизации инстанса по номеру телефона | [GetAuthorizationCode](https://green-api.com/docs/api/account/GetAuthorizationCode/) | 196 | | `device.getDeviceInfo` | Метод предназначен для получения информации об устройстве (телефоне), на котором запущено приложение WhatsApp Business | [GetDeviceInfo](https://green-api.com/docs/api/phone/GetDeviceInfo/) | 197 | | `groups.createGroup` | Метод предназначен для создания группового чата | [CreateGroup](https://green-api.com/docs/api/groups/CreateGroup/) | 198 | | `groups.updateGroupName` | Метод изменяет наименование группового чата | [UpdateGroupName](https://green-api.com/docs/api/groups/UpdateGroupName/) | 199 | | `groups.getGroupData` | Метод получает данные группового чата | [GetGroupData](https://green-api.com/docs/api/groups/GetGroupData/) | 200 | | `groups.addGroupParticipant` | Метод добавляет участника в групповой чат | [AddGroupParticipant](https://green-api.com/docs/api/groups/AddGroupParticipant/) | 201 | | `groups.removeGroupParticipant` | Метод удаляет участника из группового чата | [RemoveGroupParticipant](https://green-api.com/docs/api/groups/RemoveGroupParticipant/) | 202 | | `groups.setGroupAdmin` | Метод назначает участника группового чата администратором | [SetGroupAdmin](https://green-api.com/docs/api/groups/SetGroupAdmin/) | 203 | | `groups.removeAdmin` | Метод лишает участника прав администрирования группового чата | [RemoveAdmin](https://green-api.com/docs/api/groups/RemoveAdmin/) | 204 | | `groups.setGroupPicture` | Метод устанавливает аватар группы | [SetGroupPicture](https://green-api.com/docs/api/groups/SetGroupPicture/) | 205 | | `groups.leaveGroup` | Метод производит выход пользователя текущего аккаунта из группового чата | [LeaveGroup](https://green-api.com/docs/api/groups/LeaveGroup/) | 206 | | `journals.getChatHistory` | Метод возвращает историю сообщений чата | [GetChatHistory](https://green-api.com/docs/api/journals/GetChatHistory/) | 207 | | `journals.getMessage` | Метод возвращает сообщение чата | [GetMessage](https://green-api.com/docs/api/journals/GetMessage/) | 208 | | `journals.lastIncomingMessages` | Метод возвращает крайние входящие сообщения аккаунта | [LastIncomingMessages](https://green-api.com/docs/api/journals/LastIncomingMessages/) | 209 | | `journals.lastOutgoingMessages` | Метод возвращает крайние отправленные сообщения аккаунта | [LastOutgoingMessages](https://green-api.com/docs/api/journals/LastOutgoingMessages/) | 210 | | `queues.showMessagesQueue` | Метод предназначен для получения списка сообщений, находящихся в очереди на отправку | [ShowMessagesQueue](https://green-api.com/docs/api/queues/ShowMessagesQueue/) | 211 | | `queues.clearMessagesQueue` | Метод предназначен для очистки очереди сообщений на отправку | [ClearMessagesQueue](https://green-api.com/docs/api/queues/ClearMessagesQueue/) | 212 | | `marking.readChat` | Метод предназначен для отметки сообщений в чате прочитанными | [ReadChat](https://green-api.com/docs/api/marks/ReadChat/) | 213 | | `receiving.receiveNotification` | Метод предназначен для получения одного входящего уведомления из очереди уведомлений | [ReceiveNotification](https://green-api.com/docs/api/receiving/technology-http-api/ReceiveNotification/) | 214 | | `receiving.deleteNotification` | Метод предназначен для удаления входящего уведомления из очереди уведомлений | [DeleteNotification](https://green-api.com/docs/api/receiving/technology-http-api/DeleteNotification/) | 215 | | `receiving.downloadFile` | Метод предназначен для скачивания принятых и отправленных файлов | [DownloadFile](https://green-api.com/docs/api/receiving/files/DownloadFile/) | 216 | | `sending.sendMessage` | Метод предназначен для отправки текстового сообщения в личный или групповой чат | [SendMessage](https://green-api.com/docs/api/sending/SendMessage/) | 217 | | `sending.sendButtons` | Метод предназначен для отправки сообщения с кнопками в личный или групповой чат | [SendButtons](https://green-api.com/docs/api/sending/SendButtons/) | 218 | | `sending.sendTemplateButtons` | Метод предназначен для отправки сообщения с интерактивными кнопками из перечня шаблонов в личный или групповой чат | [SendTemplateButtons](https://green-api.com/docs/api/sending/SendTemplateButtons/) | 219 | | `sending.sendListMessage` | Метод предназначен для отправки сообщения с кнопкой выбора из списка значений в личный или групповой чат | [SendListMessage](https://green-api.com/docs/api/sending/SendListMessage/) | 220 | | `sending.sendFileByUpload` | Метод предназначен для отправки файла, загружаемого через форму (form-data) | [SendFileByUpload](https://green-api.com/docs/api/sending/SendFileByUpload/) | 221 | | `sending.sendFileByUrl` | Метод предназначен для отправки файла, загружаемого по ссылке | [SendFileByUrl](https://green-api.com/docs/api/sending/SendFileByUrl/) | 222 | | `sending.uploadFile` | Метод предназначен для загрузки файла в облачное хранилище, который можно отправить методом sendFileByUrl | [UploadFile](https://green-api.com/docs/api/sending/UploadFile/) | 223 | | `sending.sendLocation` | Метод предназначен для отправки сообщения геолокации | [SendLocation](https://green-api.com/docs/api/sending/SendLocation/) | 224 | | `sending.sendContact` | Метод предназначен для отправки сообщения с контактом | [SendContact](https://green-api.com/docs/api/sending/SendContact/) | 225 | | `sending.sendLink` | Метод предназначен для отправки сообщения со ссылкой, по которой будут добавлены превью изображения, заголовок и описание | [SendLink](https://green-api.com/docs/api/sending/SendLink/) | 226 | | `sending.forwardMessages` | Метод предназначен для пересылки сообщений в личный или групповой чат | [ForwardMessages](https://green-api.com/docs/api/sending/ForwardMessages/) | 227 | | `sending.sendPoll` | Метод предназначен для отправки сообщения с опросом в личный или групповой чат | [SendPoll](https://green-api.com/docs/api/sending/SendPoll/) | 228 | | `serviceMethods.checkWhatsapp` | Метод проверяет наличие аккаунта WhatsApp на номере телефона | [CheckWhatsapp](https://green-api.com/docs/api/service/CheckWhatsapp/) | 229 | | `serviceMethods.getAvatar` | Метод возвращает аватар корреспондента или группового чата | [GetAvatar](https://green-api.com/docs/api/service/GetAvatar/) | 230 | | `serviceMethods.getContacts` | Метод предназначен для получения списка контактов текущего аккаунта | [GetContacts](https://green-api.com/docs/api/service/GetContacts/) | 231 | | `serviceMethods.getContactInfo` | Метод предназначен для получения информации о контакте | [GetContactInfo](https://green-api.com/docs/api/service/GetContactInfo/) | 232 | | `serviceMethods.deleteMessage` | Метод удаляет сообщение из чата | [DeleteMessage](https://green-api.com/docs/api/service/deleteMessage/) | 233 | | `serviceMethods.editMessage` | Метод изменяет сообщение в чате | [EditMessage](https://green-api.com/docs/api/service/editMessage/) | 234 | | `serviceMethods.archiveChat` | Метод архивирует чат | [ArchiveChat](https://green-api.com/docs/api/service/archiveChat/) | 235 | | `serviceMethods.unarchiveChat` | Метод разархивирует чат | [UnarchiveChat](https://green-api.com/docs/api/service/unarchiveChat/) | 236 | | `serviceMethods.setDisappearingChat` | Метод предназначен для изменения настроек исчезающих сообщений в чатах | [SetDisappearingChat](https://green-api.com/docs/api/service/SetDisappearingChat/) | 237 | | `webhooks.startReceivingNotifications` | Метод предназначен для старта получения новых уведомлений | | 238 | | `webhooks.stopReceivingNotifications` | Метод предназначен для остановки получения новых уведомлений | | 239 | | `partner.GetInstances` | Метод предназначен для получения всех инстансов аккаунтов созданных партнёром. | [GetInstances](https://green-api.com/docs/partners/getInstances/) | 240 | | `partner.CreateInstance` | Метод предназначен для создания инстанса от имени партнёра. | [CreateInstance](https://green-api.com/docs/partners/createInstance/) | 241 | | `partner.DeleteInstanceAccount` | Метод предназначен для удаления инстанса аккаунта партнёра. | [DeleteInstanceAccount](https://green-api.com/docs/partners/deleteInstanceAccount/) | 242 | 243 | ## Документация по методам сервиса 244 | 245 | [https://green-api.com/docs/api/](https://green-api.com/docs/api/). 246 | 247 | ## Сторонние продукты 248 | 249 | - [requests](https://requests.readthedocs.io/en/latest/) - для HTTP запросов. 250 | 251 | ## Лицензия 252 | 253 | Лицензировано на условиях [ 254 | Creative Commons Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) 255 | ](https://creativecommons.org/licenses/by-nd/4.0/). 256 | [LICENSE](../LICENSE). 257 | -------------------------------------------------------------------------------- /examples/createGroupAndSendMessage.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | create_group_response = greenAPI.groups.createGroup( 10 | "Group Name", ["11001234567@c.us", "11001234567@c.us"] 11 | ) 12 | if create_group_response.code == 200: 13 | print(create_group_response.data) 14 | 15 | send_message_response = greenAPI.sending.sendMessage( 16 | create_group_response.data["chatId"], "Message text" 17 | ) 18 | if send_message_response.code == 200: 19 | print(send_message_response.data) 20 | else: 21 | print(send_message_response.error) 22 | else: 23 | print(create_group_response.error) 24 | 25 | 26 | if __name__ == '__main__': 27 | main() 28 | -------------------------------------------------------------------------------- /examples/data/rates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/green-api/whatsapp-api-client-python/731b8f60328bc34601716bc393f0e9a4dd5d80ff/examples/data/rates.png -------------------------------------------------------------------------------- /examples/lastMessages.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | # If no argument, the messages for 24 hours are returned. 10 | 11 | print("Incoming messages in the last 72 hours:") 12 | response = greenAPI.journals.lastIncomingMessages(4320) 13 | print(response.data) 14 | 15 | print("Outgoing messages in the last 72 hours:") 16 | response = greenAPI.journals.lastOutgoingMessages(4320) 17 | print(response.data) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() -------------------------------------------------------------------------------- /examples/partherMethods/CreateInstance.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenApiPartner( 4 | "gac.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst" 5 | ) 6 | 7 | 8 | def main(): 9 | settings = { 10 | "name": "Created by Python SDK", 11 | "webhookUrl": "https://webhook.url", 12 | "webhookUrlToken": "auth_token", 13 | "delaySendMessagesMilliseconds": 5000, 14 | "markIncomingMessagesReaded": "yes", 15 | "markIncomingMessagesReadedOnReply": "yes", 16 | "outgoingWebhook": "yes", 17 | "outgoingMessageWebhook": "yes", 18 | "outgoingAPIMessageWebhook": "yes", 19 | "stateWebhook": "yes", 20 | "incomingWebhook": "yes", 21 | "deviceWebhook": "yes", 22 | "keepOnlineStatus": "yes", 23 | "pollMessageWebhook": "yes", 24 | "incomingBlockWebhook": "yes", 25 | "incomingCallWebhook": "yes", 26 | "editedMessageWebhook": "yes", 27 | "deletedMessageWebhook": "yes" 28 | } 29 | 30 | response = greenAPI.partner.createInstance(settings) 31 | print(response.data) 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /examples/partherMethods/DeleteInstanceAccount.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenApiPartner( 4 | "gac.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.partner.deleteInstanceAccount(1103123456) 10 | print(response.data) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | -------------------------------------------------------------------------------- /examples/partherMethods/GetInstances.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenApiPartner( 4 | "gac.abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.partner.getInstances() 10 | print(response.data) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | -------------------------------------------------------------------------------- /examples/receiveNotification.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from json import dumps 3 | 4 | from whatsapp_api_client_python import API 5 | 6 | greenAPI = API.GreenAPI( 7 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 8 | ) 9 | 10 | 11 | def main(): 12 | greenAPI.webhooks.startReceivingNotifications(handler) 13 | 14 | 15 | def handler(type_webhook: str, body: dict) -> None: 16 | if type_webhook == "incomingMessageReceived": 17 | incoming_message_received(body) 18 | elif type_webhook == "outgoingMessageReceived": 19 | outgoing_message_received(body) 20 | elif type_webhook == "outgoingAPIMessageReceived": 21 | outgoing_api_message_received(body) 22 | elif type_webhook == "outgoingMessageStatus": 23 | outgoing_message_status(body) 24 | elif type_webhook == "stateInstanceChanged": 25 | state_instance_changed(body) 26 | elif type_webhook == "deviceInfo": 27 | device_info(body) 28 | elif type_webhook == "incomingCall": 29 | incoming_call(body) 30 | elif type_webhook == "statusInstanceChanged": 31 | status_instance_changed(body) 32 | 33 | 34 | def get_notification_time(timestamp: int) -> str: 35 | return str(datetime.fromtimestamp(timestamp)) 36 | 37 | 38 | def incoming_message_received(body: dict) -> None: 39 | timestamp = body["timestamp"] 40 | time = get_notification_time(timestamp) 41 | 42 | data = dumps(body, ensure_ascii=False, indent=4) 43 | 44 | print(f"New incoming message at {time} with data: {data}", end="\n\n") 45 | 46 | 47 | def outgoing_message_received(body: dict) -> None: 48 | timestamp = body["timestamp"] 49 | time = get_notification_time(timestamp) 50 | 51 | data = dumps(body, ensure_ascii=False, indent=4) 52 | 53 | print(f"New outgoing message at {time} with data: {data}", end="\n\n") 54 | 55 | 56 | def outgoing_api_message_received(body: dict) -> None: 57 | timestamp = body["timestamp"] 58 | time = get_notification_time(timestamp) 59 | 60 | data = dumps(body, ensure_ascii=False, indent=4) 61 | 62 | print(f"New outgoing API message at {time} with data: {data}", end="\n\n") 63 | 64 | 65 | def outgoing_message_status(body: dict) -> None: 66 | timestamp = body["timestamp"] 67 | time = get_notification_time(timestamp) 68 | 69 | data = dumps(body, ensure_ascii=False, indent=4) 70 | 71 | response = ( 72 | f"Status of sent message has been updated at {time} with data: {data}" 73 | ) 74 | print(response, end="\n\n") 75 | 76 | 77 | def state_instance_changed(body: dict) -> None: 78 | timestamp = body["timestamp"] 79 | time = get_notification_time(timestamp) 80 | 81 | data = dumps(body, ensure_ascii=False, indent=4) 82 | 83 | print(f"Current instance state at {time} with data: {data}", end="\n\n") 84 | 85 | 86 | def device_info(body: dict) -> None: 87 | timestamp = body["timestamp"] 88 | time = get_notification_time(timestamp) 89 | 90 | data = dumps(body, ensure_ascii=False, indent=4) 91 | 92 | response = ( 93 | f"Current device information at {time} with data: {data}" 94 | ) 95 | print(response, end="\n\n") 96 | 97 | 98 | def incoming_call(body: dict) -> None: 99 | timestamp = body["timestamp"] 100 | time = get_notification_time(timestamp) 101 | 102 | data = dumps(body, ensure_ascii=False, indent=4) 103 | 104 | print(f"New incoming call at {time} with data: {data}", end="\n\n") 105 | 106 | 107 | def status_instance_changed(body: dict) -> None: 108 | timestamp = body["timestamp"] 109 | time = get_notification_time(timestamp) 110 | 111 | data = dumps(body, ensure_ascii=False, indent=4) 112 | 113 | print(f"Current instance status at {time} with data: {data}", end="\n\n") 114 | 115 | 116 | if __name__ == '__main__': 117 | main() 118 | -------------------------------------------------------------------------------- /examples/sendPictureByLink.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.sending.sendFileByUrl( 10 | "11001234567@c.us", 11 | "https://download.samplelib.com/png/sample-clouds2-400x300.png", 12 | "sample-clouds2-400x300.png", 13 | "Sample PNG" 14 | ) 15 | 16 | print(response.data) 17 | 18 | 19 | if __name__ == '__main__': 20 | main() 21 | -------------------------------------------------------------------------------- /examples/sendPictureByUpload.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.sending.sendFileByUpload( 10 | "11001234567@c.us", 11 | "data/rates.png", 12 | "rates.png", 13 | "Available rates" 14 | ) 15 | 16 | print(response.data) 17 | 18 | 19 | if __name__ == '__main__': 20 | main() 21 | -------------------------------------------------------------------------------- /examples/sendPoll.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.sending.sendPoll( 10 | "11001234567@c.us", 11 | "Please choose a color:", 12 | [ 13 | {"optionName": "Red"}, 14 | {"optionName": "Green"}, 15 | {"optionName": "Blue"} 16 | ] 17 | ) 18 | 19 | print(response.data) 20 | 21 | 22 | if __name__ == '__main__': 23 | main() 24 | -------------------------------------------------------------------------------- /examples/sendTextMessage.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.sending.sendMessage("11001234567@c.us", "Message text") 10 | 11 | print(response.data) 12 | 13 | 14 | if __name__ == '__main__': 15 | main() 16 | -------------------------------------------------------------------------------- /examples/serviceMethods.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | # DeleteMessage for sender 10 | response = greenAPI.serviceMethods.deleteMessage("11001234567@c.us", "BAE52A7F04F452F9", True) 11 | 12 | # DeleteMessage for all (default) 13 | response = greenAPI.serviceMethods.deleteMessage("11001234567@c.us", "BAE5558FFC7565C2") 14 | 15 | # EditMessage 16 | response = greenAPI.serviceMethods.editMessage("11001234567@c.us", "BAE5F793F61411D0", "New text") 17 | print(response.data) # new idMessage 18 | 19 | if __name__ == '__main__': 20 | main() 21 | -------------------------------------------------------------------------------- /examples/setSettings.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | settings = { 10 | "webhookUrl": "https://webhook.url", 11 | "webhookUrlToken": "auth_token", 12 | "delaySendMessagesMilliseconds": 5000, 13 | "markIncomingMessagesReaded": "yes", 14 | "markIncomingMessagesReadedOnReply": "yes", 15 | "outgoingWebhook": "yes", 16 | "outgoingMessageWebhook": "yes", 17 | "outgoingAPIMessageWebhook": "yes", 18 | "stateWebhook": "yes", 19 | "incomingWebhook": "yes", 20 | "deviceWebhook": "yes", 21 | "keepOnlineStatus": "yes", 22 | "pollMessageWebhook": "yes", 23 | "incomingBlockWebhook": "yes", 24 | "incomingCallWebhook": "yes", 25 | "editedMessageWebhook": "yes", 26 | "deletedMessageWebhook": "yes" 27 | } 28 | 29 | response = greenAPI.account.setSettings(settings) 30 | print(response.data) 31 | 32 | 33 | if __name__ == '__main__': 34 | main() 35 | -------------------------------------------------------------------------------- /examples/statusesMethods/deleteStatus.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.statuses.deleteStatus('BAE54F518532FCB1') 10 | print(response.data) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | -------------------------------------------------------------------------------- /examples/statusesMethods/getStatuses.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.statuses.getIncomingStatuses(1400) # minutes argument is Optional 10 | print(response.data) 11 | 12 | response = greenAPI.statuses.getOutgoingStatuses(1400) # minutes argument is Optional 13 | print(response.data) 14 | 15 | response = greenAPI.statuses.getStatusStatistic('BAE54F518532FCB1') 16 | print(response.data) 17 | 18 | if __name__ == '__main__': 19 | main() 20 | -------------------------------------------------------------------------------- /examples/statusesMethods/sendMediaStatus.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.statuses.sendMediaStatus( 10 | "https://example.com/file.mp4", 11 | "test.mp4" 12 | "#54c774") 13 | 14 | print(response.data) 15 | 16 | if __name__ == '__main__': 17 | main() 18 | -------------------------------------------------------------------------------- /examples/statusesMethods/sendTextStatus.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.statuses.sendTextStatus( 10 | "I sent this status using Green Api Python SDK!", 11 | "#54c774", 12 | "NORICAN_REGULAR") 13 | 14 | print(response.data) 15 | 16 | if __name__ == '__main__': 17 | main() 18 | -------------------------------------------------------------------------------- /examples/statusesMethods/sendVoiceStatus.py: -------------------------------------------------------------------------------- 1 | from whatsapp_api_client_python import API 2 | 3 | greenAPI = API.GreenAPI( 4 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 5 | ) 6 | 7 | 8 | def main(): 9 | response = greenAPI.statuses.sendVoiceStatus( 10 | "https://example.com/file.mp3", 11 | "test.mp3" 12 | "#54c774") 13 | 14 | print(response.data) 15 | 16 | if __name__ == '__main__': 17 | main() 18 | -------------------------------------------------------------------------------- /examples/uploadFileAndSendFileByUrl.py: -------------------------------------------------------------------------------- 1 | from os.path import basename 2 | from urllib.parse import urlparse 3 | 4 | from whatsapp_api_client_python import API 5 | 6 | greenAPI = API.GreenAPI( 7 | "1101000001", "d75b3a66374942c5b3c019c698abc2067e151558acbd412345" 8 | ) 9 | 10 | 11 | def main(): 12 | upload_file_response = greenAPI.sending.uploadFile( 13 | "data/rates.png" 14 | ) 15 | if upload_file_response.code == 200: 16 | print(upload_file_response.data) 17 | 18 | url_file = upload_file_response.data["urlFile"] 19 | 20 | url = urlparse(url_file) 21 | file_name = basename(url.path) 22 | 23 | send_file_by_url_response = greenAPI.sending.sendFileByUrl( 24 | "11001234567@c.us", url_file, file_name 25 | ) 26 | if send_file_by_url_response.code == 200: 27 | print(send_file_by_url_response.data) 28 | else: 29 | print(send_file_by_url_response.error) 30 | else: 31 | print(upload_file_response.error) 32 | 33 | 34 | if __name__ == '__main__': 35 | main() 36 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | requests>=2.31.0 2 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import find_packages, setup 2 | 3 | with open("README.md", encoding="UTF-8") as file: 4 | long_description = file.read() 5 | 6 | setup( 7 | name="whatsapp-api-client-python", 8 | version="0.0.50", 9 | description=( 10 | "This library helps you easily create" 11 | " a Python application with WhatsApp API." 12 | ), 13 | long_description=long_description, 14 | long_description_content_type="text/markdown", 15 | author="GREEN API", 16 | author_email="support@green-api.com", 17 | url="https://github.com/green-api/whatsapp-api-client-python", 18 | packages=find_packages(exclude=["tests"]), 19 | classifiers=[ 20 | "Development Status :: 5 - Production/Stable", 21 | "Environment :: Console", 22 | "Intended Audience :: Developers", 23 | "License :: Other/Proprietary License", 24 | "Natural Language :: English", 25 | "Natural Language :: Russian", 26 | "Operating System :: OS Independent", 27 | "Programming Language :: Python", 28 | "Programming Language :: Python :: 3", 29 | "Programming Language :: Python :: 3 :: Only", 30 | "Programming Language :: Python :: 3.7", 31 | "Programming Language :: Python :: 3.8", 32 | "Programming Language :: Python :: 3.9", 33 | "Programming Language :: Python :: 3.10", 34 | "Programming Language :: Python :: 3.11", 35 | "Programming Language :: Python :: 3.12", 36 | "Topic :: Communications", 37 | "Topic :: Communications :: Chat", 38 | "Topic :: Software Development", 39 | "Topic :: Software Development :: Libraries", 40 | "Topic :: Software Development :: Libraries :: Application Frameworks" 41 | ], 42 | license=( 43 | "Creative Commons Attribution-NoDerivatives 4.0 International" 44 | " (CC BY-ND 4.0)" 45 | ), 46 | install_requires=["requests>=2.31.0"], 47 | python_requires=">=3.7" 48 | ) 49 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/green-api/whatsapp-api-client-python/731b8f60328bc34601716bc393f0e9a4dd5d80ff/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_methods.py: -------------------------------------------------------------------------------- 1 | import typing 2 | import unittest 3 | from unittest.mock import Mock, patch 4 | 5 | from whatsapp_api_client_python.API import GreenAPI 6 | from whatsapp_api_client_python.response import Response 7 | 8 | api = GreenAPI("", "") 9 | 10 | path = "examples/data/rates.png" 11 | 12 | 13 | class MethodsTestCase(unittest.TestCase): 14 | @patch("whatsapp_api_client_python.API.Session.request") 15 | def test_methods(self, mock_request): 16 | mock_request.return_value = Mock( 17 | status_code=200, text="""{"example": {"key": "value"}}""" 18 | ) 19 | 20 | methods = [ 21 | *self.account_methods, 22 | *self.device_methods, 23 | *self.group_methods, 24 | *self.status_methods, 25 | *self.log_methods, 26 | *self.queue_methods, 27 | *self.read_mark_methods, 28 | *self.receiving_methods, 29 | *self.sending_methods, 30 | *self.service_methods 31 | ] 32 | 33 | for response in methods: 34 | self.assertEqual(response.code, 200) 35 | self.assertEqual(response.data, {"example": {"key": "value"}}) 36 | 37 | self.assertEqual(mock_request.call_count, len(methods)) 38 | 39 | @property 40 | def account_methods(self) -> typing.List[Response]: 41 | return [ 42 | api.account.getSettings(), 43 | api.account.getWaSettings(), 44 | api.account.setSettings({}), 45 | api.account.getStateInstance(), 46 | api.account.getStatusInstance(), 47 | api.account.reboot(), 48 | api.account.logout(), 49 | api.account.qr(), 50 | api.account.setProfilePicture(path), 51 | api.account.getAuthorizationCode(0) 52 | ] 53 | 54 | @property 55 | def device_methods(self) -> typing.List[Response]: 56 | return [api.device.getDeviceInfo()] 57 | 58 | @property 59 | def group_methods(self) -> typing.List[Response]: 60 | return [ 61 | api.groups.createGroup("", []), 62 | api.groups.updateGroupName("", ""), 63 | api.groups.getGroupData(""), 64 | api.groups.addGroupParticipant("", ""), 65 | api.groups.removeGroupParticipant("", ""), 66 | api.groups.setGroupAdmin("", ""), 67 | api.groups.removeAdmin("", ""), 68 | api.groups.setGroupPicture("", path), 69 | api.groups.leaveGroup("") 70 | ] 71 | 72 | @property 73 | def status_methods(self) -> typing.List[Response]: 74 | return [ 75 | api.statuses.sendTextStatus(""), 76 | api.statuses.sendVoiceStatus("", ""), 77 | api.statuses.sendMediaStatus("", ""), 78 | api.statuses.deleteStatus(""), 79 | api.statuses.getStatusStatistic(""), 80 | api.statuses.getIncomingStatuses(), 81 | api.statuses.getOutgoingStatuses() 82 | ] 83 | 84 | @property 85 | def log_methods(self) -> typing.List[Response]: 86 | return [ 87 | api.journals.getChatHistory(""), 88 | api.journals.getMessage("", ""), 89 | api.journals.lastIncomingMessages(), 90 | api.journals.lastOutgoingMessages() 91 | ] 92 | 93 | @property 94 | def queue_methods(self) -> typing.List[Response]: 95 | return [ 96 | api.queues.showMessagesQueue(), 97 | api.queues.clearMessagesQueue() 98 | ] 99 | 100 | @property 101 | def read_mark_methods(self) -> typing.List[Response]: 102 | return [api.marking.readChat("")] 103 | 104 | @property 105 | def receiving_methods(self) -> typing.List[Response]: 106 | return [ 107 | api.receiving.receiveNotification(), 108 | api.receiving.deleteNotification(0), 109 | api.receiving.downloadFile("", "") 110 | ] 111 | 112 | @property 113 | def sending_methods(self) -> typing.List[Response]: 114 | return [ 115 | api.sending.sendMessage("", ""), 116 | api.sending.sendButtons("", "", []), 117 | api.sending.sendTemplateButtons("", "", []), 118 | api.sending.sendListMessage("", "", "", []), 119 | api.sending.sendFileByUpload("", path), 120 | api.sending.sendFileByUrl("", "", ""), 121 | api.sending.uploadFile(path), 122 | api.sending.sendLocation("", 0.0, 0.0), 123 | api.sending.sendContact("", {}), 124 | api.sending.sendLink("", ""), 125 | api.sending.forwardMessages("", "", []), 126 | api.sending.sendPoll("", "", []) 127 | ] 128 | 129 | @property 130 | def service_methods(self) -> typing.List[Response]: 131 | return [ 132 | api.serviceMethods.checkWhatsapp(0), 133 | api.serviceMethods.getAvatar(""), 134 | api.serviceMethods.getContacts(), 135 | api.serviceMethods.getContactInfo(""), 136 | api.serviceMethods.deleteMessage("", ""), 137 | api.serviceMethods.archiveChat(""), 138 | api.serviceMethods.unarchiveChat(""), 139 | api.serviceMethods.setDisappearingChat("") 140 | ] 141 | 142 | 143 | if __name__ == '__main__': 144 | unittest.main() 145 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/API.py: -------------------------------------------------------------------------------- 1 | import json 2 | import logging 3 | from typing import Any, NoReturn, Optional 4 | 5 | from requests import Response, Session 6 | from requests.adapters import HTTPAdapter, Retry 7 | 8 | from .response import Response as GreenAPIResponse 9 | from .tools import ( 10 | account, 11 | device, 12 | groups, 13 | journals, 14 | marking, 15 | queues, 16 | receiving, 17 | sending, 18 | serviceMethods, 19 | webhooks, 20 | partner, 21 | statuses 22 | ) 23 | 24 | 25 | class GreenApi: 26 | host: str 27 | media: str 28 | idInstance: str 29 | apiTokenInstance: str 30 | 31 | def __init__( 32 | self, 33 | idInstance: str, 34 | apiTokenInstance: str, 35 | debug_mode: bool = False, 36 | raise_errors: bool = False, 37 | host: str = "https://api.green-api.com", 38 | media: str = "https://media.green-api.com", 39 | host_timeout: float = 180, # sec per retry 40 | media_timeout: float = 10800, # sec per retry 41 | ): 42 | self.host = host 43 | self.media = media 44 | self.debug_mode = debug_mode 45 | self.raise_errors = raise_errors 46 | 47 | # Change default values in init() if required 48 | self.host_timeout = host_timeout 49 | self.media_timeout = media_timeout 50 | 51 | self.idInstance = idInstance 52 | self.apiTokenInstance = apiTokenInstance 53 | 54 | self.session = Session() 55 | self.__prepare_session() 56 | 57 | self.account = account.Account(self) 58 | self.device = device.Device(self) 59 | self.groups = groups.Groups(self) 60 | self.journals = journals.Journals(self) 61 | self.marking = marking.Marking(self) 62 | self.queues = queues.Queues(self) 63 | self.receiving = receiving.Receiving(self) 64 | self.sending = sending.Sending(self) 65 | self.serviceMethods = serviceMethods.ServiceMethods(self) 66 | self.webhooks = webhooks.Webhooks(self) 67 | self.statuses = statuses.Statuses(self) 68 | 69 | self.logger = logging.getLogger("whatsapp-api-client-python") 70 | self.__prepare_logger() 71 | 72 | def request( 73 | self, 74 | method: str, 75 | url: str, 76 | payload: Optional[dict] = None, 77 | files: Optional[dict] = None 78 | ) -> GreenAPIResponse: 79 | url = url.replace("{{host}}", self.host) 80 | url = url.replace("{{media}}", self.media) 81 | url = url.replace("{{idInstance}}", self.idInstance) 82 | url = url.replace("{{apiTokenInstance}}", self.apiTokenInstance) 83 | 84 | headers = { 85 | 'User-Agent': 'GREEN-API_SDK_PY/1.0' 86 | } 87 | 88 | try: 89 | if not files: 90 | response = self.session.request( 91 | method=method, url=url, json=payload, timeout=self.host_timeout, headers=headers 92 | ) 93 | else: 94 | response = self.session.request( 95 | method=method, url=url, data=payload, files=files, timeout=self.media_timeout, headers=headers 96 | ) 97 | except Exception as error: 98 | error_message = f"Request was failed with error: {error}." 99 | 100 | if self.raise_errors: 101 | raise GreenAPIError(error_message) 102 | self.logger.log(logging.CRITICAL, error_message) 103 | 104 | return GreenAPIResponse(None, error_message) 105 | 106 | self.__handle_response(response) 107 | 108 | return GreenAPIResponse(response.status_code, response.text) 109 | 110 | def raw_request(self, **arguments: Any) -> GreenAPIResponse: 111 | try: 112 | response = self.session.request(**arguments) 113 | except Exception as error: 114 | error_message = f"Request was failed with error: {error}." 115 | 116 | if self.raise_errors: 117 | raise GreenAPIError(error_message) 118 | self.logger.log(logging.CRITICAL, error_message) 119 | 120 | return GreenAPIResponse(None, error_message) 121 | 122 | self.__handle_response(response) 123 | 124 | return GreenAPIResponse(response.status_code, response.text) 125 | 126 | def __handle_response(self, response: Response) -> Optional[NoReturn]: 127 | status_code = response.status_code 128 | if status_code != 200 or self.debug_mode: 129 | try: 130 | data = json.dumps( 131 | json.loads(response.text), ensure_ascii=False, indent=4 132 | ) 133 | except json.JSONDecodeError: 134 | data = response.text 135 | 136 | if status_code != 200: 137 | error_message = ( 138 | f"Request was failed with status code: {status_code}." 139 | f" Data: {data}" 140 | ) 141 | 142 | if self.raise_errors: 143 | raise GreenAPIError(error_message) 144 | self.logger.log(logging.ERROR, error_message) 145 | 146 | return None 147 | 148 | self.logger.log( 149 | logging.DEBUG, f"Request was successful with data: {data}" 150 | ) 151 | 152 | def __prepare_logger(self) -> None: 153 | handler = logging.StreamHandler() 154 | handler.setFormatter(logging.Formatter( 155 | ( 156 | "%(asctime)s:%(name)s:" 157 | "%(levelname)s:%(message)s" 158 | ), datefmt="%Y-%m-%d %H:%M:%S" 159 | )) 160 | 161 | self.logger.addHandler(handler) 162 | 163 | if not self.debug_mode: 164 | self.logger.setLevel(logging.INFO) 165 | else: 166 | self.logger.setLevel(logging.DEBUG) 167 | 168 | def __prepare_session(self) -> None: 169 | self.session.headers["Connection"] = "close" 170 | 171 | retry = Retry( 172 | total=3, 173 | backoff_factor=1.0, 174 | allowed_methods=None, 175 | status_forcelist=[429] 176 | ) 177 | 178 | self.session.mount("http://", HTTPAdapter(max_retries=retry)) 179 | self.session.mount("https://", HTTPAdapter(max_retries=retry)) 180 | 181 | class GreenAPI(GreenApi): 182 | pass 183 | 184 | 185 | class GreenAPIError(Exception): 186 | pass 187 | 188 | class GreenApiPartner(GreenApi): 189 | def __init__( 190 | self, 191 | partnerToken: str, 192 | email: str = None, 193 | host: str = "https://api.green-api.com" 194 | ): 195 | 196 | super().__init__( 197 | idInstance="", 198 | apiTokenInstance="", 199 | host=host 200 | ) 201 | 202 | self.partnerToken = partnerToken 203 | self.email = email 204 | self.partner = partner.Partner(self) 205 | 206 | def request( 207 | self, 208 | method: str, 209 | url: str, 210 | payload: Optional[dict] = None, 211 | files: Optional[dict] = None 212 | ) -> GreenAPIResponse: 213 | 214 | url = url.replace("{{partnerToken}}", self.partnerToken) 215 | 216 | return super().request(method, url, payload, files) -------------------------------------------------------------------------------- /whatsapp_api_client_python/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/green-api/whatsapp-api-client-python/731b8f60328bc34601716bc393f0e9a4dd5d80ff/whatsapp_api_client_python/__init__.py -------------------------------------------------------------------------------- /whatsapp_api_client_python/response.py: -------------------------------------------------------------------------------- 1 | from json import loads 2 | from typing import Optional 3 | 4 | 5 | class Response: 6 | code: Optional[int] 7 | data: Optional[dict] = None 8 | error: Optional[str] = None 9 | 10 | def __init__(self, code: Optional[int], text: str): 11 | self.code = code 12 | if self.code == 200: 13 | try: 14 | self.data = loads(text) 15 | except Exception: 16 | self.data = "[]" 17 | else: 18 | self.error = text 19 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/green-api/whatsapp-api-client-python/731b8f60328bc34601716bc393f0e9a4dd5d80ff/whatsapp_api_client_python/tools/__init__.py -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/account.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import Dict, TYPE_CHECKING, Union 3 | 4 | from ..response import Response 5 | 6 | if TYPE_CHECKING: 7 | from ..API import GreenApi 8 | 9 | 10 | class Account: 11 | def __init__(self, api: "GreenApi"): 12 | self.api = api 13 | 14 | def getSettings(self) -> Response: 15 | """ 16 | The method is aimed for getting the current account settings. 17 | 18 | https://green-api.com/en/docs/api/account/GetSettings/ 19 | """ 20 | 21 | return self.api.request( 22 | "GET", ( 23 | "{{host}}/waInstance{{idInstance}}/" 24 | "getSettings/{{apiTokenInstance}}" 25 | ) 26 | ) 27 | 28 | def getWaSettings(self) -> Response: 29 | """ 30 | The method is aimed to get information about the WhatsApp 31 | account. 32 | 33 | https://green-api.com/en/docs/api/account/GetWaSettings/ 34 | """ 35 | 36 | return self.api.request( 37 | "GET", ( 38 | "{{host}}/waInstance{{idInstance}}/" 39 | "getWaSettings/{{apiTokenInstance}}" 40 | ) 41 | ) 42 | 43 | def setSettings(self, requestBody: Dict[str, Union[int, str]]) -> Response: 44 | """ 45 | The method is aimed for setting account settings. 46 | 47 | https://green-api.com/en/docs/api/account/SetSettings/ 48 | """ 49 | 50 | return self.api.request( 51 | "POST", ( 52 | "{{host}}/waInstance{{idInstance}}/" 53 | "setSettings/{{apiTokenInstance}}" 54 | ), requestBody 55 | ) 56 | 57 | def getStateInstance(self) -> Response: 58 | """ 59 | The method is aimed for getting the account state. 60 | 61 | https://green-api.com/en/docs/api/account/GetStateInstance/ 62 | """ 63 | 64 | return self.api.request( 65 | "GET", ( 66 | "{{host}}/waInstance{{idInstance}}/" 67 | "getStateInstance/{{apiTokenInstance}}" 68 | ) 69 | ) 70 | 71 | def getStatusInstance(self) -> Response: 72 | """ 73 | The method is aimed for getting the status of the account 74 | instance socket connection with WhatsApp. 75 | 76 | https://green-api.com/en/docs/api/account/GetStatusInstance/ 77 | """ 78 | 79 | return self.api.request( 80 | "GET", ( 81 | "{{host}}/waInstance{{idInstance}}/" 82 | "getStatusInstance/{{apiTokenInstance}}" 83 | ) 84 | ) 85 | 86 | def reboot(self) -> Response: 87 | """ 88 | The method is aimed for rebooting an account. 89 | 90 | https://green-api.com/en/docs/api/account/Reboot/ 91 | """ 92 | 93 | return self.api.request( 94 | "GET", ( 95 | "{{host}}/waInstance{{idInstance}}/reboot/{{apiTokenInstance}}" 96 | ) 97 | ) 98 | 99 | def logout(self) -> Response: 100 | """ 101 | The method is aimed for logging out an account. 102 | 103 | https://green-api.com/en/docs/api/account/Logout/ 104 | """ 105 | 106 | return self.api.request( 107 | "GET", ( 108 | "{{host}}/waInstance{{idInstance}}/logout/{{apiTokenInstance}}" 109 | ) 110 | ) 111 | 112 | def qr(self) -> Response: 113 | """ 114 | The method is aimed for getting QR code. 115 | 116 | https://green-api.com/en/docs/api/account/QR/ 117 | """ 118 | 119 | return self.api.request( 120 | "GET", "{{host}}/waInstance{{idInstance}}/qr/{{apiTokenInstance}}" 121 | ) 122 | 123 | def setProfilePicture(self, path: str) -> Response: 124 | """ 125 | The method is aimed for setting an account picture. 126 | 127 | https://green-api.com/en/docs/api/account/SetProfilePicture/ 128 | """ 129 | 130 | file_name = Path(path).name 131 | files = {"file": (file_name, open(path, "rb"), "image/jpeg")} 132 | 133 | return self.api.request( 134 | "POST", ( 135 | "{{host}}/waInstance{{idInstance}}/" 136 | "setProfilePicture/{{apiTokenInstance}}" 137 | ), files=files 138 | ) 139 | 140 | def getAuthorizationCode(self, phoneNumber: int) -> Response: 141 | """ 142 | The method is designed to authorize an instance by phone number. 143 | 144 | https://green-api.com/en/docs/api/account/GetAuthorizationCode/ 145 | """ 146 | 147 | request_body = locals() 148 | request_body.pop("self") 149 | 150 | return self.api.request( 151 | "POST", ( 152 | "{{host}}/waInstance{{idInstance}}/" 153 | "getAuthorizationCode/{{apiTokenInstance}}" 154 | ), request_body 155 | ) 156 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/device.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class Device: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def getDeviceInfo(self) -> Response: 14 | """ 15 | The method is aimed for getting information about the device 16 | (phone) running WhatsApp Business application. 17 | 18 | https://green-api.com/en/docs/api/phone/GetDeviceInfo/ 19 | """ 20 | 21 | return self.api.request( 22 | "GET", ( 23 | "{{host}}/waInstance{{idInstance}}/" 24 | "getDeviceInfo/{{apiTokenInstance}}" 25 | ) 26 | ) 27 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/groups.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import List, TYPE_CHECKING 3 | 4 | from ..response import Response 5 | 6 | if TYPE_CHECKING: 7 | from ..API import GreenApi 8 | 9 | 10 | class Groups: 11 | def __init__(self, api: "GreenApi"): 12 | self.api = api 13 | 14 | def createGroup(self, groupName: str, chatIds: List[str]) -> Response: 15 | """ 16 | The method is aimed for creating a group chat. 17 | 18 | https://green-api.com/en/docs/api/groups/CreateGroup/ 19 | """ 20 | 21 | request_body = self.__handle_parameters(locals()) 22 | 23 | return self.api.request( 24 | "POST", ( 25 | "{{host}}/waInstance{{idInstance}}/" 26 | "createGroup/{{apiTokenInstance}}" 27 | ), request_body 28 | ) 29 | 30 | def updateGroupName(self, groupId: str, groupName: str) -> Response: 31 | """ 32 | The method changes a group chat name. 33 | 34 | https://green-api.com/en/docs/api/groups/UpdateGroupName/ 35 | """ 36 | 37 | request_body = self.__handle_parameters(locals()) 38 | 39 | return self.api.request( 40 | "POST", ( 41 | "{{host}}/waInstance{{idInstance}}/" 42 | "updateGroupName/{{apiTokenInstance}}" 43 | ), request_body 44 | ) 45 | 46 | def getGroupData(self, groupId: str) -> Response: 47 | """ 48 | The method gets group chat data. 49 | 50 | https://green-api.com/en/docs/api/groups/GetGroupData/ 51 | """ 52 | 53 | request_body = self.__handle_parameters(locals()) 54 | 55 | return self.api.request( 56 | "POST", ( 57 | "{{host}}/waInstance{{idInstance}}/" 58 | "getGroupData/{{apiTokenInstance}}" 59 | ), request_body 60 | ) 61 | 62 | def addGroupParticipant( 63 | self, groupId: str, participantChatId: str 64 | ) -> Response: 65 | """ 66 | The method adds a participant to a group chat. 67 | 68 | https://green-api.com/en/docs/api/groups/AddGroupParticipant/ 69 | """ 70 | 71 | request_body = self.__handle_parameters(locals()) 72 | 73 | return self.api.request( 74 | "POST", ( 75 | "{{host}}/waInstance{{idInstance}}/" 76 | "addGroupParticipant/{{apiTokenInstance}}" 77 | ), request_body 78 | ) 79 | 80 | def removeGroupParticipant( 81 | self, groupId: str, participantChatId: str 82 | ) -> Response: 83 | """ 84 | The method removes a participant from a group chat. 85 | 86 | https://green-api.com/en/docs/api/groups/RemoveGroupParticipant/ 87 | """ 88 | 89 | request_body = self.__handle_parameters(locals()) 90 | 91 | return self.api.request( 92 | "POST", ( 93 | "{{host}}/waInstance{{idInstance}}/" 94 | "removeGroupParticipant/{{apiTokenInstance}}" 95 | ), request_body 96 | ) 97 | 98 | def setGroupAdmin(self, groupId: str, participantChatId: str) -> Response: 99 | """ 100 | The method sets a group chat participant as an administrator. 101 | 102 | https://green-api.com/en/docs/api/groups/SetGroupAdmin/ 103 | """ 104 | 105 | request_body = self.__handle_parameters(locals()) 106 | 107 | return self.api.request( 108 | "POST", ( 109 | "{{host}}/waInstance{{idInstance}}/" 110 | "setGroupAdmin/{{apiTokenInstance}}" 111 | ), request_body 112 | ) 113 | 114 | def removeAdmin(self, groupId: str, participantChatId: str) -> Response: 115 | """ 116 | The method removes a participant from group chat administration 117 | rights. 118 | 119 | https://green-api.com/en/docs/api/groups/RemoveAdmin/ 120 | """ 121 | 122 | request_body = self.__handle_parameters(locals()) 123 | 124 | return self.api.request( 125 | "POST", ( 126 | "{{host}}/waInstance{{idInstance}}/" 127 | "removeAdmin/{{apiTokenInstance}}" 128 | ), request_body 129 | ) 130 | 131 | def setGroupPicture(self, groupId: str, path: str) -> Response: 132 | """ 133 | The method sets a group picture. 134 | 135 | https://green-api.com/en/docs/api/groups/SetGroupPicture/ 136 | """ 137 | 138 | request_body = self.__handle_parameters(locals()) 139 | 140 | file_name = Path(path).name 141 | files = {"file": (file_name, open(path, "rb"), "image/jpeg")} 142 | 143 | request_body.pop("path") 144 | 145 | return self.api.request( 146 | "POST", ( 147 | "{{host}}/waInstance{{idInstance}}/" 148 | "setGroupPicture/{{apiTokenInstance}}" 149 | ), request_body, files 150 | ) 151 | 152 | def leaveGroup(self, groupId: str) -> Response: 153 | """ 154 | The method makes the current account user leave the group chat. 155 | 156 | https://green-api.com/en/docs/api/groups/LeaveGroup/ 157 | """ 158 | 159 | request_body = self.__handle_parameters(locals()) 160 | 161 | return self.api.request( 162 | "POST", ( 163 | "{{host}}/waInstance{{idInstance}}/" 164 | "leaveGroup/{{apiTokenInstance}}" 165 | ), request_body 166 | ) 167 | 168 | @classmethod 169 | def __handle_parameters(cls, parameters: dict) -> dict: 170 | handled_parameters = parameters.copy() 171 | 172 | handled_parameters.pop("self") 173 | 174 | for key, value in parameters.items(): 175 | if value is None: 176 | handled_parameters.pop(key) 177 | 178 | return handled_parameters 179 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/journals.py: -------------------------------------------------------------------------------- 1 | from typing import Optional, TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class Journals: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def getChatHistory( 14 | self, chatId: str, count: Optional[int] = None 15 | ) -> Response: 16 | """ 17 | The method returns the chat message history. 18 | 19 | https://green-api.com/en/docs/api/journals/GetChatHistory/ 20 | """ 21 | 22 | request_body = locals() 23 | if count is None: 24 | request_body.pop("count") 25 | request_body.pop("self") 26 | 27 | return self.api.request( 28 | "POST", ( 29 | "{{host}}/waInstance{{idInstance}}/" 30 | "getChatHistory/{{apiTokenInstance}}" 31 | ), request_body 32 | ) 33 | 34 | def getMessage(self, chatId: str, idMessage: str) -> Response: 35 | """ 36 | The method returns the chat message. 37 | 38 | https://green-api.com/en/docs/api/journals/GetMessage/ 39 | """ 40 | 41 | request_body = locals() 42 | request_body.pop("self") 43 | 44 | return self.api.request( 45 | "POST", ( 46 | "{{host}}/waInstance{{idInstance}}/" 47 | "getMessage/{{apiTokenInstance}}" 48 | ), request_body 49 | ) 50 | 51 | def lastIncomingMessages(self, minutes: Optional[int] = None) -> Response: 52 | """ 53 | The method returns the last incoming messages of the account. 54 | 55 | https://green-api.com/en/docs/api/journals/LastIncomingMessages/ 56 | """ 57 | 58 | append_minutes = "" 59 | if minutes is not None: 60 | append_minutes = f"?minutes={minutes}" 61 | 62 | return self.api.request( 63 | "GET", ( 64 | "{{host}}/waInstance{{idInstance}}/" 65 | "lastIncomingMessages/{{apiTokenInstance}}"+append_minutes 66 | ) 67 | ) 68 | 69 | def lastOutgoingMessages(self, minutes: Optional[int] = None) -> Response: 70 | """ 71 | The method returns the last outgoing messages of the account. 72 | 73 | https://green-api.com/en/docs/api/journals/LastOutgoingMessages/ 74 | """ 75 | 76 | append_minutes = "" 77 | if minutes is not None: 78 | append_minutes = f"?minutes={minutes}" 79 | 80 | return self.api.request( 81 | "GET", ( 82 | "{{host}}/waInstance{{idInstance}}/" 83 | "lastOutgoingMessages/{{apiTokenInstance}}"+append_minutes 84 | ) 85 | ) 86 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/marking.py: -------------------------------------------------------------------------------- 1 | from typing import Optional, TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class Marking: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def readChat( 14 | self, chatId: str, idMessage: Optional[str] = None 15 | ) -> Response: 16 | """ 17 | The method is aimed for marking messages in a chat as read. 18 | 19 | https://green-api.com/en/docs/api/marks/ReadChat/ 20 | """ 21 | 22 | request_body = locals() 23 | if idMessage is None: 24 | request_body.pop("idMessage") 25 | request_body.pop("self") 26 | 27 | return self.api.request( 28 | "POST", ( 29 | "{{host}}/waInstance{{idInstance}}/" 30 | "readChat/{{apiTokenInstance}}" 31 | ), request_body 32 | ) 33 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/partner.py: -------------------------------------------------------------------------------- 1 | from typing import Dict, TYPE_CHECKING, Union 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApiPartner 7 | 8 | class Partner: 9 | def __init__(self, api: "GreenApiPartner"): 10 | self.api = api 11 | 12 | def getInstances(self) -> Response: 13 | """ 14 | The method is aimed for getting all the account instances created by the partner. 15 | 16 | https://green-api.com/en/docs/partners/getInstances/ 17 | """ 18 | 19 | return self.api.request( 20 | "GET", ( 21 | "{{host}}/partner/" 22 | "getInstances/{{partnerToken}}" 23 | ) 24 | ) 25 | 26 | def createInstance(self, requestBody: Dict[str, Union[int, str]]) -> Response: 27 | """ 28 | The method is aimed for creating a messenger account instance on the partner's part. 29 | 30 | https://green-api.com/en/docs/partners/createInstance/ 31 | """ 32 | 33 | return self.api.request( 34 | "POST", ( 35 | "{{host}}/partner/" 36 | "createInstance/{{partnerToken}}" 37 | ), requestBody 38 | ) 39 | 40 | def deleteInstanceAccount(self, idInstance: int) -> Response: 41 | """ 42 | The method is aimed for deleting an instance of the partners's account. 43 | 44 | https://green-api.com/en/docs/partners/deleteInstanceAccount/ 45 | """ 46 | 47 | request_body = self.__handle_parameters(locals()) 48 | 49 | return self.api.request( 50 | "POST", ( 51 | "{{host}}/partner/" 52 | "deleteInstanceAccount/{{partnerToken}}" 53 | ), request_body 54 | ) 55 | 56 | @classmethod 57 | def __handle_parameters(cls, parameters: dict) -> dict: 58 | handled_parameters = parameters.copy() 59 | 60 | handled_parameters.pop("self") 61 | 62 | for key, value in parameters.items(): 63 | if value is None: 64 | handled_parameters.pop(key) 65 | 66 | return handled_parameters -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/queues.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class Queues: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def showMessagesQueue(self) -> Response: 14 | """ 15 | The method is aimed for getting a list of messages in the queue 16 | to be sent. 17 | 18 | https://green-api.com/en/docs/api/queues/ShowMessagesQueue/ 19 | """ 20 | 21 | return self.api.request( 22 | "GET", ( 23 | "{{host}}/waInstance{{idInstance}}/" 24 | "showMessagesQueue/{{apiTokenInstance}}" 25 | ) 26 | ) 27 | 28 | def clearMessagesQueue(self) -> Response: 29 | """ 30 | The method is aimed for clearing the queue of messages to be 31 | sent. 32 | 33 | https://green-api.com/en/docs/api/queues/ClearMessagesQueue/ 34 | """ 35 | 36 | return self.api.request( 37 | "GET", ( 38 | "{{host}}/waInstance{{idInstance}}/" 39 | "clearMessagesQueue/{{apiTokenInstance}}" 40 | ) 41 | ) 42 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/receiving.py: -------------------------------------------------------------------------------- 1 | from typing import TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class Receiving: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def receiveNotification(self) -> Response: 14 | """ 15 | The method is aimed for receiving one incoming notification 16 | from the notifications queue. 17 | 18 | https://green-api.com/en/docs/api/receiving/technology-http-api/ReceiveNotification/ 19 | """ 20 | 21 | return self.api.request( 22 | "GET", ( 23 | "{{host}}/waInstance{{idInstance}}/" 24 | "receiveNotification/{{apiTokenInstance}}" 25 | ) 26 | ) 27 | 28 | def deleteNotification(self, receiptId: int) -> Response: 29 | """ 30 | The method is aimed for deleting an incoming notification from 31 | the notification queue. 32 | 33 | https://green-api.com/en/docs/api/receiving/technology-http-api/DeleteNotification/ 34 | """ 35 | 36 | url = ( 37 | "{{host}}/waInstance{{idInstance}}/" 38 | "deleteNotification/{{apiTokenInstance}}" 39 | ) 40 | 41 | return self.api.request("DELETE", f"{url}/{receiptId}") 42 | 43 | def downloadFile(self, chatId: str, idMessage: str) -> Response: 44 | """ 45 | The method is aimed for downloading incoming and outgoing files. 46 | 47 | https://green-api.com/en/docs/api/receiving/files/DownloadFile/ 48 | """ 49 | 50 | request_body = locals() 51 | request_body.pop("self") 52 | 53 | return self.api.request( 54 | "POST", ( 55 | "{{host}}/waInstance{{idInstance}}/" 56 | "downloadFile/{{apiTokenInstance}}" 57 | ), request_body 58 | ) 59 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/sending.py: -------------------------------------------------------------------------------- 1 | import mimetypes 2 | import pathlib 3 | from typing import Dict, List, Optional, TYPE_CHECKING, Union 4 | 5 | from ..response import Response 6 | 7 | if TYPE_CHECKING: 8 | from ..API import GreenApi 9 | 10 | 11 | class Sending: 12 | def __init__(self, api: "GreenApi"): 13 | self.api = api 14 | 15 | def sendMessage( 16 | self, 17 | chatId: str, 18 | message: str, 19 | quotedMessageId: Optional[str] = None, 20 | archiveChat: Optional[bool] = None, 21 | linkPreview: Optional[bool] = None 22 | ) -> Response: 23 | """ 24 | The method is aimed for sending a text message to a personal or 25 | a group chat. 26 | 27 | https://green-api.com/en/docs/api/sending/SendMessage/ 28 | """ 29 | 30 | request_body = self.__handle_parameters(locals()) 31 | 32 | return self.api.request( 33 | "POST", ( 34 | "{{host}}/waInstance{{idInstance}}/" 35 | "sendMessage/{{apiTokenInstance}}" 36 | ), request_body 37 | ) 38 | 39 | def sendButtons( 40 | self, 41 | chatId: str, 42 | message: str, 43 | buttons: List[Dict[str, Union[int, str]]], 44 | footer: Optional[str] = None, 45 | quotedMessageId: Optional[str] = None, 46 | archiveChat: Optional[bool] = None 47 | ) -> Response: 48 | """ 49 | The method is aimed for sending a button message to a personal 50 | or a group chat. 51 | 52 | https://green-api.com/en/docs/api/sending/SendButtons/ 53 | """ 54 | 55 | request_body = self.__handle_parameters(locals()) 56 | 57 | return self.api.request( 58 | "POST", ( 59 | "{{host}}/waInstance{{idInstance}}/" 60 | "sendButtons/{{apiTokenInstance}}" 61 | ), request_body 62 | ) 63 | 64 | def sendTemplateButtons( 65 | self, 66 | chatId: str, 67 | message: str, 68 | templateButtons: List[Dict[str, Union[int, Dict[str, str]]]], 69 | footer: Optional[str] = None, 70 | quotedMessageId: Optional[str] = None, 71 | archiveChat: Optional[bool] = None 72 | ) -> Response: 73 | """ 74 | The method is aimed for sending a message with template list 75 | interactive buttons to a personal or a group chat. 76 | 77 | https://green-api.com/en/docs/api/sending/SendTemplateButtons/ 78 | """ 79 | 80 | request_body = self.__handle_parameters(locals()) 81 | 82 | return self.api.request( 83 | "POST", ( 84 | "{{host}}/waInstance{{idInstance}}/" 85 | "sendTemplateButtons/{{apiTokenInstance}}" 86 | ), request_body 87 | ) 88 | 89 | def sendListMessage( 90 | self, 91 | chatId: str, 92 | message: str, 93 | buttonText: str, 94 | sections: List[Dict[str, Union[str, List[Dict[str, str]]]]], 95 | title: Optional[str] = None, 96 | footer: Optional[str] = None, 97 | quotedMessageId: Optional[str] = None, 98 | archiveChat: Optional[bool] = None 99 | ) -> Response: 100 | """ 101 | The method is aimed for sending a message with a select button 102 | from a list of values to a personal or a group chat. 103 | 104 | https://green-api.com/en/docs/api/sending/SendListMessage/ 105 | """ 106 | 107 | request_body = self.__handle_parameters(locals()) 108 | 109 | return self.api.request( 110 | "POST", ( 111 | "{{host}}/waInstance{{idInstance}}/" 112 | "sendListMessage/{{apiTokenInstance}}" 113 | ), request_body 114 | ) 115 | 116 | def sendFileByUpload( 117 | self, 118 | chatId: str, 119 | path: str, 120 | fileName: Optional[str] = None, 121 | caption: Optional[str] = None, 122 | quotedMessageId: Optional[str] = None 123 | ) -> Response: 124 | """ 125 | The method is aimed for sending a file uploaded by form 126 | (form-data). 127 | 128 | https://green-api.com/en/docs/api/sending/SendFileByUpload/ 129 | """ 130 | 131 | request_body = self.__handle_parameters(locals()) 132 | 133 | file_name = pathlib.Path(path).name 134 | content_type = mimetypes.guess_type(file_name)[0] 135 | 136 | files = {"file": (file_name, open(path, "rb"), content_type)} 137 | 138 | request_body.pop("path") 139 | 140 | return self.api.request( 141 | "POST", ( 142 | "{{media}}/waInstance{{idInstance}}/" 143 | "sendFileByUpload/{{apiTokenInstance}}" 144 | ), request_body, files 145 | ) 146 | 147 | def sendFileByUrl( 148 | self, 149 | chatId: str, 150 | urlFile: str, 151 | fileName: str, 152 | caption: Optional[str] = None, 153 | quotedMessageId: Optional[str] = None, 154 | archiveChat: Optional[bool] = None 155 | ) -> Response: 156 | """ 157 | The method is aimed for sending a file uploaded by URL. 158 | 159 | https://green-api.com/en/docs/api/sending/SendFileByUrl/ 160 | """ 161 | 162 | request_body = self.__handle_parameters(locals()) 163 | 164 | return self.api.request( 165 | "POST", ( 166 | "{{host}}/waInstance{{idInstance}}/" 167 | "sendFileByUrl/{{apiTokenInstance}}" 168 | ), request_body 169 | ) 170 | 171 | def uploadFile(self, path: str) -> Response: 172 | """ 173 | The method is designed to upload a file to the cloud storage, 174 | which can be sent using the sendFileByUrl method. 175 | 176 | https://green-api.com/en/docs/api/sending/UploadFile/ 177 | """ 178 | 179 | file_name = pathlib.Path(path).name 180 | content_type = mimetypes.guess_type(file_name)[0] 181 | 182 | with open(path, "rb") as file: 183 | return self.api.raw_request( 184 | method="POST", 185 | url=( 186 | f"{self.api.media}/waInstance{self.api.idInstance}/" 187 | f"uploadFile/{self.api.apiTokenInstance}" 188 | ), 189 | data=file.read(), 190 | headers={"Content-Type": content_type, 191 | "GA-Filename": file_name} 192 | ) 193 | 194 | def sendLocation( 195 | self, 196 | chatId: str, 197 | latitude: float, 198 | longitude: float, 199 | nameLocation: Optional[str] = None, 200 | address: Optional[str] = None, 201 | quotedMessageId: Optional[str] = None 202 | ) -> Response: 203 | """ 204 | The method is aimed for sending location message. 205 | 206 | https://green-api.com/en/docs/api/sending/SendLocation/ 207 | """ 208 | 209 | request_body = self.__handle_parameters(locals()) 210 | 211 | return self.api.request( 212 | "POST", ( 213 | "{{host}}/waInstance{{idInstance}}/" 214 | "sendLocation/{{apiTokenInstance}}" 215 | ), request_body 216 | ) 217 | 218 | def sendContact( 219 | self, 220 | chatId: str, 221 | contact: Dict[str, Union[int, str]], 222 | quotedMessageId: Optional[str] = None 223 | ) -> Response: 224 | """ 225 | The method is aimed for sending a contact message. 226 | 227 | https://green-api.com/en/docs/api/sending/SendContact/ 228 | """ 229 | 230 | request_body = self.__handle_parameters(locals()) 231 | 232 | return self.api.request( 233 | "POST", ( 234 | "{{host}}/waInstance{{idInstance}}/" 235 | "sendContact/{{apiTokenInstance}}" 236 | ), request_body 237 | ) 238 | 239 | def sendLink( 240 | self, 241 | chatId: str, 242 | urlLink: str, 243 | quotedMessageId: Optional[str] = None 244 | ) -> Response: 245 | """ 246 | The method is deprecated. Please use SendMessage. 247 | 248 | The method is aimed for sending a message with a link, by which 249 | an image preview, title and description will be added. 250 | 251 | https://green-api.com/en/docs/api/sending/SendLink/ 252 | """ 253 | 254 | request_body = self.__handle_parameters(locals()) 255 | 256 | return self.api.request( 257 | "POST", ( 258 | "{{host}}/waInstance{{idInstance}}/" 259 | "sendLink/{{apiTokenInstance}}" 260 | ), request_body 261 | ) 262 | 263 | def forwardMessages( 264 | self, 265 | chatId: str, 266 | chatIdFrom: str, 267 | messages: List[str] 268 | ) -> Response: 269 | """ 270 | The method is intended for forwarding messages to a personal or 271 | group chat. 272 | 273 | https://green-api.com/en/docs/api/sending/ForwardMessages/ 274 | """ 275 | 276 | request_body = self.__handle_parameters(locals()) 277 | 278 | return self.api.request( 279 | "POST", ( 280 | "{{host}}/waInstance{{idInstance}}/" 281 | "forwardMessages/{{apiTokenInstance}}" 282 | ), request_body 283 | ) 284 | 285 | def sendPoll( 286 | self, 287 | chatId: str, 288 | message: str, 289 | options: List[Dict[str, str]], 290 | multipleAnswers: Optional[bool] = None, 291 | quotedMessageId: Optional[str] = None 292 | ) -> Response: 293 | """ 294 | This method is intended for sending messages with a poll to a 295 | private or group chat. 296 | 297 | https://green-api.com/en/docs/api/sending/SendPoll/ 298 | """ 299 | 300 | request_body = self.__handle_parameters(locals()) 301 | 302 | return self.api.request( 303 | "POST", ( 304 | "{{host}}/waInstance{{idInstance}}/" 305 | "sendPoll/{{apiTokenInstance}}" 306 | ), request_body 307 | ) 308 | 309 | @classmethod 310 | def __handle_parameters(cls, parameters: dict) -> dict: 311 | handled_parameters = parameters.copy() 312 | 313 | handled_parameters.pop("self") 314 | 315 | for key, value in parameters.items(): 316 | if value is None: 317 | handled_parameters.pop(key) 318 | 319 | return handled_parameters 320 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/serviceMethods.py: -------------------------------------------------------------------------------- 1 | from typing import Optional, TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class ServiceMethods: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def checkWhatsapp(self, phoneNumber: int) -> Response: 14 | """ 15 | The method checks WhatsApp account availability on a phone 16 | number. 17 | 18 | https://green-api.com/en/docs/api/service/CheckWhatsapp/ 19 | """ 20 | 21 | request_body = locals() 22 | request_body.pop("self") 23 | 24 | return self.api.request( 25 | "POST", ( 26 | "{{host}}/waInstance{{idInstance}}/" 27 | "checkWhatsapp/{{apiTokenInstance}}" 28 | ), request_body 29 | ) 30 | 31 | def getAvatar(self, chatId: str) -> Response: 32 | """ 33 | The method returns a user or a group chat avatar. 34 | 35 | https://green-api.com/en/docs/api/service/GetAvatar/ 36 | """ 37 | 38 | request_body = locals() 39 | request_body.pop("self") 40 | 41 | return self.api.request( 42 | "POST", ( 43 | "{{host}}/waInstance{{idInstance}}/" 44 | "getAvatar/{{apiTokenInstance}}" 45 | ), request_body 46 | ) 47 | 48 | def getContacts(self) -> Response: 49 | """ 50 | The method is aimed for getting a list of the current account 51 | contacts. 52 | 53 | https://green-api.com/en/docs/api/service/GetContacts/ 54 | """ 55 | 56 | return self.api.request( 57 | "GET", ( 58 | "{{host}}/waInstance{{idInstance}}/" 59 | "getContacts/{{apiTokenInstance}}" 60 | ) 61 | ) 62 | 63 | def getContactInfo(self, chatId: str) -> Response: 64 | """ 65 | The method is aimed for getting information on a contact. 66 | 67 | https://green-api.com/en/docs/api/service/GetContactInfo/ 68 | """ 69 | 70 | request_body = locals() 71 | request_body.pop("self") 72 | 73 | return self.api.request( 74 | "POST", ( 75 | "{{host}}/waInstance{{idInstance}}/" 76 | "getContactInfo/{{apiTokenInstance}}" 77 | ), request_body 78 | ) 79 | 80 | def deleteMessage(self, chatId: str, idMessage: str, onlySenderDelete: Optional[bool] = None) -> Response: 81 | """ 82 | The method deletes a message from a chat. 83 | 84 | https://green-api.com/en/docs/api/service/deleteMessage/ 85 | """ 86 | 87 | request_body = locals() 88 | if onlySenderDelete is None: 89 | request_body.pop("onlySenderDelete") 90 | request_body.pop("self") 91 | print(request_body) 92 | 93 | return self.api.request( 94 | "POST", ( 95 | "{{host}}/waInstance{{idInstance}}/" 96 | "deleteMessage/{{apiTokenInstance}}" 97 | ), request_body 98 | ) 99 | 100 | def editMessage(self, chatId: str, idMessage: str, message: str) -> Response: 101 | """ 102 | The method edits a message in chat. 103 | 104 | https://green-api.com/en/docs/api/service/editMessage/ 105 | """ 106 | 107 | request_body = locals() 108 | request_body.pop("self") 109 | 110 | return self.api.request( 111 | "POST", ( 112 | "{{host}}/waInstance{{idInstance}}/" 113 | "editMessage/{{apiTokenInstance}}" 114 | ), request_body 115 | ) 116 | 117 | def archiveChat(self, chatId: str) -> Response: 118 | """ 119 | The method archives a chat. 120 | 121 | https://green-api.com/en/docs/api/service/archiveChat/ 122 | """ 123 | 124 | request_body = locals() 125 | request_body.pop("self") 126 | 127 | return self.api.request( 128 | "POST", ( 129 | "{{host}}/waInstance{{idInstance}}/" 130 | "archiveChat/{{apiTokenInstance}}" 131 | ), request_body 132 | ) 133 | 134 | def unarchiveChat(self, chatId: str) -> Response: 135 | """ 136 | The method unarchives a chat. 137 | 138 | https://green-api.com/en/docs/api/service/unarchiveChat/ 139 | """ 140 | 141 | request_body = locals() 142 | request_body.pop("self") 143 | 144 | return self.api.request( 145 | "POST", ( 146 | "{{host}}/waInstance{{idInstance}}/" 147 | "unarchiveChat/{{apiTokenInstance}}" 148 | ), request_body 149 | ) 150 | 151 | def setDisappearingChat( 152 | self, chatId: str, ephemeralExpiration: Optional[int] = None 153 | ) -> Response: 154 | """ 155 | The method is aimed for changing settings of disappearing 156 | messages in chats. 157 | 158 | https://green-api.com/en/docs/api/service/SetDisappearingChat/ 159 | """ 160 | 161 | request_body = locals() 162 | if ephemeralExpiration is None: 163 | request_body.pop("ephemeralExpiration") 164 | request_body.pop("self") 165 | 166 | return self.api.request( 167 | "POST", ( 168 | "{{host}}/waInstance{{idInstance}}/" 169 | "setDisappearingChat/{{apiTokenInstance}}" 170 | ), request_body 171 | ) 172 | -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/statuses.py: -------------------------------------------------------------------------------- 1 | from typing import List, Optional, TYPE_CHECKING 2 | 3 | from ..response import Response 4 | 5 | if TYPE_CHECKING: 6 | from ..API import GreenApi 7 | 8 | 9 | class Statuses: 10 | def __init__(self, api: "GreenApi"): 11 | self.api = api 12 | 13 | def sendTextStatus( 14 | self, 15 | message: str, 16 | backgroundColor: Optional[str] = None, 17 | font: Optional[str] = None, 18 | participants: Optional[List[str]] = None 19 | ) -> Response: 20 | """ 21 | The method is aimed for sending a text status. 22 | 23 | https://green-api.com/en/docs/api/statuses/SendTextStatus/ 24 | """ 25 | 26 | request_body = self.__handle_parameters(locals()) 27 | 28 | return self.api.request( 29 | "POST", ( 30 | "{{host}}/waInstance{{idInstance}}/" 31 | "sendTextStatus/{{apiTokenInstance}}" 32 | ), request_body 33 | ) 34 | 35 | def sendVoiceStatus( 36 | self, 37 | urlFile: str, 38 | fileName: str, 39 | backgroundColor: Optional[str] = None, 40 | participants: Optional[List[str]] = None 41 | ) -> Response: 42 | """ 43 | The method is aimed for sending a voice status. 44 | 45 | https://green-api.com/en/docs/api/statuses/SendVoiceStatus/ 46 | """ 47 | 48 | request_body = self.__handle_parameters(locals()) 49 | 50 | return self.api.request( 51 | "POST", ( 52 | "{{host}}/waInstance{{idInstance}}/" 53 | "sendVoiceStatus/{{apiTokenInstance}}" 54 | ), request_body 55 | ) 56 | 57 | def sendMediaStatus( 58 | self, 59 | urlFile: str, 60 | fileName: str, 61 | caption: Optional[str] = None, 62 | participants: Optional[List[str]] = None 63 | ) -> Response: 64 | """ 65 | The method is aimed for sending a pictures or video status. 66 | 67 | https://green-api.com/en/docs/api/statuses/SendMediaStatus/ 68 | """ 69 | 70 | request_body = self.__handle_parameters(locals()) 71 | 72 | return self.api.request( 73 | "POST", ( 74 | "{{host}}/waInstance{{idInstance}}/" 75 | "sendMediaStatus/{{apiTokenInstance}}" 76 | ), request_body 77 | ) 78 | 79 | def deleteStatus( 80 | self, 81 | idMessage: str 82 | ) -> Response: 83 | """ 84 | The method is aimed for deleting a certain status. 85 | 86 | https://green-api.com/en/docs/api/statuses/DeleteStatus/ 87 | """ 88 | 89 | request_body = self.__handle_parameters(locals()) 90 | 91 | return self.api.request( 92 | "POST", ( 93 | "{{host}}/waInstance{{idInstance}}/" 94 | "deleteStatus/{{apiTokenInstance}}" 95 | ), request_body 96 | ) 97 | 98 | def getStatusStatistic( 99 | self, 100 | idMessage: str 101 | ) -> Response: 102 | """ 103 | The method returns an array of recipients marked sent/delivered/read for a given status. 104 | 105 | https://green-api.com/en/docs/api/statuses/GetStatusStatistic/ 106 | """ 107 | url = ( 108 | "{{host}}/waInstance{{idInstance}}/" 109 | "getStatusStatistic/{{apiTokenInstance}}" 110 | ) 111 | 112 | return self.api.request("GET", f"{url}?idMessage={idMessage}") 113 | 114 | def getIncomingStatuses( 115 | self, 116 | minutes: Optional[int] = None 117 | ) -> Response: 118 | """ 119 | The method returns the incoming statuses of the account 120 | If no argument passed, the incoming statuses for the past 24 hours are returned. 121 | 122 | https://green-api.com/en/docs/api/statuses/GetIncomingStatuses/ 123 | """ 124 | url = ( 125 | "{{host}}/waInstance{{idInstance}}/" 126 | "getIncomingStatuses/{{apiTokenInstance}}" 127 | ) 128 | 129 | if minutes: 130 | return self.api.request("GET", f"{url}?minutes={minutes}") 131 | else: 132 | return self.api.request("GET", f"{url}") 133 | 134 | def getOutgoingStatuses( 135 | self, 136 | minutes: Optional[int] = None 137 | ) -> Response: 138 | """ 139 | The method returns the outgoing statuses of the account 140 | If no argument passed, the outgoing statuses for the past 24 hours are returned. 141 | 142 | https://green-api.com/en/docs/api/statuses/GetOutgoingStatuses/ 143 | """ 144 | url = ( 145 | "{{host}}/waInstance{{idInstance}}/" 146 | "getOutgoingStatuses/{{apiTokenInstance}}" 147 | ) 148 | 149 | if minutes: 150 | return self.api.request("GET", f"{url}?minutes={minutes}") 151 | else: 152 | return self.api.request("GET", f"{url}") 153 | 154 | @classmethod 155 | def __handle_parameters(cls, parameters: dict) -> dict: 156 | handled_parameters = parameters.copy() 157 | 158 | handled_parameters.pop("self") 159 | 160 | for key, value in parameters.items(): 161 | if value is None: 162 | handled_parameters.pop(key) 163 | 164 | return handled_parameters -------------------------------------------------------------------------------- /whatsapp_api_client_python/tools/webhooks.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from typing import Any, Callable, Optional, TYPE_CHECKING 3 | 4 | if TYPE_CHECKING: 5 | from ..API import GreenApi 6 | 7 | 8 | class Webhooks: 9 | _running: Optional[bool] = None 10 | 11 | def __init__(self, api: "GreenApi"): 12 | self.api = api 13 | 14 | @property 15 | def started(self) -> Optional[bool]: 16 | """Deprecated""" 17 | 18 | self.api.logger.log(logging.WARNING, "This property is deprecated.") 19 | 20 | return self._running 21 | 22 | @started.setter 23 | def started(self, value: bool) -> None: 24 | """Deprecated""" 25 | 26 | self.api.logger.log(logging.WARNING, "This property is deprecated.") 27 | 28 | self._running = value 29 | 30 | def startReceivingNotifications( 31 | self, onEvent: Callable[[str, dict], Any] 32 | ) -> None: 33 | self._running = True 34 | 35 | self._start_polling(onEvent) 36 | 37 | def stopReceivingNotifications(self) -> None: 38 | self._running = False 39 | 40 | def job(self, onEvent: Callable[[str, dict], Any]) -> None: 41 | """Deprecated""" 42 | 43 | self.api.logger.log(logging.WARNING, "This function is deprecated.") 44 | 45 | print(( 46 | "Started receiving incoming notifications." 47 | " To stop the process, press Ctrl + C." 48 | )) 49 | 50 | while self.started: 51 | try: 52 | response = self.api.receiving.receiveNotification() 53 | if response.code == 200: 54 | if not response.data: 55 | continue 56 | response = response.data 57 | 58 | body = response["body"] 59 | type_webhook = body["typeWebhook"] 60 | 61 | onEvent(type_webhook, body) 62 | 63 | self.api.receiving.deleteNotification( 64 | response["receiptId"] 65 | ) 66 | except KeyboardInterrupt: 67 | break 68 | 69 | print("Stopped receiving incoming notifications.") 70 | 71 | def _start_polling(self, handler: Callable[[str, dict], Any]) -> None: 72 | self.api.session.headers["Connection"] = "keep-alive" 73 | 74 | self.api.logger.log( 75 | logging.INFO, "Started receiving incoming notifications." 76 | ) 77 | 78 | while self._running: 79 | try: 80 | response = self.api.receiving.receiveNotification() 81 | if response.code == 200: 82 | if not response.data: 83 | continue 84 | response = response.data 85 | 86 | body = response["body"] 87 | type_webhook = body["typeWebhook"] 88 | 89 | handler(type_webhook, body) 90 | 91 | self.api.receiving.deleteNotification( 92 | response["receiptId"] 93 | ) 94 | except KeyboardInterrupt: 95 | break 96 | 97 | self.api.session.headers["Connection"] = "close" 98 | 99 | self.api.logger.log( 100 | logging.INFO, "Stopped receiving incoming notifications." 101 | ) 102 | --------------------------------------------------------------------------------