@@ -20,6 +20,8 @@ class RequestType(str, Enum):
2020
2121 SMS = 'SMS'
2222 DELIVERY_REQUEST = 'DELIVERY_REQUEST'
23+ VOICE_MESSAGE = 'VOICE_MESSAGE'
24+ VOICE_MESSAGE_DELIVERY_REQUEST = 'VOICE_MESSAGE_DELIVERY_REQUEST'
2325
2426
2527class SmsOperatorState (IntegerChoicesEnum ):
@@ -55,9 +57,12 @@ class SMSOperatorSendingError(Exception):
5557 pass
5658
5759 TEMPLATES = {
58- 'base' : 'pymess/sms/sms_operator/base.xml' ,
60+ 'base_sms' : 'pymess/sms/sms_operator/base_sms.xml' ,
61+ 'base_voice' : 'pymess/sms/sms_operator/base_voice.xml' ,
5962 RequestType .SMS : 'pymess/sms/sms_operator/sms.xml' ,
60- RequestType .DELIVERY_REQUEST : 'pymess/sms/sms_operator/delivery_request.xml' ,
63+ RequestType .DELIVERY_REQUEST : 'pymess/sms/sms_operator/sms_delivery_request.xml' ,
64+ RequestType .VOICE_MESSAGE : 'pymess/sms/sms_operator/voice.xml' ,
65+ RequestType .VOICE_MESSAGE_DELIVERY_REQUEST : 'pymess/sms/sms_operator/voice_delivery_request.xml' ,
6166 }
6267
6368 SMS_OPERATOR_STATES_MAPPING = {
@@ -78,11 +83,19 @@ class SMSOperatorSendingError(Exception):
7883 }
7984
8085 config = {
81- 'URL' : 'https://www.sms-operator.cz/webservices/webservice.aspx' ,
86+ 'SMS_URL' : 'https://www.sms-operator.cz/webservices/webservice.aspx' ,
87+ 'VOICE_URL' : 'https://www.sms-operator.cz/webservices/voice.ashx' ,
8288 'UNIQ_PREFIX' : '' ,
8389 'TIMEOUT' : 5 , # 5s
8490 }
8591
92+ URLS = {
93+ RequestType .SMS : 'SMS_URL' ,
94+ RequestType .DELIVERY_REQUEST : 'SMS_URL' ,
95+ RequestType .VOICE_MESSAGE : 'VOICE_URL' ,
96+ RequestType .VOICE_MESSAGE_DELIVERY_REQUEST : 'VOICE_URL' ,
97+ }
98+
8699 def _get_extra_sender_data (self ):
87100 return {
88101 'prefix' : self .config ['UNIQ_PREFIX' ],
@@ -95,14 +108,22 @@ def _serialize_messages(self, messages, request_type):
95108 :param request_type: type of the request to the SMS operator
96109 :return: serialized XML message that will be sent to the SMS operator service
97110 """
111+ # Determine the base template and type based on request type
112+ if request_type in [RequestType .VOICE_MESSAGE , RequestType .VOICE_MESSAGE_DELIVERY_REQUEST ]:
113+ base_template = self .TEMPLATES ['base_voice' ]
114+ type_value = 'Voice' if request_type == RequestType .VOICE_MESSAGE else 'Voice-Status'
115+ else :
116+ base_template = self .TEMPLATES ['base_sms' ]
117+ type_value = 'SMS' if request_type == RequestType .SMS else 'SMS-Status'
118+
98119 return render_to_string (
99- self . TEMPLATES [ 'base' ] , {
120+ base_template , {
100121 'username' : self .config ['USERNAME' ],
101122 'password' : self .config ['PASSWORD' ],
102123 'prefix' : str (self .config ['UNIQ_PREFIX' ]) + '-' ,
103124 'template_type' : self .TEMPLATES [request_type ],
104125 'messages' : messages ,
105- 'type' : 'SMS' if request_type == RequestType . SMS else 'SMS-Status' ,
126+ 'type' : type_value ,
106127 }
107128 )
108129
@@ -115,9 +136,12 @@ def _send_requests(self, messages, request_type, is_sending=False, **change_sms_
115136 :param change_sms_kwargs: extra kwargs that will be stored to the message object
116137 """
117138 requests_xml = self ._serialize_messages (messages , request_type )
139+ url_key = self .URLS [request_type ]
140+ url = self .config [url_key ]
141+
118142 try :
119143 resp = generate_session (slug = 'pymess - SMS operator' , related_objects = list (messages )).post (
120- self . config [ 'URL' ] ,
144+ url ,
121145 data = requests_xml ,
122146 headers = {'Content-Type' : 'text/xml' },
123147 timeout = self .config ['TIMEOUT' ]
@@ -189,9 +213,10 @@ def _update_sms_states_from_response(self, messages, parsed_response, is_sending
189213
190214 def publish_message (self , message ):
191215 try :
216+ request_type = RequestType .VOICE_MESSAGE if getattr (message , 'is_voice_message' , False ) else RequestType .SMS
192217 self ._send_requests (
193218 [message ],
194- request_type = RequestType . SMS . value ,
219+ request_type = request_type ,
195220 is_sending = True ,
196221 sent_at = timezone .now ()
197222 )
@@ -210,7 +235,25 @@ def publish_message(self, message):
210235 # about exception).
211236
212237 def publish_messages (self , messages ):
213- self ._send_requests (messages , request_type = RequestType .SMS , is_sending = True , sent_at = timezone .now ())
238+ sent_at = timezone .now ()
239+ voice_messages = [message for message in messages if getattr (message , 'is_voice_message' , False )]
240+ sms_messages = [message for message in messages if not getattr (message , 'is_voice_message' , False )]
241+
242+ if voice_messages :
243+ self ._send_requests (
244+ voice_messages ,
245+ request_type = RequestType .VOICE_MESSAGE ,
246+ is_sending = True ,
247+ sent_at = sent_at
248+ )
249+
250+ if sms_messages :
251+ self ._send_requests (
252+ sms_messages ,
253+ request_type = RequestType .SMS ,
254+ is_sending = True ,
255+ sent_at = sent_at
256+ )
214257
215258 def _parse_response_codes (self , xml ):
216259 """
@@ -222,8 +265,23 @@ def _parse_response_codes(self, xml):
222265
223266 soup = BeautifulSoup (xml , 'html.parser' )
224267
225- return {int (item .smsid .string .lstrip (self .config ['UNIQ_PREFIX' ] + '-' )): SmsOperatorState (int (item .status .string ))
226- for item in soup .find_all ('dataitem' )}
268+ result = {}
269+ for item in soup .find_all ('dataitem' ):
270+ # Try to get the ID from either smsid or msgid tags (for voice messages)
271+ id_tag = item .smsid if item .smsid else item .msgid
272+ if id_tag :
273+ message_id = int (id_tag .string .lstrip (self .config ['UNIQ_PREFIX' ] + '-' ))
274+ status = SmsOperatorState (int (item .status .string ))
275+ result [message_id ] = status
276+
277+ return result
227278
228279 def update_sms_states (self , messages ):
229- self ._send_requests (messages , request_type = RequestType .DELIVERY_REQUEST )
280+ voice_messages = [message for message in messages if getattr (message , 'is_voice_message' , False )]
281+ sms_messages = [message for message in messages if not getattr (message , 'is_voice_message' , False )]
282+
283+ if voice_messages :
284+ self ._send_requests (voice_messages , request_type = RequestType .VOICE_MESSAGE_DELIVERY_REQUEST )
285+
286+ if sms_messages :
287+ self ._send_requests (sms_messages , request_type = RequestType .DELIVERY_REQUEST )
0 commit comments