o
    ×èFhöV  ã                   @   s´  d Z ddlZddlZddlZddlZddlmZ ddlmZ ddl	Z	ddl	m
Z
 ddl	mZ ddl	mZ ddl	mZ dd	l	mZ dd
l	mZ dZg d¢ZejZejZejZejZejZejZejZejZejZejZejZejZejZejZej Z ej!Z!ej"Z"ej#Z#ej$Z$ej%Z%ej&Z&ej'Z'dd„ Z(d(dd„Z)d(dd„Z*d(dd„Z+d(dd„Z,d(dd„Z-d)dd„Z.d)dd„Z/G dd„ dƒZ0G d d!„ d!ƒZ1G d"d#„ d#ƒZ2G d$d%„ d%ƒZ3G d&d'„ d'ƒZ4dS )*z Firebase Cloud Messaging module.é    N)Úhttp)Ú_auth)Ú_http_client)Ú_messaging_encoder)Ú_messaging_utils)Ú_gapic_utils)Ú_utils)Ú
exceptionsÚ
_messaging)!ÚAndroidConfigÚAndroidFCMOptionsÚAndroidNotificationÚ
APNSConfigÚAPNSFCMOptionsÚAPNSPayloadÚApsÚApsAlertÚBatchResponseÚCriticalSoundÚ	ErrorInfoÚ
FCMOptionsÚLightSettingsÚMessageÚMulticastMessageÚNotificationÚQuotaExceededErrorÚSenderIdMismatchErrorÚSendResponseÚThirdPartyAuthErrorÚTopicManagementResponseÚUnregisteredErrorÚWebpushConfigÚWebpushFCMOptionsÚWebpushNotificationÚWebpushNotificationActionÚsendÚsend_allÚsend_multicastÚ	send_eachÚsend_each_for_multicastÚsubscribe_to_topicÚunsubscribe_from_topicc                 C   s   t  | tt¡S ©N)r   Úget_app_serviceÚ_MESSAGING_ATTRIBUTEÚ_MessagingService)Úapp© r1   úQ/var/www/html/loop/nvenv/lib/python3.10/site-packages/firebase_admin/messaging.pyÚ_get_messaging_serviced   s   r3   Fc                 C   ó   t |ƒ | |¡S )aÀ  Sends the given message via Firebase Cloud Messaging (FCM).

    If the ``dry_run`` mode is enabled, the message will not be actually delivered to the
    recipients. Instead FCM performs all the usual validations, and emulates the send operation.

    Args:
        message: An instance of ``messaging.Message``.
        dry_run: A boolean indicating whether to run the operation in dry run mode (optional).
        app: An App instance (optional).

    Returns:
        string: A message ID string that uniquely identifies the sent message.

    Raises:
        FirebaseError: If an error occurs while sending the message to the FCM service.
        ValueError: If the input arguments are invalid.
    )r3   r%   )ÚmessageÚdry_runr0   r1   r1   r2   r%   g   ó   r%   c                 C   r4   )a½  Sends each message in the given list via Firebase Cloud Messaging.

    If the ``dry_run`` mode is enabled, the message will not be actually delivered to the
    recipients. Instead FCM performs all the usual validations, and emulates the send operation.

    Args:
        messages: A list of ``messaging.Message`` instances.
        dry_run: A boolean indicating whether to run the operation in dry run mode (optional).
        app: An App instance (optional).

    Returns:
        BatchResponse: A ``messaging.BatchResponse`` instance.

    Raises:
        FirebaseError: If an error occurs while sending the message to the FCM service.
        ValueError: If the input arguments are invalid.
    )r3   r(   ©Úmessagesr6   r0   r1   r1   r2   r(   {   r7   r(   c                    s6   t ˆ tƒs	tdƒ‚‡ fdd„ˆ jD ƒ}t|ƒ ||¡S )aÛ  Sends the given mutlicast message to each token via Firebase Cloud Messaging (FCM).

    If the ``dry_run`` mode is enabled, the message will not be actually delivered to the
    recipients. Instead FCM performs all the usual validations, and emulates the send operation.

    Args:
        multicast_message: An instance of ``messaging.MulticastMessage``.
        dry_run: A boolean indicating whether to run the operation in dry run mode (optional).
        app: An App instance (optional).

    Returns:
        BatchResponse: A ``messaging.BatchResponse`` instance.

    Raises:
        FirebaseError: If an error occurs while sending the message to the FCM service.
        ValueError: If the input arguments are invalid.
    ú@Message must be an instance of messaging.MulticastMessage class.c                    ó.   g | ]}t ˆ jˆ jˆ jˆ jˆ jˆ j|d �‘qS ©)ÚdataÚnotificationÚandroidÚwebpushÚapnsÚfcm_optionsÚtoken©r   r=   r>   r?   r@   rA   rB   ©Ú.0rC   ©Úmulticast_messager1   r2   Ú
<listcomp>£   ó    ø
ùz+send_each_for_multicast.<locals>.<listcomp>)Ú
isinstancer   Ú
ValueErrorÚtokensr3   r(   ©rH   r6   r0   r9   r1   rG   r2   r)   �   s   

ø	r)   c                 C   s   t  dt¡ t|ƒ | |¡S )a  Sends the given list of messages via Firebase Cloud Messaging as a single batch.

    If the ``dry_run`` mode is enabled, the message will not be actually delivered to the
    recipients. Instead FCM performs all the usual validations, and emulates the send operation.

    Args:
        messages: A list of ``messaging.Message`` instances.
        dry_run: A boolean indicating whether to run the operation in dry run mode (optional).
        app: An App instance (optional).

    Returns:
        BatchResponse: A ``messaging.BatchResponse`` instance.

    Raises:
        FirebaseError: If an error occurs while sending the message to the FCM service.
        ValueError: If the input arguments are invalid.

    send_all() is deprecated. Use send_each() instead.
    z2send_all() is deprecated. Use send_each() instead.)ÚwarningsÚwarnÚDeprecationWarningr3   r&   r8   r1   r1   r2   r&   ®   s   r&   c                    sB   t  dt¡ tˆ tƒstdƒ‚‡ fdd„ˆ jD ƒ}t|ƒ ||¡S )a'  Sends the given mutlicast message to all tokens via Firebase Cloud Messaging (FCM).

    If the ``dry_run`` mode is enabled, the message will not be actually delivered to the
    recipients. Instead FCM performs all the usual validations, and emulates the send operation.

    Args:
        multicast_message: An instance of ``messaging.MulticastMessage``.
        dry_run: A boolean indicating whether to run the operation in dry run mode (optional).
        app: An App instance (optional).

    Returns:
        BatchResponse: A ``messaging.BatchResponse`` instance.

    Raises:
        FirebaseError: If an error occurs while sending the message to the FCM service.
        ValueError: If the input arguments are invalid.

    send_multicast() is deprecated. Use send_each_for_multicast() instead.
    zFsend_multicast() is deprecated. Use send_each_for_multicast() instead.r:   c                    r;   r<   rD   rE   rG   r1   r2   rI   Ý   rJ   z"send_multicast.<locals>.<listcomp>)	rO   rP   rQ   rK   r   rL   rM   r3   r&   rN   r1   rG   r2   r'   Å   s   ÿ

ø	r'   c                 C   ó   t |ƒ | |d¡S )a4  Subscribes a list of registration tokens to an FCM topic.

    Args:
        tokens: A non-empty list of device registration tokens. List may not have more than 1000
            elements.
        topic: Name of the topic to subscribe to. May contain the ``/topics/`` prefix.
        app: An App instance (optional).

    Returns:
        TopicManagementResponse: A ``TopicManagementResponse`` instance.

    Raises:
        FirebaseError: If an error occurs while communicating with instance ID service.
        ValueError: If the input arguments are invalid.
    ziid/v1:batchAdd©r3   Úmake_topic_management_request©rM   Útopicr0   r1   r1   r2   r*   è   ó   ÿr*   c                 C   rR   )a<  Unsubscribes a list of registration tokens from an FCM topic.

    Args:
        tokens: A non-empty list of device registration tokens. List may not have more than 1000
            elements.
        topic: Name of the topic to unsubscribe from. May contain the ``/topics/`` prefix.
        app: An App instance (optional).

    Returns:
        TopicManagementResponse: A ``TopicManagementResponse`` instance.

    Raises:
        FirebaseError: If an error occurs while communicating with instance ID service.
        ValueError: If the input arguments are invalid.
    ziid/v1:batchRemoverS   rU   r1   r1   r2   r+   û   rW   r+   c                   @   s0   e Zd ZdZdd„ Zedd„ ƒZedd„ ƒZdS )	r   zBAn error encountered when performing a topic management operation.c                 C   s   || _ || _d S r,   )Ú_indexÚ_reason)ÚselfÚindexÚreasonr1   r1   r2   Ú__init__  s   
zErrorInfo.__init__c                 C   ó   | j S )zBIndex of the registration token to which this error is related to.)rX   ©rZ   r1   r1   r2   r[     ó   zErrorInfo.indexc                 C   r^   )z*String describing the nature of the error.)rY   r_   r1   r1   r2   r\     r`   zErrorInfo.reasonN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r]   Úpropertyr[   r\   r1   r1   r1   r2   r     s    
r   c                   @   ó<   e Zd ZdZdd„ Zedd„ ƒZedd„ ƒZedd	„ ƒZd
S )r   z8The response received from a topic management operation.c                 C   sˆ   t |tƒr	d|vrtd |¡ƒ‚d| _d| _g | _t|d ƒD ]"\}}d|v r:|  jd7  _| j t	||d ƒ¡ q|  jd7  _qd S )NÚresultsz*Unexpected topic management response: {0}.r   Úerroré   )
rK   ÚdictrL   ÚformatÚ_success_countÚ_failure_countÚ_errorsÚ	enumerateÚappendr   )rZ   Úrespr[   Úresultr1   r1   r2   r]   $  s   ûz TopicManagementResponse.__init__c                 C   r^   )zCNumber of tokens that were successfully subscribed or unsubscribed.©rl   r_   r1   r1   r2   Úsuccess_count1  r`   z%TopicManagementResponse.success_countc                 C   r^   )zLNumber of tokens that could not be subscribed or unsubscribed due to errors.)rm   r_   r1   r1   r2   Úfailure_count6  r`   z%TopicManagementResponse.failure_countc                 C   r^   )z;A list of ``messaging.ErrorInfo`` objects (possibly empty).)rn   r_   r1   r1   r2   Úerrors;  r`   zTopicManagementResponse.errorsN)	ra   rb   rc   rd   r]   re   rt   ru   rv   r1   r1   r1   r2   r   !  s    

r   c                   @   rf   )r   z:The response received from a batch request to the FCM API.c                 C   s   || _ tdd„ |D ƒƒ| _d S )Nc                 S   s   g | ]}|j r|‘qS r1   )Úsuccess©rF   rq   r1   r1   r2   rI   F  s    z*BatchResponse.__init__.<locals>.<listcomp>)Ú
_responsesÚlenrl   )rZ   Ú	responsesr1   r1   r2   r]   D  s   zBatchResponse.__init__c                 C   r^   )z>A list of ``messaging.SendResponse`` objects (possibly empty).)ry   r_   r1   r1   r2   r{   H  r`   zBatchResponse.responsesc                 C   r^   r,   rs   r_   r1   r1   r2   rt   M  s   zBatchResponse.success_countc                 C   s   t | jƒ| j S r,   )rz   r{   rt   r_   r1   r1   r2   ru   Q  s   zBatchResponse.failure_countN)	ra   rb   rc   rd   r]   re   r{   rt   ru   r1   r1   r1   r2   r   A  s    

r   c                   @   rf   )r   zHThe response received from an individual batched request to the FCM API.c                 C   s&   || _ d | _|r| dd ¡| _d S d S )NÚname)Ú
_exceptionÚ_message_idÚget)rZ   rq   Ú	exceptionr1   r1   r2   r]   Y  s
   ÿzSendResponse.__init__c                 C   r^   )z9A message ID string that uniquely identifies the message.)r~   r_   r1   r1   r2   Ú
message_id_  r`   zSendResponse.message_idc                 C   s   | j duo| j S )z3A boolean indicating if the request was successful.N)r~   r}   r_   r1   r1   r2   rw   d  s   zSendResponse.successc                 C   r^   )zTA ``FirebaseError`` if an error occurs while sending the message to the FCM service.)r}   r_   r1   r1   r2   r€   i  r`   zSendResponse.exceptionN)	ra   rb   rc   rd   r]   re   r�   rw   r€   r1   r1   r1   r2   r   V  s    

r   c                   @   sÂ   e Zd ZdZdZdZdZddiZe 	¡ Z
eeeeedœZdd	„ Zed
d„ ƒZd&dd„Zd&dd„Zd&dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zedd „ ƒZed!d"„ ƒZed#d$„ ƒZd%S )'r/   zKService class that implements Firebase Cloud Messaging (FCM) functionality.z8https://fcm.googleapis.com/v1/projects/{0}/messages:sendz https://fcm.googleapis.com/batchzhttps://iid.googleapis.comÚaccess_token_authÚtrue)ÚAPNS_AUTH_ERRORÚQUOTA_EXCEEDEDÚSENDER_ID_MISMATCHÚTHIRD_PARTY_AUTH_ERRORÚUNREGISTEREDc                 C   sn   |j }|s	tdƒ‚tj |¡| _dd tj¡dœ| _|j	 
dtj¡}|j ¡ | _tj| j|d�| _tj| _d S )NzÀProject ID is required to access Cloud Messaging service. Either set the projectId option, or use service account credentials. Alternatively, set the GOOGLE_CLOUD_PROJECT environment variable.Ú2zfire-admin-python/{0})zX-GOOG-API-FORMAT-VERSIONzX-FIREBASE-CLIENTÚhttpTimeout)Ú
credentialÚtimeout)Ú
project_idrL   r/   ÚFCM_URLrk   Ú_fcm_urlÚfirebase_adminÚ__version__Ú_fcm_headersÚoptionsr   r   ÚDEFAULT_TIMEOUT_SECONDSr‹   Úget_credentialÚ_credentialÚJsonHttpClientÚ_clientr   Úauthorized_httpÚ_build_transport)rZ   r0   r�   rŒ   r1   r1   r2   r]   €  s   ÿ
þz_MessagingService.__init__c                 C   s   t |tƒs	tdƒ‚| j |¡S )Nz7Message must be an instance of messaging.Message class.)rK   r   rL   ÚJSON_ENCODERÚdefault)Úclsr5   r1   r1   r2   Úencode_message‘  s   
z _MessagingService.encode_messageFc              
   C   sV   |   ||¡}z| jjd| j| j|d�}W |d S  tjjy* } z|  |¡‚d}~ww )z2Sends the given message to FCM via the FCM v1 API.Úpost©ÚurlÚheadersÚjsonNr|   )	Ú_message_datar˜   Úbodyr�   r’   Úrequestsr	   ÚRequestExceptionÚ_handle_fcm_error)rZ   r5   r6   r=   rq   rh   r1   r1   r2   r%   —  s   ü	ý
€ÿz_MessagingService.sendc              
      sÌ   t |tƒs	tdƒ‚t|ƒdkrtdƒ‚‡fdd„}‡ ‡fdd„|D ƒ}z,tjjt|ƒd��}d	d„ | ||¡D ƒ}t|ƒW  d
  ƒ W S 1 sHw   Y  W d
S  t	ye } z
t
jd |¡|d�‚d
}~ww )z3Sends the given messages to FCM via the FCM v1 API.ú7messages must be a list of messaging.Message instances.éô  ú1messages must not contain more than 500 elements.c              
      sd   zˆ j jdˆ jˆ j| d�}W n tjjy+ } ztd ˆ  |¡d�W  Y d }~S d }~ww t|d d�S )NrŸ   r    )rq   r€   )r€   )	r˜   r¥   r�   r’   r¦   r	   r§   r   r¨   )r=   rq   r€   r_   r1   r2   Ú	send_data­  s   
ü€ÿz._MessagingService.send_each.<locals>.send_datac                    s   g | ]}ˆ  |ˆ ¡‘qS r1   )r¤   )rF   r5   ©r6   rZ   r1   r2   rI   ¹  s    z/_MessagingService.send_each.<locals>.<listcomp>)Úmax_workersc                 S   s   g | ]}|‘qS r1   r1   rx   r1   r1   r2   rI   ¼  s    Nz4Unknown error while making remote service calls: {0})r5   Úcause)rK   ÚlistrL   rz   Ú
concurrentÚfuturesÚThreadPoolExecutorÚmapr   Ú	Exceptionr	   ÚUnknownErrorrk   )rZ   r9   r6   r¬   Úmessage_dataÚexecutorr{   rh   r1   r­   r2   r(   ¦  s$   
(þþ€ÿz_MessagingService.send_eachc           
   
      sÌ   t |tƒs	tdƒ‚t|ƒdkrtdƒ‚g ‰ ‡ ‡fdd„}tj|tjd�}ˆ ˆj	¡}|D ]}t
 ˆ ||¡¡}tj|ˆjˆjd|ˆjd�}| |¡ q,z	| ¡  W tˆ ƒS  tye }	 zˆ |	¡‚d	}	~	ww )
z2Sends the given messages to FCM via the batch API.r©   rª   r«   c                    s*   d }|r	ˆ  |¡}t||ƒ}ˆ  |¡ d S r,   )Ú_handle_batch_errorr   rp   )Ú_Úresponserh   r€   Úsend_response©r{   rZ   r1   r2   Úbatch_callbackÌ  s
   

z2_MessagingService.send_all.<locals>.batch_callback)ÚcallbackÚ	batch_uriÚPOST)r   ÚpostprocÚuriÚmethodr¥   r¢   N)rK   r°   rL   rz   r   ÚBatchHttpRequestr/   ÚFCM_BATCH_URLrš   r–   r£   Údumpsr¤   ÚHttpRequestÚ	_postprocr�   r’   ÚaddÚexecuterµ   r¹   r   )
rZ   r9   r6   r¾   ÚbatchÚ	transportr5   r¥   Úreqrh   r1   r½   r2   r&   Ã  s8   
ÿú
ý
€ÿz_MessagingService.send_allc           	   
   C   sÊ   t |tƒr|g}t |tƒr|stdƒ‚dd„ |D ƒ}|r tdƒ‚t |tƒr'|s+tdƒ‚| d¡s5d |¡}||dœ}d	 tj|¡}z| jj	d
||tj
d�}W t|ƒS  tjjyd } z|  |¡‚d}~ww )z;Invokes the IID service for topic management functionality.z7Tokens must be a string or a non-empty list of strings.c                 S   s   g | ]}t |tƒr|s|‘qS r1   )rK   Ústr)rF   Útr1   r1   r2   rI   ï  s    zC_MessagingService.make_topic_management_request.<locals>.<listcomp>z!Tokens must be non-empty strings.z!Topic must be a non-empty string.z/topics/z/topics/{0})ÚtoÚregistration_tokensz{0}/{1}rŸ   )r¡   r£   r¢   N)rK   rÏ   r°   rL   Ú
startswithrk   r/   ÚIID_URLr˜   r¥   ÚIID_HEADERSr¦   r	   r§   Ú_handle_iid_errorr   )	rZ   rM   rV   Ú	operationÚinvalid_strr=   r¡   rq   rh   r1   r1   r2   rT   é  s6   


þü	ý
€ÿz/_MessagingService.make_topic_management_requestc                 C   s   dt  |¡i}|rd|d< |S )Nr5   TÚvalidate_only)r/   rž   )rZ   r5   r6   r=   r1   r1   r2   r¤     s   z_MessagingService._message_datac                 C   s   t  | ¡ ¡S )z'Handle response from batch API request.)r£   ÚloadsÚdecode)rZ   rº   r¥   r1   r1   r2   rÉ     s   z_MessagingService._postprocc                 C   ó   t  |tj¡S )z)Handles errors received from the FCM API.)r   Ú#handle_platform_error_from_requestsr/   Ú_build_fcm_error_requests©rZ   rh   r1   r1   r2   r¨     ó   ÿz#_MessagingService._handle_fcm_errorc                 C   sŠ   |j du r
t |¡‚i }z|j  ¡ }t|tƒr|}W n	 ty#   Y nw | d¡}d}|r3d |¡}nd |j j	|j j
 ¡ ¡}t ||¡S )z1Handles errors received from the Instance ID API.Nrh   z(Error while calling the IID service: {0}z4Unexpected HTTP response with status: {0}; body: {1})r»   r   Úhandle_requests_errorr£   rK   rj   rL   r   rk   Ústatus_codeÚcontentrÛ   )rZ   rh   r=   Úparsed_bodyÚcodeÚmsgr1   r1   r2   rÖ     s&   



€ÿ
ÿz#_MessagingService._handle_iid_errorc                 C   rÜ   )zMHandles errors received from the googleapiclient while making batch requests.)r   Ú*handle_platform_error_from_googleapiclientr/   Ú _build_fcm_error_googleapiclientrß   r1   r1   r2   r¹   0  rà   z%_MessagingService._handle_batch_errorc                 C   s"   |   |¡}|r||||jd�S dS ©zfParses an error response from the FCM API and creates a FCM-specific exception if
        appropriate.)r¯   Úhttp_responseN)Ú_build_fcm_errorr»   )r�   rh   r5   Ú
error_dictÚexc_typer1   r1   r2   rÞ   5  s   
z+_MessagingService._build_fcm_error_requestsc                 C   s    |   |¡}|r||||d�S dS ré   )rë   )r�   rh   r5   rì   rê   rí   r1   r1   r2   rè   <  s   
z2_MessagingService._build_fcm_error_googleapiclientc                 C   sF   |sd S d }|  dg ¡D ]}|  d¡dkr|  d¡} nqtj  |¡S )NÚdetailsz@typez3type.googleapis.com/google.firebase.fcm.v1.FcmErrorÚ	errorCode)r   r/   ÚFCM_ERROR_TYPES)r�   rì   Úfcm_codeÚdetailr1   r1   r2   rë   C  s   
þz"_MessagingService._build_fcm_errorN)F)ra   rb   rc   rd   rŽ   rÆ   rÔ   rÕ   r   ÚMessageEncoderr›   r   r   r   r    rð   r]   Úclassmethodrž   r%   r(   r&   rT   r¤   rÉ   r¨   rÖ   r¹   rÞ   rè   rë   r1   r1   r1   r2   r/   o  s>    û



&

r/   )FNr,   )5rd   Úconcurrent.futuresr±   r£   rO   r¦   Úgoogleapiclientr   r   r�   r   r   r   r   r   r	   r.   Ú__all__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r!   r"   r#   r$   r   r   r   r    r3   r%   r(   r)   r&   r'   r*   r+   r   r   r   r   r/   r1   r1   r1   r2   Ú<module>   sf   &





#
 