whatsapp-python 3.0.2.post1__py3-none-any.whl
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.
- examples/example_hook_obj.py +85 -0
- examples/reply_to_message_obj.py +14 -0
- examples/sending_audio.py +15 -0
- examples/sending_button.py +33 -0
- examples/sending_document.py +16 -0
- examples/sending_image.py +15 -0
- examples/sending_location.py +18 -0
- examples/sending_message.py +14 -0
- examples/sending_template_message.py +13 -0
- examples/sending_video.py +15 -0
- examples/standalone_hook.py +133 -0
- setup.py +42 -0
- whatsapp/__init__.py +238 -0
- whatsapp/constants.py +3 -0
- whatsapp/ext/_buttons.py +82 -0
- whatsapp/ext/_media.py +135 -0
- whatsapp/ext/_message.py +103 -0
- whatsapp/ext/_property.py +5 -0
- whatsapp/ext/_send_media.py +267 -0
- whatsapp/ext/_send_others.py +86 -0
- whatsapp/ext/_static.py +310 -0
- whatsapp_python-3.0.2.post1.dist-info/METADATA +105 -0
- whatsapp_python-3.0.2.post1.dist-info/RECORD +25 -0
- whatsapp_python-3.0.2.post1.dist-info/WHEEL +4 -0
- whatsapp_python-3.0.2.post1.dist-info/licenses/LICENSE +21 -0
whatsapp/ext/_buttons.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import requests
|
|
3
|
+
from typing import Dict, Any
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def create_button(self, button: Dict[Any, Any]) -> Dict[Any, Any]:
|
|
7
|
+
"""
|
|
8
|
+
Method to create a button object to be used in the send_message method.
|
|
9
|
+
|
|
10
|
+
This is method is designed to only be used internally by the send_button method.
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
button[dict]: A dictionary containing the button data
|
|
14
|
+
"""
|
|
15
|
+
data = {"type": "list", "action": button.get("action")}
|
|
16
|
+
if button.get("header"):
|
|
17
|
+
data["header"] = {"type": "text", "text": button.get("header")}
|
|
18
|
+
if button.get("body"):
|
|
19
|
+
data["body"] = {"text": button.get("body")}
|
|
20
|
+
if button.get("footer"):
|
|
21
|
+
data["footer"] = {"text": button.get("footer")}
|
|
22
|
+
return data
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def send_button(self, button: Dict[Any, Any], recipient_id: str) -> Dict[Any, Any]:
|
|
26
|
+
"""
|
|
27
|
+
Sends an interactive buttons message to a WhatsApp user
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
button[dict]: A dictionary containing the button data(rows-title may not exceed 20 characters)
|
|
31
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
32
|
+
|
|
33
|
+
check https://github.com/Neurotech-HQ/whatsapp#sending-interactive-reply-buttons for an example.
|
|
34
|
+
"""
|
|
35
|
+
data = {
|
|
36
|
+
"messaging_product": "whatsapp",
|
|
37
|
+
"to": recipient_id,
|
|
38
|
+
"type": "interactive",
|
|
39
|
+
"interactive": self.create_button(button),
|
|
40
|
+
}
|
|
41
|
+
logging.info(f"Sending buttons to {recipient_id}")
|
|
42
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
43
|
+
if r.status_code == 200:
|
|
44
|
+
logging.info(f"Buttons sent to {recipient_id}")
|
|
45
|
+
return r.json()
|
|
46
|
+
logging.info(f"Buttons not sent to {recipient_id}")
|
|
47
|
+
logging.info(f"Status code: {r.status_code}")
|
|
48
|
+
logging.info(f"Response: {r.json()}")
|
|
49
|
+
return r.json()
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def send_reply_button(
|
|
53
|
+
self, button: Dict[Any, Any], recipient_id: str
|
|
54
|
+
) -> Dict[Any, Any]:
|
|
55
|
+
"""
|
|
56
|
+
Sends an interactive reply buttons[menu] message to a WhatsApp user
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
button[dict]: A dictionary containing the button data
|
|
60
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
61
|
+
|
|
62
|
+
Note:
|
|
63
|
+
The maximum number of buttons is 3, more than 3 buttons will rise an error.
|
|
64
|
+
"""
|
|
65
|
+
if len(button["action"]["buttons"]) > 3:
|
|
66
|
+
raise ValueError("The maximum number of buttons is 3.")
|
|
67
|
+
|
|
68
|
+
data = {
|
|
69
|
+
"messaging_product": "whatsapp",
|
|
70
|
+
"recipient_type": "individual",
|
|
71
|
+
"to": recipient_id,
|
|
72
|
+
"type": "interactive",
|
|
73
|
+
"interactive": button,
|
|
74
|
+
}
|
|
75
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
76
|
+
if r.status_code == 200:
|
|
77
|
+
logging.info(f"Reply buttons sent to {recipient_id}")
|
|
78
|
+
return r.json()
|
|
79
|
+
logging.info(f"Reply buttons not sent to {recipient_id}")
|
|
80
|
+
logging.info(f"Status code: {r.status_code}")
|
|
81
|
+
logging.info(f"Response: {r.json()}")
|
|
82
|
+
return r.json()
|
whatsapp/ext/_media.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import requests
|
|
3
|
+
import os
|
|
4
|
+
import mimetypes
|
|
5
|
+
from requests_toolbelt.multipart.encoder import MultipartEncoder
|
|
6
|
+
from typing import Union, Dict, Any
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def upload_media(self, media: str) -> Union[Dict[Any, Any], None]:
|
|
10
|
+
"""
|
|
11
|
+
Uploads a media to the cloud api and returns the id of the media
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
media[str]: Path of the media to be uploaded
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> from whatsapp import WhatsApp
|
|
18
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
19
|
+
>>> whatsapp.upload_media("/path/to/media")
|
|
20
|
+
|
|
21
|
+
REFERENCE: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/media#
|
|
22
|
+
"""
|
|
23
|
+
form_data = {
|
|
24
|
+
"file": (
|
|
25
|
+
media,
|
|
26
|
+
open(os.path.realpath(media), "rb"),
|
|
27
|
+
mimetypes.guess_type(media)[0],
|
|
28
|
+
),
|
|
29
|
+
"messaging_product": "whatsapp",
|
|
30
|
+
"type": mimetypes.guess_type(media)[0],
|
|
31
|
+
}
|
|
32
|
+
form_data = MultipartEncoder(fields=form_data)
|
|
33
|
+
headers = self.headers.copy()
|
|
34
|
+
headers["Content-Type"] = form_data.content_type
|
|
35
|
+
logging.info(f"Content-Type: {form_data.content_type}")
|
|
36
|
+
logging.info(f"Uploading media {media}")
|
|
37
|
+
r = requests.post(
|
|
38
|
+
f"{self.base_url}/{self.phone_number_id}/media",
|
|
39
|
+
headers=headers,
|
|
40
|
+
data=form_data,
|
|
41
|
+
)
|
|
42
|
+
if r.status_code == 200:
|
|
43
|
+
logging.info(f"Media {media} uploaded")
|
|
44
|
+
return r.json()
|
|
45
|
+
logging.info(f"Error uploading media {media}")
|
|
46
|
+
logging.info(f"Status code: {r.status_code}")
|
|
47
|
+
logging.info(f"Response: {r.json()}")
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def delete_media(self, media_id: str) -> Union[Dict[Any, Any], None]:
|
|
52
|
+
"""
|
|
53
|
+
Deletes a media from the cloud api
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
media_id[str]: Id of the media to be deleted
|
|
57
|
+
"""
|
|
58
|
+
logging.info(f"Deleting media {media_id}")
|
|
59
|
+
r = requests.delete(
|
|
60
|
+
f"{self.base_url}/{media_id}", headers=self.headers)
|
|
61
|
+
if r.status_code == 200:
|
|
62
|
+
logging.info(f"Media {media_id} deleted")
|
|
63
|
+
return r.json()
|
|
64
|
+
logging.info(f"Error deleting media {media_id}")
|
|
65
|
+
logging.info(f"Status code: {r.status_code}")
|
|
66
|
+
logging.info(f"Response: {r.json()}")
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def query_media_url(self, media_id: str) -> Union[str, None]:
|
|
71
|
+
"""
|
|
72
|
+
Query media url from media id obtained either by manually uploading media or received media
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
media_id[str]: Media id of the media
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
str: Media url
|
|
79
|
+
|
|
80
|
+
Example:
|
|
81
|
+
>>> from whatsapp import WhatsApp
|
|
82
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
83
|
+
>>> whatsapp.query_media_url("media_id")
|
|
84
|
+
"""
|
|
85
|
+
|
|
86
|
+
logging.info(f"Querying media url for {media_id}")
|
|
87
|
+
r = requests.get(f"{self.base_url}/{media_id}", headers=self.headers)
|
|
88
|
+
if r.status_code == 200:
|
|
89
|
+
logging.info(f"Media url queried for {media_id}")
|
|
90
|
+
return r.json()["url"]
|
|
91
|
+
logging.info(f"Media url not queried for {media_id}")
|
|
92
|
+
logging.info(f"Status code: {r.status_code}")
|
|
93
|
+
logging.info(f"Response: {r.json()}")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def download_media(
|
|
98
|
+
self, media_url: str, mime_type: str, file_path: str = "temp"
|
|
99
|
+
) -> Union[str, None]:
|
|
100
|
+
"""
|
|
101
|
+
Download media from media url obtained either by manually uploading media or received media
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
media_url[str]: Media url of the media
|
|
105
|
+
mime_type[str]: Mime type of the media
|
|
106
|
+
file_path[str]: Path of the file to be downloaded to. Default is "temp"
|
|
107
|
+
Do not include the file extension. It will be added automatically.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
str: Media url
|
|
111
|
+
|
|
112
|
+
Example:
|
|
113
|
+
>>> from whatsapp import WhatsApp
|
|
114
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
115
|
+
>>> whatsapp.download_media("media_url", "image/jpeg")
|
|
116
|
+
>>> whatsapp.download_media("media_url", "video/mp4", "path/to/file") #do not include the file extension
|
|
117
|
+
"""
|
|
118
|
+
r = requests.get(media_url, headers=self.headers)
|
|
119
|
+
content = r.content
|
|
120
|
+
extension = mime_type.split("/")[1]
|
|
121
|
+
save_file_here = None
|
|
122
|
+
# create a temporary file
|
|
123
|
+
try:
|
|
124
|
+
|
|
125
|
+
save_file_here = (
|
|
126
|
+
f"{file_path}.{extension}" if file_path else f"temp.{extension}"
|
|
127
|
+
)
|
|
128
|
+
with open(save_file_here, "wb") as f:
|
|
129
|
+
f.write(content)
|
|
130
|
+
logging.info(f"Media downloaded to {save_file_here}")
|
|
131
|
+
return f.name
|
|
132
|
+
except Exception as e:
|
|
133
|
+
logging.info(e)
|
|
134
|
+
logging.error(f"Error downloading media to {save_file_here}")
|
|
135
|
+
return None
|
whatsapp/ext/_message.py
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import requests
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def send_template(self, template: str, recipient_id: str, components: str, lang: str = "en_US") -> dict:
|
|
6
|
+
"""
|
|
7
|
+
Sends a template message to a WhatsApp user, Template messages can either be;
|
|
8
|
+
1. Text template
|
|
9
|
+
2. Media based template
|
|
10
|
+
3. Interactive template
|
|
11
|
+
You can customize the template message by passing a dictionary of components.
|
|
12
|
+
You can find the available components in the documentation.
|
|
13
|
+
https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-message-templates
|
|
14
|
+
Args:
|
|
15
|
+
template[str]: Template name to be sent to the user
|
|
16
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
17
|
+
lang[str]: Language of the template message
|
|
18
|
+
components[list]: List of components to be sent to the user # \
|
|
19
|
+
Example:
|
|
20
|
+
>>> from whatsapp import WhatsApp
|
|
21
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
22
|
+
>>> whatsapp.send_template("hello_world", "5511999999999", lang="en_US"))
|
|
23
|
+
"""
|
|
24
|
+
data = {
|
|
25
|
+
"messaging_product": "whatsapp",
|
|
26
|
+
"to": recipient_id,
|
|
27
|
+
"type": "template",
|
|
28
|
+
"template": {
|
|
29
|
+
"name": template,
|
|
30
|
+
"language": {"code": lang},
|
|
31
|
+
"components": components,
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
logging.info(f"Sending template to {recipient_id}")
|
|
35
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
36
|
+
if r.status_code == 200:
|
|
37
|
+
logging.info(f"Template sent to {recipient_id}")
|
|
38
|
+
return r.json()
|
|
39
|
+
logging.info(f"Template not sent to {recipient_id}")
|
|
40
|
+
logging.info(f"Status code: {r.status_code}")
|
|
41
|
+
logging.error(f"Response: {r.json()}")
|
|
42
|
+
return r.json()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# MESSAGE()
|
|
46
|
+
|
|
47
|
+
def reply(self, reply_text: str = "", preview_url: bool = True) -> dict:
|
|
48
|
+
if self.data == {}:
|
|
49
|
+
return {"error": "No data provided"}
|
|
50
|
+
author = self.instance.get_author(self.data)
|
|
51
|
+
payload = {
|
|
52
|
+
"messaging_product": "whatsapp",
|
|
53
|
+
"recipient_type": "individual",
|
|
54
|
+
"to": str(author),
|
|
55
|
+
"type": "text",
|
|
56
|
+
"context": {"message_id": self.id},
|
|
57
|
+
"text": {"preview_url": preview_url, "body": reply_text},
|
|
58
|
+
}
|
|
59
|
+
logging.info(f"Replying to {self.id}")
|
|
60
|
+
r = requests.post(self.url, headers=self.headers, json=payload)
|
|
61
|
+
if r.status_code == 200:
|
|
62
|
+
logging.info(f"Message sent to {self.instance.get_author(self.data)}")
|
|
63
|
+
return r.json()
|
|
64
|
+
logging.info(f"Message not sent to {self.instance.get_author(self.data)}")
|
|
65
|
+
logging.info(f"Status code: {r.status_code}")
|
|
66
|
+
logging.error(f"Response: {r.json()}")
|
|
67
|
+
return r.json()
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def mark_as_read(self) -> dict:
|
|
71
|
+
payload = {
|
|
72
|
+
"messaging_product": "whatsapp",
|
|
73
|
+
"status": "read",
|
|
74
|
+
"message_id": self.id,
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
response = requests.post(
|
|
78
|
+
f"{self.instance.url}", headers=self.instance.headers, json=payload)
|
|
79
|
+
if response.status_code == 200:
|
|
80
|
+
logging.info(response.json())
|
|
81
|
+
return response.json()
|
|
82
|
+
else:
|
|
83
|
+
logging.error(response.json())
|
|
84
|
+
return response.json()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def send(self, preview_url: bool = True) -> dict:
|
|
88
|
+
data = {
|
|
89
|
+
"messaging_product": "whatsapp",
|
|
90
|
+
"recipient_type": self.rec,
|
|
91
|
+
"to": self.to,
|
|
92
|
+
"type": "text",
|
|
93
|
+
"text": {"preview_url": preview_url, "body": self.content},
|
|
94
|
+
}
|
|
95
|
+
logging.info(f"Sending message to {self.to}")
|
|
96
|
+
r = requests.post(f"{self.url}", headers=self.headers, json=data)
|
|
97
|
+
if r.status_code == 200:
|
|
98
|
+
logging.info(f"Message sent to {self.to}")
|
|
99
|
+
return r.json()
|
|
100
|
+
logging.info(f"Message not sent to {self.to}")
|
|
101
|
+
logging.info(f"Status code: {r.status_code}")
|
|
102
|
+
logging.error(f"Response: {r.json()}")
|
|
103
|
+
return r.json()
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import requests
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def send_location(self, lat: str, long: str, name: str, address: str, recipient_id: str) -> dict:
|
|
6
|
+
"""
|
|
7
|
+
Sends a location message to a WhatsApp user
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
lat[str]: Latitude of the location
|
|
11
|
+
long[str]: Longitude of the location
|
|
12
|
+
name[str]: Name of the location
|
|
13
|
+
address[str]: Address of the location
|
|
14
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
15
|
+
|
|
16
|
+
Example:
|
|
17
|
+
>>> from whatsapp import WhatsApp
|
|
18
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
19
|
+
>>> whatsapp.send_location("-23.564", "-46.654", "My Location", "Rua dois, 123", "5511999999999")
|
|
20
|
+
"""
|
|
21
|
+
data = {
|
|
22
|
+
"messaging_product": "whatsapp",
|
|
23
|
+
"to": recipient_id,
|
|
24
|
+
"type": "location",
|
|
25
|
+
"location": {
|
|
26
|
+
"latitude": lat,
|
|
27
|
+
"longitude": long,
|
|
28
|
+
"name": name,
|
|
29
|
+
"address": address,
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
logging.info(f"Sending location to {recipient_id}")
|
|
33
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
34
|
+
if r.status_code == 200:
|
|
35
|
+
logging.info(f"Location sent to {recipient_id}")
|
|
36
|
+
return r.json()
|
|
37
|
+
logging.info(f"Location not sent to {recipient_id}")
|
|
38
|
+
logging.info(f"Status code: {r.status_code}")
|
|
39
|
+
logging.error(r.json())
|
|
40
|
+
return r.json()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def send_image(
|
|
44
|
+
self,
|
|
45
|
+
image: str,
|
|
46
|
+
recipient_id: str,
|
|
47
|
+
recipient_type: str = "individual",
|
|
48
|
+
caption: str = "",
|
|
49
|
+
link: bool = True,
|
|
50
|
+
) -> dict:
|
|
51
|
+
"""
|
|
52
|
+
Sends an image message to a WhatsApp user
|
|
53
|
+
|
|
54
|
+
There are two ways to send an image message to a user, either by passing the image id or by passing the image link.
|
|
55
|
+
Image id is the id of the image uploaded to the cloud api.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
image[str]: Image id or link of the image
|
|
59
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
60
|
+
recipient_type[str]: Type of the recipient, either individual or group
|
|
61
|
+
caption[str]: Caption of the image
|
|
62
|
+
link[bool]: Whether to send an image id or an image link, True means that the image is an id, False means that the image is a link
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
Example:
|
|
66
|
+
>>> from whatsapp import WhatsApp
|
|
67
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
68
|
+
>>> whatsapp.send_image("https://i.imgur.com/Fh7XVYY.jpeg", "5511999999999")
|
|
69
|
+
"""
|
|
70
|
+
if link:
|
|
71
|
+
data = {
|
|
72
|
+
"messaging_product": "whatsapp",
|
|
73
|
+
"recipient_type": recipient_type,
|
|
74
|
+
"to": recipient_id,
|
|
75
|
+
"type": "image",
|
|
76
|
+
"image": {"link": image, "caption": caption},
|
|
77
|
+
}
|
|
78
|
+
else:
|
|
79
|
+
data = {
|
|
80
|
+
"messaging_product": "whatsapp",
|
|
81
|
+
"recipient_type": recipient_type,
|
|
82
|
+
"to": recipient_id,
|
|
83
|
+
"type": "image",
|
|
84
|
+
"image": {"id": image, "caption": caption},
|
|
85
|
+
}
|
|
86
|
+
logging.info(f"Sending image to {recipient_id}")
|
|
87
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
88
|
+
if r.status_code == 200:
|
|
89
|
+
logging.info(f"Image sent to {recipient_id}")
|
|
90
|
+
return r.json()
|
|
91
|
+
logging.info(f"Image not sent to {recipient_id}")
|
|
92
|
+
logging.info(f"Status code: {r.status_code}")
|
|
93
|
+
logging.error(r.json())
|
|
94
|
+
return r.json()
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def send_sticker(self, sticker: str, recipient_id: str, recipient_type: str = "individual", link: bool = True) -> dict:
|
|
98
|
+
"""
|
|
99
|
+
Sends a sticker message to a WhatsApp user
|
|
100
|
+
|
|
101
|
+
There are two ways to send a sticker message to a user, either by passing the image id or by passing the sticker link.
|
|
102
|
+
Sticker id is the id of the sticker uploaded to the cloud api.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
sticker[str]: Sticker id or link of the sticker
|
|
106
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
107
|
+
recipient_type[str]: Type of the recipient, either individual or group
|
|
108
|
+
link[bool]: Whether to send an sticker id or an sticker link, True means that the sticker is an id, False means that the image is a link
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
Example:
|
|
112
|
+
>>> from whatsapp import WhatsApp
|
|
113
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
114
|
+
>>> whatsapp.send_sticker("170511049062862", "5511999999999", link=False)
|
|
115
|
+
"""
|
|
116
|
+
if link:
|
|
117
|
+
data = {
|
|
118
|
+
"messaging_product": "whatsapp",
|
|
119
|
+
"recipient_type": recipient_type,
|
|
120
|
+
"to": recipient_id,
|
|
121
|
+
"type": "sticker",
|
|
122
|
+
"sticker": {"link": sticker},
|
|
123
|
+
}
|
|
124
|
+
else:
|
|
125
|
+
data = {
|
|
126
|
+
"messaging_product": "whatsapp",
|
|
127
|
+
"recipient_type": recipient_type,
|
|
128
|
+
"to": recipient_id,
|
|
129
|
+
"type": "sticker",
|
|
130
|
+
"sticker": {"id": sticker},
|
|
131
|
+
}
|
|
132
|
+
logging.info(f"Sending sticker to {recipient_id}")
|
|
133
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
134
|
+
if r.status_code == 200:
|
|
135
|
+
logging.info(f"Sticker sent to {recipient_id}")
|
|
136
|
+
return r.json()
|
|
137
|
+
logging.info(f"Sticker not sent to {recipient_id}")
|
|
138
|
+
logging.info(f"Status code: {r.status_code}")
|
|
139
|
+
logging.error(r.json())
|
|
140
|
+
return r.json()
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def send_audio(self, audio: str, recipient_id: str, link: bool = True) -> dict:
|
|
144
|
+
"""
|
|
145
|
+
Sends an audio message to a WhatsApp user
|
|
146
|
+
Audio messages can either be sent by passing the audio id or by passing the audio link.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
audio[str]: Audio id or link of the audio
|
|
150
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
151
|
+
link[bool]: Whether to send an audio id or an audio link, True means that the audio is an id, False means that the audio is a link
|
|
152
|
+
|
|
153
|
+
Example:
|
|
154
|
+
>>> from whatsapp import WhatsApp
|
|
155
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
156
|
+
>>> whatsapp.send_audio("https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3", "5511999999999")
|
|
157
|
+
"""
|
|
158
|
+
if link:
|
|
159
|
+
data = {
|
|
160
|
+
"messaging_product": "whatsapp",
|
|
161
|
+
"to": recipient_id,
|
|
162
|
+
"type": "audio",
|
|
163
|
+
"audio": {"link": audio},
|
|
164
|
+
}
|
|
165
|
+
else:
|
|
166
|
+
data = {
|
|
167
|
+
"messaging_product": "whatsapp",
|
|
168
|
+
"to": recipient_id,
|
|
169
|
+
"type": "audio",
|
|
170
|
+
"audio": {"id": audio},
|
|
171
|
+
}
|
|
172
|
+
logging.info(f"Sending audio to {recipient_id}")
|
|
173
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
174
|
+
if r.status_code == 200:
|
|
175
|
+
logging.info(f"Audio sent to {recipient_id}")
|
|
176
|
+
return r.json()
|
|
177
|
+
logging.info(f"Audio not sent to {recipient_id}")
|
|
178
|
+
logging.info(f"Status code: {r.status_code}")
|
|
179
|
+
logging.error(f"Response: {r.json()}")
|
|
180
|
+
return r.json()
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
def send_video(
|
|
184
|
+
self, video: str, recipient_id: str, caption: str = "", link: bool = True
|
|
185
|
+
) -> dict:
|
|
186
|
+
""" "
|
|
187
|
+
Sends a video message to a WhatsApp user
|
|
188
|
+
Video messages can either be sent by passing the video id or by passing the video link.
|
|
189
|
+
|
|
190
|
+
Args:
|
|
191
|
+
video[str]: Video id or link of the video
|
|
192
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
193
|
+
caption[str]: Caption of the video
|
|
194
|
+
link[bool]: Whether to send a video id or a video link, True means that the video is an id, False means that the video is a link
|
|
195
|
+
|
|
196
|
+
example:
|
|
197
|
+
>>> from whatsapp import WhatsApp
|
|
198
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
199
|
+
>>> whatsapp.send_video("https://www.youtube.com/watch?v=dQw4w9WgXcQ", "5511999999999")
|
|
200
|
+
"""
|
|
201
|
+
if link:
|
|
202
|
+
data = {
|
|
203
|
+
"messaging_product": "whatsapp",
|
|
204
|
+
"to": recipient_id,
|
|
205
|
+
"type": "video",
|
|
206
|
+
"video": {"link": video, "caption": caption},
|
|
207
|
+
}
|
|
208
|
+
else:
|
|
209
|
+
data = {
|
|
210
|
+
"messaging_product": "whatsapp",
|
|
211
|
+
"to": recipient_id,
|
|
212
|
+
"type": "video",
|
|
213
|
+
"video": {"id": video, "caption": caption},
|
|
214
|
+
}
|
|
215
|
+
logging.info(f"Sending video to {recipient_id}")
|
|
216
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
217
|
+
if r.status_code == 200:
|
|
218
|
+
logging.info(f"Video sent to {recipient_id}")
|
|
219
|
+
return r.json()
|
|
220
|
+
logging.info(f"Video not sent to {recipient_id}")
|
|
221
|
+
logging.info(f"Status code: {r.status_code}")
|
|
222
|
+
logging.error(f"Response: {r.json()}")
|
|
223
|
+
return r.json()
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def send_document(
|
|
227
|
+
self, document: str, recipient_id: str, caption: str = "", link: bool = True
|
|
228
|
+
) -> dict:
|
|
229
|
+
""" "
|
|
230
|
+
Sends a document message to a WhatsApp user
|
|
231
|
+
Document messages can either be sent by passing the document id or by passing the document link.
|
|
232
|
+
|
|
233
|
+
Args:
|
|
234
|
+
document[str]: Document id or link of the document
|
|
235
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
236
|
+
caption[str]: Caption of the document
|
|
237
|
+
link[bool]: Whether to send a document id or a document link, True means that the document is an id, False means that the document is a link
|
|
238
|
+
|
|
239
|
+
Example:
|
|
240
|
+
>>> from whatsapp import WhatsApp
|
|
241
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
242
|
+
>>> whatsapp.send_document("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf", "5511999999999")
|
|
243
|
+
"""
|
|
244
|
+
if link:
|
|
245
|
+
data = {
|
|
246
|
+
"messaging_product": "whatsapp",
|
|
247
|
+
"to": recipient_id,
|
|
248
|
+
"type": "document",
|
|
249
|
+
"document": {"link": document, "caption": caption},
|
|
250
|
+
}
|
|
251
|
+
else:
|
|
252
|
+
data = {
|
|
253
|
+
"messaging_product": "whatsapp",
|
|
254
|
+
"to": recipient_id,
|
|
255
|
+
"type": "document",
|
|
256
|
+
"document": {"id": document, "caption": caption},
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
logging.info(f"Sending document to {recipient_id}")
|
|
260
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
261
|
+
if r.status_code == 200:
|
|
262
|
+
logging.info(f"Document sent to {recipient_id}")
|
|
263
|
+
return r.json()
|
|
264
|
+
logging.info(f"Document not sent to {recipient_id}")
|
|
265
|
+
logging.info(f"Status code: {r.status_code}")
|
|
266
|
+
logging.error(f"Response: {r.json()}")
|
|
267
|
+
return r.json()
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
from typing import Any, Dict, List
|
|
2
|
+
import requests
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def send_custom_json(self, data: dict, recipient_id: str = ""):
|
|
7
|
+
"""
|
|
8
|
+
Sends a custom json to a WhatsApp user. This can be used to send custom objects to the message endpoint.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
data[dict]: Dictionary that should be send
|
|
12
|
+
recipient_id[str]: Phone number of the user with country code wihout +
|
|
13
|
+
Example:
|
|
14
|
+
>>> from whatsapp import WhatsApp
|
|
15
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
16
|
+
>>> whatsapp.send_custom_json({
|
|
17
|
+
"messaging_product": "whatsapp",
|
|
18
|
+
"type": "audio",
|
|
19
|
+
"audio": {"id": audio}}, "5511999999999")
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
if recipient_id:
|
|
23
|
+
if "to" in data.keys():
|
|
24
|
+
data_recipient_id = data["to"]
|
|
25
|
+
logging.info(
|
|
26
|
+
f"Recipient Id is defined in data ({data_recipient_id}) and recipient_id parameter ({recipient_id})")
|
|
27
|
+
else:
|
|
28
|
+
data["to"] = recipient_id
|
|
29
|
+
|
|
30
|
+
logging.info(f"Sending custom json to {recipient_id}")
|
|
31
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
32
|
+
if r.status_code == 200:
|
|
33
|
+
logging.info(f"Custom json sent to {recipient_id}")
|
|
34
|
+
return r.json()
|
|
35
|
+
logging.info(f"Custom json not sent to {recipient_id}")
|
|
36
|
+
logging.info(f"Status code: {r.status_code}")
|
|
37
|
+
logging.error(f"Response: {r.json()}")
|
|
38
|
+
return r.json()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def send_contacts(
|
|
42
|
+
self, contacts: List[Dict[Any, Any]], recipient_id: str
|
|
43
|
+
) -> Dict[Any, Any]:
|
|
44
|
+
"""send_contacts
|
|
45
|
+
|
|
46
|
+
Send a list of contacts to a user
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
contacts(List[Dict[Any, Any]]): List of contacts to send
|
|
50
|
+
recipient_id(str): Phone number of the user with country code wihout +
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
>>> from whatsapp import WhatsApp
|
|
54
|
+
>>> whatsapp = WhatsApp(token, phone_number_id)
|
|
55
|
+
>>> contacts = [{
|
|
56
|
+
"addresses": [{
|
|
57
|
+
"street": "STREET",
|
|
58
|
+
"city": "CITY",
|
|
59
|
+
"state": "STATE",
|
|
60
|
+
"zip": "ZIP",
|
|
61
|
+
"country": "COUNTRY",
|
|
62
|
+
"country_code": "COUNTRY_CODE",
|
|
63
|
+
"type": "HOME"
|
|
64
|
+
},
|
|
65
|
+
....
|
|
66
|
+
}
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
REFERENCE: https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#contacts-object
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
data = {
|
|
73
|
+
"messaging_product": "whatsapp",
|
|
74
|
+
"to": recipient_id,
|
|
75
|
+
"type": "contacts",
|
|
76
|
+
"contacts": contacts,
|
|
77
|
+
}
|
|
78
|
+
logging.info(f"Sending contacts to {recipient_id}")
|
|
79
|
+
r = requests.post(self.url, headers=self.headers, json=data)
|
|
80
|
+
if r.status_code == 200:
|
|
81
|
+
logging.info(f"Contacts sent to {recipient_id}")
|
|
82
|
+
return r.json()
|
|
83
|
+
logging.info(f"Contacts not sent to {recipient_id}")
|
|
84
|
+
logging.info(f"Status code: {r.status_code}")
|
|
85
|
+
logging.error(f"Response: {r.json()}")
|
|
86
|
+
return r.json()
|