@@ -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