Skip to content

Commit a21baa5

Browse files
committed
Code review changes
1 parent a40c04d commit a21baa5

5 files changed

Lines changed: 76 additions & 20 deletions

File tree

whatsapp/README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,6 @@ Configure the integration within Autohive using platform authentication for What
8181
## Requirements
8282

8383
- `autohive-integrations-sdk`
84-
- `requests>=2.32.0`
85-
- `aiohttp>=3.8.0`
8684

8785
## Usage Examples
8886

whatsapp/config.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"output_schema": {
3535
"type": "object",
3636
"properties": {
37-
"message_id": {"type": "string"},
37+
"message_id": {"type": ["string", "null"]},
3838
"success": {"type": "boolean"},
3939
"error": {"type": "string"}
4040
},
@@ -76,7 +76,7 @@
7676
"output_schema": {
7777
"type": "object",
7878
"properties": {
79-
"message_id": {"type": "string"},
79+
"message_id": {"type": ["string", "null"]},
8080
"success": {"type": "boolean"},
8181
"error": {"type": "string"}
8282
},
@@ -120,7 +120,7 @@
120120
"output_schema": {
121121
"type": "object",
122122
"properties": {
123-
"message_id": {"type": "string"},
123+
"message_id": {"type": ["string", "null"]},
124124
"success": {"type": "boolean"},
125125
"error": {"type": "string"}
126126
},

whatsapp/requirements.txt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
11
autohive-integrations-sdk~=1.0.2
2-
requests>=2.32.0
3-
aiohttp>=3.8.0

whatsapp/tests/test_whatsapp.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,29 @@ async def test_media_url_validation():
135135
print(f"Error testing media URL validation for {url}: {e}")
136136

137137

138+
async def test_phone_number_id_validation():
139+
"""Test phone number ID validation logic with invalid inputs."""
140+
print("Testing phone number ID validation...")
141+
142+
# Test invalid phone number IDs
143+
invalid_ids = ["abc", "123a", "", " ", "-123"]
144+
145+
# Use a valid phone number to bypass phone validation
146+
valid_phone = "+1234567890"
147+
148+
for pid in invalid_ids:
149+
inputs = {"to": valid_phone, "message": "test", "phone_number_id": pid}
150+
async with ExecutionContext(auth=AUTH) as context:
151+
try:
152+
result = await whatsapp.execute_action("send_message", inputs, context)
153+
print(f"Phone ID {pid}: {result}")
154+
data = result.result.data
155+
assert not data["success"]
156+
assert "Invalid phone number ID" in data["error"]
157+
except Exception as e:
158+
print(f"Error testing phone number ID validation for {pid}: {e}")
159+
160+
138161
async def main():
139162
print("Testing WhatsApp Business Integration")
140163
print("====================================")
@@ -146,7 +169,8 @@ async def main():
146169
"test_send_media_message": test_send_media_message,
147170
"test_get_phone_number_health": test_get_phone_number_health,
148171
"test_phone_validation": test_phone_validation,
149-
"test_media_url_validation": test_media_url_validation
172+
"test_media_url_validation": test_media_url_validation,
173+
"test_phone_number_id_validation": test_phone_number_id_validation
150174
}
151175

152176
# Check for specific test to run from command line args

whatsapp/whatsapp.py

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ def get_whatsapp_creds(auth: Dict[str, Any]) -> Dict[str, str]:
1414
access_token = creds_source.get("access_token") or creds_source.get("accessToken") or creds_source.get("token")
1515

1616
if not access_token:
17-
keys = list(auth.keys())
18-
raise ValueError(f"Missing access_token in auth context. Available keys: {keys}")
17+
raise ValueError(f"Missing access_token in auth context.")
1918

2019
return {
2120
"access_token": access_token
@@ -30,6 +29,10 @@ def validate_media_url(url: str) -> bool:
3029
"""Validate that the media URL is a valid HTTPS URL."""
3130
return url.startswith("https://")
3231

32+
def validate_phone_number_id(phone_number_id: str) -> bool:
33+
"""Validate that the phone number ID is a numeric string."""
34+
return phone_number_id.isdigit()
35+
3336
# ---- Action Handlers ----
3437

3538
@whatsapp.action("send_message")
@@ -42,10 +45,18 @@ async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
4245
message = inputs["message"]
4346
phone_number_id = inputs["phone_number_id"]
4447

48+
# Validate phone number ID
49+
if not validate_phone_number_id(phone_number_id):
50+
return ActionResult(data={
51+
"message_id": None,
52+
"success": False,
53+
"error": "Invalid phone number ID. Must be a numeric string."
54+
})
55+
4556
# Validate phone number format to ensure it meets E.164 standards
4657
if not validate_phone_number(to):
4758
return ActionResult(data={
48-
"message_id": "",
59+
"message_id": None,
4960
"success": False,
5061
"error": "Invalid phone number format. Use format: +1234567890"
5162
})
@@ -79,14 +90,14 @@ async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
7990
else:
8091
# Handle API errors or unexpected response structure
8192
return ActionResult(data={
82-
"message_id": "",
93+
"message_id": None,
8394
"success": False,
8495
"error": response.get("error", {}).get("message", "Unknown error")
8596
})
8697

8798
except Exception as e:
8899
return ActionResult(data={
89-
"message_id": "",
100+
"message_id": None,
90101
"success": False,
91102
"error": f"Failed to send message: {str(e)}"
92103
})
@@ -105,10 +116,18 @@ async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
105116
language_code = inputs.get("language_code", "en")
106117
parameters = inputs.get("parameters", [])
107118

119+
# Validate phone number ID
120+
if not validate_phone_number_id(phone_number_id):
121+
return ActionResult(data={
122+
"message_id": None,
123+
"success": False,
124+
"error": "Invalid phone number ID. Must be a numeric string."
125+
})
126+
108127
# Validate phone number format
109128
if not validate_phone_number(to):
110129
return ActionResult(data={
111-
"message_id": "",
130+
"message_id": None,
112131
"success": False,
113132
"error": "Invalid phone number format. Use format: +1234567890"
114133
})
@@ -153,14 +172,14 @@ async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
153172
})
154173
else:
155174
return ActionResult(data={
156-
"message_id": "",
175+
"message_id": None,
157176
"success": False,
158177
"error": response.get("error", {}).get("message", "Unknown error")
159178
})
160179

161180
except Exception as e:
162181
return ActionResult(data={
163-
"message_id": "",
182+
"message_id": None,
164183
"success": False,
165184
"error": f"Failed to send template message: {str(e)}"
166185
})
@@ -179,18 +198,26 @@ async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
179198
caption = inputs.get("caption", "")
180199
filename = inputs.get("filename", "")
181200

201+
# Validate phone number ID
202+
if not validate_phone_number_id(phone_number_id):
203+
return ActionResult(data={
204+
"message_id": None,
205+
"success": False,
206+
"error": "Invalid phone number ID. Must be a numeric string."
207+
})
208+
182209
# Validate phone number format
183210
if not validate_phone_number(to):
184211
return ActionResult(data={
185-
"message_id": "",
212+
"message_id": None,
186213
"success": False,
187214
"error": "Invalid phone number format. Use format: +1234567890"
188215
})
189216

190217
# Validate media URL
191218
if not validate_media_url(media_url):
192219
return ActionResult(data={
193-
"message_id": "",
220+
"message_id": None,
194221
"success": False,
195222
"error": "Invalid media URL. Must be a publicly accessible HTTPS URL."
196223
})
@@ -237,14 +264,14 @@ async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
237264
})
238265
else:
239266
return ActionResult(data={
240-
"message_id": "",
267+
"message_id": None,
241268
"success": False,
242269
"error": response.get("error", {}).get("message", "Unknown error")
243270
})
244271

245272
except Exception as e:
246273
return ActionResult(data={
247-
"message_id": "",
274+
"message_id": None,
248275
"success": False,
249276
"error": f"Failed to send media message: {str(e)}"
250277
})
@@ -258,6 +285,15 @@ class GetPhoneNumberHealthAction(ActionHandler):
258285
async def execute(self, inputs: Dict[str, Any], context: ExecutionContext):
259286
phone_number_id = inputs["phone_number_id"]
260287

288+
# Validate phone number ID
289+
if not validate_phone_number_id(phone_number_id):
290+
return ActionResult(data={
291+
"status": "UNKNOWN",
292+
"quality_rating": "UNKNOWN",
293+
"success": False,
294+
"error": "Invalid phone number ID. Must be a numeric string."
295+
})
296+
261297
try:
262298
creds = get_whatsapp_creds(context.auth)
263299

0 commit comments

Comments
 (0)