whatsapp-python 3.3.5.dev0__py3-none-any.whl → 3.3.9__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.
whatsapp/constants.py CHANGED
@@ -1,4 +1,4 @@
1
- # This file contains the constants used in the project.
2
- # The VERSION constant is used to store the version of the project - it's not only used in the __init__.py file, but also in the pyproject.toml file.
3
-
4
- VERSION = "3.3.5.dev0"
1
+ # This file contains the constants used in the project.
2
+ # The VERSION constant is used to store the version of the project - it's not only used in the __init__.py file, but also in the pyproject.toml file.
3
+
4
+ VERSION = "3.3.9"
whatsapp/ext/_buttons.py CHANGED
@@ -1,82 +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()
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 CHANGED
@@ -1,135 +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.debug(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
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.debug(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