whatsapp-python 4.2.0__tar.gz → 4.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- whatsapp_python-4.4.0/.github/workflows/python-publish.yml +46 -0
- whatsapp_python-4.4.0/CONTRIBUTING.md +22 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/LICENSE +1 -1
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/PKG-INFO +26 -21
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/README.md +19 -19
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/reply_to_message_obj.py +2 -2
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_audio.py +2 -3
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_button.py +2 -3
- whatsapp_python-4.4.0/examples/sending_button_async.py +40 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_document.py +2 -3
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_image.py +3 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_location.py +2 -3
- whatsapp_python-4.4.0/examples/sending_message.py +14 -0
- whatsapp_python-4.4.0/examples/sending_message_async.py +19 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_template_message.py +3 -3
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/sending_video.py +2 -3
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/examples/standalone_hook.py +4 -8
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/pyproject.toml +18 -2
- whatsapp_python-4.4.0/tests/manual/README.md +15 -0
- whatsapp_python-4.4.0/tests/manual/async_smoke.py +180 -0
- whatsapp_python-4.4.0/tests/manual/sync_smoke.py +123 -0
- whatsapp_python-4.4.0/tests/test_client.py +241 -0
- whatsapp_python-4.4.0/tests/test_errors.py +28 -0
- whatsapp_python-4.4.0/tests/test_graph_api.py +60 -0
- whatsapp_python-4.4.0/tests/test_static_parsers.py +115 -0
- whatsapp_python-4.4.0/whatsapp/__init__.py +818 -0
- whatsapp_python-4.4.0/whatsapp/async_ext/_buttons.py +230 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/async_ext/_media.py +27 -27
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/async_ext/_message.py +39 -21
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/async_ext/_send_media.py +91 -77
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/async_ext/_send_others.py +12 -8
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/async_ext/_static.py +18 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/constants.py +5 -1
- whatsapp_python-4.4.0/whatsapp/errors.py +340 -0
- whatsapp_python-4.4.0/whatsapp/ext/_buttons.py +201 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/ext/_media.py +14 -9
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/ext/_message.py +33 -19
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/ext/_send_media.py +79 -69
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/ext/_send_others.py +5 -4
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/ext/_static.py +18 -0
- whatsapp_python-4.4.0/whatsapp/graph_api.py +113 -0
- whatsapp_python-4.2.0/.github/workflows/python-publish.yml +0 -39
- whatsapp_python-4.2.0/CONTRIBUTING.md +0 -19
- whatsapp_python-4.2.0/async_test.py +0 -142
- whatsapp_python-4.2.0/examples/sending_message.py +0 -15
- whatsapp_python-4.2.0/tests.py +0 -128
- whatsapp_python-4.2.0/whatsapp/__init__.py +0 -813
- whatsapp_python-4.2.0/whatsapp/async_ext/_buttons.py +0 -118
- whatsapp_python-4.2.0/whatsapp/ext/_buttons.py +0 -104
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/FUNDING.yml +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/dependabot.yml +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/workflows/codeql.yml +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.github/workflows/dependency-review.yml +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/.gitignore +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/CODE_OF_CONDUCT.md +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/SECURITY.md +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/async_ext/_property.py +0 -0
- {whatsapp_python-4.2.0 → whatsapp_python-4.4.0}/whatsapp/ext/_property.py +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Upload to PyPI when a GitHub Release is published.
|
|
2
|
+
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
|
|
3
|
+
|
|
4
|
+
name: Upload Python Package
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [published]
|
|
9
|
+
# Re-run from Actions after workflow fixes (uses the selected branch/ref).
|
|
10
|
+
workflow_dispatch:
|
|
11
|
+
|
|
12
|
+
permissions:
|
|
13
|
+
contents: read
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
deployment:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
environment: publish
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
uses: actions/setup-python@v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.12"
|
|
26
|
+
|
|
27
|
+
- name: Install build tools
|
|
28
|
+
run: |
|
|
29
|
+
python -m pip install --upgrade pip
|
|
30
|
+
pip install build
|
|
31
|
+
|
|
32
|
+
- name: Build package
|
|
33
|
+
run: python -m build
|
|
34
|
+
|
|
35
|
+
- name: Check metadata
|
|
36
|
+
run: |
|
|
37
|
+
python -m pip install --upgrade "twine>=7"
|
|
38
|
+
twine check dist/*
|
|
39
|
+
|
|
40
|
+
# hatchling emits Metadata-Version 2.5; Twine 6 rejects it.
|
|
41
|
+
# gh-action-pypi-publish v1.14.2+ ships Twine 7 which accepts 2.5.
|
|
42
|
+
- name: Publish package
|
|
43
|
+
uses: pypa/gh-action-pypi-publish@v1.14.3
|
|
44
|
+
with:
|
|
45
|
+
user: __token__
|
|
46
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# How to contribute
|
|
2
|
+
|
|
3
|
+
First of all, thank you for considering contributing to this project! It's people like you that make it a reality and help me keep it alive and updated.
|
|
4
|
+
|
|
5
|
+
If you are unsure about anything, feel free to ask me. I am here to help you.
|
|
6
|
+
|
|
7
|
+
Any bug report, feature request, or code contribution is welcome. Here are some guidelines to help you get started.
|
|
8
|
+
|
|
9
|
+
## Submitting changes
|
|
10
|
+
|
|
11
|
+
Please open a [Pull Request](https://github.com/filipporomani/whatsapp-python/pull/new/master) with a list of what you've done (read more about [pull requests](http://help.github.com/pull-requests/)). Make sure, if possible, that all of your commits are atomic (one feature per commit).
|
|
12
|
+
|
|
13
|
+
Always write a clear log message for your commits. One-line messages are fine for small changes, but bigger changes should look like this:
|
|
14
|
+
|
|
15
|
+
$ git commit -m "feat: a brief summary of the commit
|
|
16
|
+
>
|
|
17
|
+
> A paragraph describing what changed and its impact."
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
* This is an open source software. Keep in mind to make your code readable to others. It's sort of like driving a car: perhaps you love doing donuts when you're alone, but with passengers the goal is to make the ride as smooth as possible.
|
|
21
|
+
|
|
22
|
+
There isn't any other particular guideline, feel free to contribute!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
2
|
Version 3, 19 November 2007
|
|
3
3
|
|
|
4
|
-
Copyright
|
|
4
|
+
Copyright © Filippo Romani
|
|
5
5
|
Everyone is permitted to copy and distribute verbatim copies
|
|
6
6
|
of this license document, but changing it is not allowed.
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: whatsapp-python
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Open source Python wrapper for the WhatsApp Cloud API
|
|
5
5
|
Project-URL: Homepage, https://github.com/filipporomani/whatsapp-python
|
|
6
6
|
Project-URL: Docs, https://github.com/filipporomani/whatsapp-python/wiki
|
|
@@ -8,6 +8,7 @@ Project-URL: Issues Reporting, https://github.com/filipporomani/whatsapp-python/
|
|
|
8
8
|
Project-URL: Download, https://github.com/filipporomani/whatsapp-python/releases/latest
|
|
9
9
|
Project-URL: Changelog, https://github.com/filipporomani/whatsapp-python/releases
|
|
10
10
|
Author-email: Filippo Romani <mail@filipporomani.it>
|
|
11
|
+
License-File: LICENSE
|
|
11
12
|
Classifier: Development Status :: 4 - Beta
|
|
12
13
|
Classifier: Intended Audience :: Customer Service
|
|
13
14
|
Classifier: Intended Audience :: Developers
|
|
@@ -26,18 +27,23 @@ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
|
|
|
26
27
|
Classifier: Topic :: Software Development :: Build Tools
|
|
27
28
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
29
|
Requires-Python: >=3.10
|
|
30
|
+
Requires-Dist: aiohttp
|
|
29
31
|
Requires-Dist: beautifulsoup4
|
|
30
32
|
Requires-Dist: fastapi
|
|
31
33
|
Requires-Dist: python-dotenv
|
|
32
34
|
Requires-Dist: requests
|
|
33
35
|
Requires-Dist: requests-toolbelt
|
|
34
36
|
Requires-Dist: uvicorn
|
|
37
|
+
Provides-Extra: test
|
|
38
|
+
Requires-Dist: httpx; extra == 'test'
|
|
39
|
+
Requires-Dist: pytest>=8.0; extra == 'test'
|
|
35
40
|
Description-Content-Type: text/markdown
|
|
36
41
|
|
|
37
42
|
<div align="center">
|
|
38
43
|
<img src="https://gist.githubusercontent.com/boywithkeyboard/e8dc5b1810bd29e1d70346ca11d7f09d/raw/7f7eeea482f5047e62944e54182aa26c89cc299a/whatsapp_python.svg" alt="logo" width="128px">
|
|
39
44
|
<h1>whatsapp-python</h1>
|
|
40
|
-
<p>Free, open-source Python wrapper for the <a href="https://developers.facebook.com/docs/whatsapp/cloud-api">WhatsApp Cloud API</a>.<br>Forked from <a href="https://github.com/Neurotech-HQ/heyoo">Neurotech-HQ/heyoo</a
|
|
45
|
+
<p>Free, open-source Python wrapper for the <a href="https://developers.facebook.com/docs/whatsapp/cloud-api">WhatsApp Cloud API</a>.<br>Forked from <a href="https://github.com/Neurotech-HQ/heyoo">Neurotech-HQ/heyoo</a>.
|
|
46
|
+
</p>
|
|
41
47
|
<img src="https://img.shields.io/badge/made%20in-italy-008751.svg?style=flat-square" alt="Made in Italy">
|
|
42
48
|
<a href="https://pepy.tech/project/whatsapp-python"><img src="https://static.pepy.tech/personalized-badge/whatsapp-python?period=total&units=none&left_color=grey&right_color=blue&left_text=Downloads" alt="Downloads"></a>
|
|
43
49
|
<a href="https://pepy.tech/project/whatsapp-python"><img src="https://pepy.tech/badge/whatsapp-python/month" alt="Monthly Downloads"></a>
|
|
@@ -69,32 +75,31 @@ hatch shell
|
|
|
69
75
|
|
|
70
76
|
Documentation is available in the [wiki](https://github.com/filipporomani/whatsapp/wiki) here on GitHub.
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
### Key features:
|
|
79
|
+
- Modern interface using `async` and `await`
|
|
80
|
+
- Full support for Graph API error handling
|
|
81
|
+
- Optimized for high-load workflows using asyncronous programming
|
|
82
|
+
- Always up to date
|
|
83
|
+
- All of the WhatsApp Business chat UI features supported
|
|
73
84
|
|
|
74
|
-
The main reason why I decided to fork the original `heyoo` library is that it uses an old version of the API, it's missing many and it's not mantained anymore.
|
|
75
85
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
I fixed some bugs and added many features, however the library can still be improved.
|
|
82
|
-
|
|
83
|
-
### Supported features:
|
|
84
|
-
|
|
85
|
-
- Listening to events (messages, media, etc.)
|
|
86
|
-
- Async version available
|
|
86
|
+
### All features
|
|
87
|
+
- Event listening (incoming messages)
|
|
88
|
+
- Asyncronous API calls
|
|
89
|
+
- Error handling
|
|
87
90
|
- Sending messages
|
|
88
91
|
- Sending messages from different numbers individually
|
|
89
|
-
- Marking messages as read
|
|
92
|
+
- Marking messages as read (optional typing indicator)
|
|
90
93
|
- Replying to messages
|
|
91
94
|
- Reacting to messages
|
|
92
|
-
- Sending
|
|
93
|
-
- Sending location
|
|
94
|
-
- Sending interactive buttons
|
|
95
|
+
- Sending medias (images, audios/voice notes, videos, links and documents)
|
|
96
|
+
- Sending location and location-request prompts
|
|
97
|
+
- Sending interactive buttons, lists, and CTA URL buttons
|
|
95
98
|
- Sending template messages
|
|
96
|
-
- Parsing messages and media received
|
|
99
|
+
- Parsing messages and media received (including reactions)
|
|
97
100
|
- Sending contacts
|
|
101
|
+
- Uploading media to the Facebook cloud
|
|
102
|
+
- Automatic Graph API version discovery with a safe fallback (`v27.0`)
|
|
98
103
|
|
|
99
104
|
## Obtaining the WhatsApp API credentials
|
|
100
105
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img src="https://gist.githubusercontent.com/boywithkeyboard/e8dc5b1810bd29e1d70346ca11d7f09d/raw/7f7eeea482f5047e62944e54182aa26c89cc299a/whatsapp_python.svg" alt="logo" width="128px">
|
|
3
3
|
<h1>whatsapp-python</h1>
|
|
4
|
-
<p>Free, open-source Python wrapper for the <a href="https://developers.facebook.com/docs/whatsapp/cloud-api">WhatsApp Cloud API</a>.<br>Forked from <a href="https://github.com/Neurotech-HQ/heyoo">Neurotech-HQ/heyoo</a
|
|
4
|
+
<p>Free, open-source Python wrapper for the <a href="https://developers.facebook.com/docs/whatsapp/cloud-api">WhatsApp Cloud API</a>.<br>Forked from <a href="https://github.com/Neurotech-HQ/heyoo">Neurotech-HQ/heyoo</a>.
|
|
5
|
+
</p>
|
|
5
6
|
<img src="https://img.shields.io/badge/made%20in-italy-008751.svg?style=flat-square" alt="Made in Italy">
|
|
6
7
|
<a href="https://pepy.tech/project/whatsapp-python"><img src="https://static.pepy.tech/personalized-badge/whatsapp-python?period=total&units=none&left_color=grey&right_color=blue&left_text=Downloads" alt="Downloads"></a>
|
|
7
8
|
<a href="https://pepy.tech/project/whatsapp-python"><img src="https://pepy.tech/badge/whatsapp-python/month" alt="Monthly Downloads"></a>
|
|
@@ -33,32 +34,31 @@ hatch shell
|
|
|
33
34
|
|
|
34
35
|
Documentation is available in the [wiki](https://github.com/filipporomani/whatsapp/wiki) here on GitHub.
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
### Key features:
|
|
38
|
+
- Modern interface using `async` and `await`
|
|
39
|
+
- Full support for Graph API error handling
|
|
40
|
+
- Optimized for high-load workflows using asyncronous programming
|
|
41
|
+
- Always up to date
|
|
42
|
+
- All of the WhatsApp Business chat UI features supported
|
|
37
43
|
|
|
38
|
-
The main reason why I decided to fork the original `heyoo` library is that it uses an old version of the API, it's missing many and it's not mantained anymore.
|
|
39
44
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
I fixed some bugs and added many features, however the library can still be improved.
|
|
46
|
-
|
|
47
|
-
### Supported features:
|
|
48
|
-
|
|
49
|
-
- Listening to events (messages, media, etc.)
|
|
50
|
-
- Async version available
|
|
45
|
+
### All features
|
|
46
|
+
- Event listening (incoming messages)
|
|
47
|
+
- Asyncronous API calls
|
|
48
|
+
- Error handling
|
|
51
49
|
- Sending messages
|
|
52
50
|
- Sending messages from different numbers individually
|
|
53
|
-
- Marking messages as read
|
|
51
|
+
- Marking messages as read (optional typing indicator)
|
|
54
52
|
- Replying to messages
|
|
55
53
|
- Reacting to messages
|
|
56
|
-
- Sending
|
|
57
|
-
- Sending location
|
|
58
|
-
- Sending interactive buttons
|
|
54
|
+
- Sending medias (images, audios/voice notes, videos, links and documents)
|
|
55
|
+
- Sending location and location-request prompts
|
|
56
|
+
- Sending interactive buttons, lists, and CTA URL buttons
|
|
59
57
|
- Sending template messages
|
|
60
|
-
- Parsing messages and media received
|
|
58
|
+
- Parsing messages and media received (including reactions)
|
|
61
59
|
- Sending contacts
|
|
60
|
+
- Uploading media to the Facebook cloud
|
|
61
|
+
- Automatic Graph API version discovery with a safe fallback (`v27.0`)
|
|
62
62
|
|
|
63
63
|
## Obtaining the WhatsApp API credentials
|
|
64
64
|
|
|
@@ -4,11 +4,11 @@ from dotenv import load_dotenv
|
|
|
4
4
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
|
-
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1:"1234", 2: "5678"})
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
8
8
|
|
|
9
9
|
data = {"your": "data"}
|
|
10
10
|
|
|
11
|
-
msg = Message(data=data, instance=messenger,sender=1)
|
|
11
|
+
msg = Message(data=data, instance=messenger, sender=1)
|
|
12
12
|
msg.reply("lol")
|
|
13
13
|
|
|
14
14
|
print(msg)
|
|
@@ -4,13 +4,12 @@ from dotenv import load_dotenv
|
|
|
4
4
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
|
-
messenger = WhatsApp(token=getenv("TOKEN"),
|
|
8
|
-
phone_number_id={1:"1234", 2: "5678"})
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
8
|
|
|
10
9
|
response = messenger.send_audio(
|
|
11
10
|
audio="https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
|
|
12
11
|
recipient_id="255757xxxxxx",
|
|
13
|
-
sender=1
|
|
12
|
+
sender=1,
|
|
14
13
|
)
|
|
15
14
|
|
|
16
15
|
print(response)
|
|
@@ -4,8 +4,7 @@ from dotenv import load_dotenv
|
|
|
4
4
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
|
-
messenger = WhatsApp(token=getenv("TOKEN"),
|
|
8
|
-
phone_number_id={1:"1234", 2: "5678"})
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
8
|
|
|
10
9
|
response = messenger.send_button(
|
|
11
10
|
recipient_id="255757xxxxxx",
|
|
@@ -30,5 +29,5 @@ if __name__ == "__main__":
|
|
|
30
29
|
],
|
|
31
30
|
},
|
|
32
31
|
},
|
|
33
|
-
sender=1
|
|
32
|
+
sender=1,
|
|
34
33
|
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from whatsapp import AsyncWhatsApp, AsyncMessage
|
|
3
|
+
import asyncio
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
|
|
6
|
+
if __name__ == "__main__":
|
|
7
|
+
load_dotenv()
|
|
8
|
+
messenger = AsyncWhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
|
+
|
|
10
|
+
async def run_test():
|
|
11
|
+
response = await messenger.send_button(
|
|
12
|
+
recipient_id="255757xxxxxx",
|
|
13
|
+
button={
|
|
14
|
+
"header": "Header Testing",
|
|
15
|
+
"body": "Body Testing",
|
|
16
|
+
"footer": "Footer Testing",
|
|
17
|
+
"action": {
|
|
18
|
+
"button": "Button Testing",
|
|
19
|
+
"sections": [
|
|
20
|
+
{
|
|
21
|
+
"title": "iBank",
|
|
22
|
+
"rows": [
|
|
23
|
+
{"id": "row 1", "title": "Send Money", "description": ""},
|
|
24
|
+
{
|
|
25
|
+
"id": "row 2",
|
|
26
|
+
"title": "Withdraw money",
|
|
27
|
+
"description": "",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
sender=1,
|
|
35
|
+
)
|
|
36
|
+
while not response.done():
|
|
37
|
+
await asyncio.sleep(.1)
|
|
38
|
+
print(response.result())
|
|
39
|
+
|
|
40
|
+
asyncio.run(run_test())
|
|
@@ -5,13 +5,12 @@ from dotenv import load_dotenv
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
7
|
|
|
8
|
-
messenger = WhatsApp(token=getenv("TOKEN"),
|
|
9
|
-
phone_number_id={1:"1234", 2: "5678"})
|
|
8
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
10
9
|
|
|
11
10
|
response = messenger.send_document(
|
|
12
11
|
document="http://www.africau.edu/images/default/sample.pdf",
|
|
13
12
|
recipient_id="255757294146",
|
|
14
|
-
sender=1
|
|
13
|
+
sender=1,
|
|
15
14
|
)
|
|
16
15
|
|
|
17
16
|
print(response)
|
|
@@ -4,8 +4,7 @@ from dotenv import load_dotenv
|
|
|
4
4
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
|
-
messenger = WhatsApp(token=getenv("TOKEN"),
|
|
8
|
-
phone_number_id={1:"1234", 2: "5678"})
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
8
|
|
|
10
9
|
response = messenger.send_location(
|
|
11
10
|
lat=1.29,
|
|
@@ -13,7 +12,7 @@ if __name__ == "__main__":
|
|
|
13
12
|
name="Singapore",
|
|
14
13
|
address="Singapore",
|
|
15
14
|
recipient_id="255757294146",
|
|
16
|
-
sender=1
|
|
15
|
+
sender=1,
|
|
17
16
|
)
|
|
18
17
|
|
|
19
18
|
print(response)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from whatsapp import WhatsApp, Message
|
|
3
|
+
from dotenv import load_dotenv
|
|
4
|
+
|
|
5
|
+
if __name__ == "__main__":
|
|
6
|
+
load_dotenv()
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
8
|
+
|
|
9
|
+
msg = Message(
|
|
10
|
+
instance=messenger, content="Hello World!", to="919999999999", sender=1
|
|
11
|
+
)
|
|
12
|
+
response = msg.send()
|
|
13
|
+
|
|
14
|
+
print(response)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from os import getenv
|
|
2
|
+
from whatsapp import AsyncWhatsApp, AsyncMessage
|
|
3
|
+
import asyncio
|
|
4
|
+
from dotenv import load_dotenv
|
|
5
|
+
|
|
6
|
+
if __name__ == "__main__":
|
|
7
|
+
load_dotenv()
|
|
8
|
+
messenger = AsyncWhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
|
+
|
|
10
|
+
msg = AsyncMessage(
|
|
11
|
+
instance=messenger, content="Hello World!", to="919999999999", sender=1
|
|
12
|
+
)
|
|
13
|
+
async def run_test():
|
|
14
|
+
response = await msg.send()
|
|
15
|
+
while not response.done():
|
|
16
|
+
await asyncio.sleep(.1)
|
|
17
|
+
print(response.result())
|
|
18
|
+
|
|
19
|
+
asyncio.run(run_test())
|
|
@@ -4,10 +4,10 @@ from dotenv import load_dotenv
|
|
|
4
4
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
|
-
messenger = WhatsApp(token=getenv("TOKEN"),
|
|
8
|
-
phone_number_id={1:"1234", 2: "5678"})
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
8
|
|
|
10
9
|
response = messenger.send_template(
|
|
11
|
-
"hello_world", "255757xxxxxx", components=[], lang="en_US", sender=1
|
|
10
|
+
"hello_world", "255757xxxxxx", components=[], lang="en_US", sender=1
|
|
11
|
+
)
|
|
12
12
|
|
|
13
13
|
print(response)
|
|
@@ -4,13 +4,12 @@ from dotenv import load_dotenv
|
|
|
4
4
|
|
|
5
5
|
if __name__ == "__main__":
|
|
6
6
|
load_dotenv()
|
|
7
|
-
messenger = WhatsApp(token=getenv("TOKEN"),
|
|
8
|
-
phone_number_id={1:"1234", 2: "5678"})
|
|
7
|
+
messenger = WhatsApp(token=getenv("TOKEN"), phone_number_id={1: "1234", 2: "5678"})
|
|
9
8
|
|
|
10
9
|
response = messenger.send_video(
|
|
11
10
|
video="https://www.youtube.com/watch?v=K4TOrB7at0Y",
|
|
12
11
|
recipient_id="255757xxxxxx",
|
|
13
|
-
sender=1
|
|
12
|
+
sender=1,
|
|
14
13
|
)
|
|
15
14
|
|
|
16
15
|
print(response)
|
|
@@ -9,8 +9,7 @@ app = Flask(__name__)
|
|
|
9
9
|
|
|
10
10
|
# Load .env file
|
|
11
11
|
load_dotenv("../.env")
|
|
12
|
-
messenger = WhatsApp(os.getenv("TOKEN"),
|
|
13
|
-
phone_number_id=os.getenv("ID"))
|
|
12
|
+
messenger = WhatsApp(os.getenv("TOKEN"), phone_number_id=os.getenv("ID"))
|
|
14
13
|
VERIFY_TOKEN = "30cca545-3838-48b2-80a7-9e43b1ae8ce4"
|
|
15
14
|
|
|
16
15
|
# Logging
|
|
@@ -51,8 +50,7 @@ def hook():
|
|
|
51
50
|
message = msg.content
|
|
52
51
|
name = msg.name
|
|
53
52
|
logging.info("Message: %s", message)
|
|
54
|
-
m = Message(instance=messenger, to=mobile,
|
|
55
|
-
content="Hello World")
|
|
53
|
+
m = Message(instance=messenger, to=mobile, content="Hello World")
|
|
56
54
|
m.send()
|
|
57
55
|
|
|
58
56
|
elif message_type == "interactive":
|
|
@@ -62,8 +60,7 @@ def hook():
|
|
|
62
60
|
interactive_type = message_response.get("type")
|
|
63
61
|
message_id = message_response[interactive_type]["id"]
|
|
64
62
|
message_text = message_response[interactive_type]["title"]
|
|
65
|
-
logging.info(
|
|
66
|
-
f"Interactive Message; {message_id}: {message_text}")
|
|
63
|
+
logging.info(f"Interactive Message; {message_id}: {message_text}")
|
|
67
64
|
|
|
68
65
|
elif message_type == "location":
|
|
69
66
|
message_location = msg.location
|
|
@@ -71,8 +68,7 @@ def hook():
|
|
|
71
68
|
return Response(status=400)
|
|
72
69
|
message_latitude = message_location["latitude"]
|
|
73
70
|
message_longitude = message_location["longitude"]
|
|
74
|
-
logging.info("Location: %s, %s",
|
|
75
|
-
message_latitude, message_longitude)
|
|
71
|
+
logging.info("Location: %s, %s", message_latitude, message_longitude)
|
|
76
72
|
|
|
77
73
|
elif message_type == "image":
|
|
78
74
|
image = msg.image
|
|
@@ -31,7 +31,15 @@ classifiers=[
|
|
|
31
31
|
dynamic = [
|
|
32
32
|
"version"
|
|
33
33
|
]
|
|
34
|
-
dependencies = [
|
|
34
|
+
dependencies = [
|
|
35
|
+
"fastapi",
|
|
36
|
+
"uvicorn",
|
|
37
|
+
"requests",
|
|
38
|
+
"requests_toolbelt",
|
|
39
|
+
"aiohttp",
|
|
40
|
+
"python-dotenv",
|
|
41
|
+
"beautifulsoup4",
|
|
42
|
+
]
|
|
35
43
|
|
|
36
44
|
[project.urls]
|
|
37
45
|
Homepage = "https://github.com/filipporomani/whatsapp-python"
|
|
@@ -41,9 +49,17 @@ Download = "https://github.com/filipporomani/whatsapp-python/releases/latest"
|
|
|
41
49
|
Changelog = "https://github.com/filipporomani/whatsapp-python/releases"
|
|
42
50
|
|
|
43
51
|
|
|
52
|
+
[project.optional-dependencies]
|
|
53
|
+
test = ["pytest>=8.0", "httpx"]
|
|
54
|
+
|
|
44
55
|
[tool.hatch.version]
|
|
45
56
|
path = "whatsapp/constants.py"
|
|
46
57
|
variable = "VERSION"
|
|
47
58
|
|
|
48
59
|
[tool.hatch.build.targets.wheel]
|
|
49
|
-
packages = ["whatsapp"]
|
|
60
|
+
packages = ["whatsapp"]
|
|
61
|
+
|
|
62
|
+
[tool.pytest.ini_options]
|
|
63
|
+
testpaths = ["tests"]
|
|
64
|
+
python_files = ["test_*.py"]
|
|
65
|
+
addopts = "-q"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Manual / live API smoke tests
|
|
2
|
+
|
|
3
|
+
These scripts call the real WhatsApp Cloud API and require environment variables:
|
|
4
|
+
|
|
5
|
+
- `GRAPH_API_TOKEN`
|
|
6
|
+
- `TEST_PHONE_NUMBER_ID`
|
|
7
|
+
- `DEST_PHONE_NUMBER`
|
|
8
|
+
- `TEST_IMAGE_PATH` (async upload smoke only)
|
|
9
|
+
|
|
10
|
+
Run from the repo root after exporting those values:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
python3 tests/manual/sync_smoke.py
|
|
14
|
+
python3 tests/manual/async_smoke.py
|
|
15
|
+
```
|