Skip to main content
Glama
lead_nurturer.cpython-313.pyc27.4 kB
� � �hpM��6�SrSSKrSSKrSSKrSSKrSSKrSSKJrJr SSKJ r J r J r J r SSK Jr SSKJr SSKrSSKJr SSKJr SS KJr SS KJr SS KJr SS KJr \"S S55r"SS5r\ S:XaSSKr\"5r!\!RE5 gg)zw Advanced Lead Nurturing System for Gmail CSV Sender Handles automated follow-ups, response tracking, and lead scoring �N)�datetime� timedelta)�Dict�List�Optional�Any)� dataclass)� EmailMessage)� Credentials)�build)� HttpError)�InstalledAppFlow)�Request)�Templatec��\rSrSr%\\S'\\S'\\S'Sr\\S'Sr\\ \S'S r \ \S 'S r \ \S 'S r \ \S 'S r\\S'Srg)�Lead��email� first_name�company�new�statusN� last_contactr�response_count�follow_up_count� lead_score��notes�)�__name__� __module__� __qualname__�__firstlineno__�str�__annotations__rrrrr�intrrr�__static_attributes__r��/workspace/lead_nurturer.pyrrsQ�� �J��O� �L��F�C��'+�L�(�8�$�+��N�C���O�S���J����E�3�Or(rc�(�\rSrSrSS\S\S\4SjjrS\S\4SjrS\\\ 44S jr S\\\44S jr S \\\44S jr S\\\44S jr SrSrS\\\44SjrSrS\S\S\4SjrS\S\4SjrS\S\4SjrSrS\S\4SjrSrSrSrg)� LeadNurturer�%N�credentials_path� token_path�servicec���U=(d URX5UlUR5UlUR 5UlUR 5UlUR5Ul g�N) � _get_servicer/� _load_leads�leads�_load_templates� templates� _load_config�config�_load_sync_state� sync_state)�selfr-r.r/s r)�__init__�LeadNurturer.__init__&sZ���Q�$�"3�"3�4D�"Q�� ��%�%�'�� ��-�-�/����'�'�)�� ��/�/�1��r(c�"�SS/nSn[RRU5(a[R"X#5nU(aUR (d�U(a<UR (a+UR(aUR[55 O%[R"X5nURSS9n[US5nURUR55 SSS5 [!SSUS 9$!,(df  N=f) zInitialize Gmail servicez.https://www.googleapis.com/auth/gmail.readonlyz*https://www.googleapis.com/auth/gmail.sendNr)�port�w�gmail�v1)� credentials)�os�path�existsr �from_authorized_user_file�valid�expired� refresh_token�refreshrr�from_client_secrets_file�run_local_server�open�write�to_jsonr )r;r-r.�SCOPES�creds�flow�tokens r)r2�LeadNurturer._get_service-s���B�=�?���� �7�7�>�>�*� %� %��9�9�*�M�E��E�K�K�����5�+>�+>�� � �g�i�(�'�@�@�AQ�Z���-�-�1�-�5���j�#�&�%�� � �E�M�M�O�,�'��W�d��6�6�'�&�s � D� D�returnc��0n[SSSS9n[R"U5nUH7nUSR5R 5n[ UUSUSS9X'M9 S S S 5 [S S5n[R"U5nUR5H�upWXQ;dM URS S 5Xl URS5(a[R"US5OS XlURSS5XlURSS5XlURSS5XlURSS5XlM� S S S 5 U$!,(df  GN=f![ a [S 5 GN-f=f!,(df  U$=f![ a [S5 U$f=f)z%Load leads from CSV and tracking filez contacts.csv�r�utf-8)�encoding�torr)rrrNzcontacts.csv not found�lead_tracking.jsonrrrrrrrrrzNo existing tracking data found)rN�csv� DictReader�strip�lowerr�FileNotFoundError�print�json�load�items�getrr� fromisoformatrrrrr)r;r4�f�reader�rowr� tracking_data�datas r)r3�LeadNurturer._load_leadsAs����� ,��n�c�G�<������*��!�C���I�O�O�-�3�3�5�E�#'�#�#&�|�#4� #�I��$�E�L�"�=� 5��*�C�0�A� $� � �!� � �#0�#6�#6�#8�K�E��~�.2�h�h�x��.G�� �+�dh�dl�dl�m{�d|�d|�H�4J�4J�4�P^�K_�4`�CG�� �1�6:�h�h�?O�QR�6S�� �3�7;�x�x�@Q�ST�7U�� �4�26�(�(�<��2K�� �/�-1�X�X�g�r�-B�� �*�$9�1�� �7=�<��!� ,� �*� +� ,�� 1�0�� ��!� 5� �3� 4�� � 5�sf� F�AE.�#F�, F.�8/F�+B9F�$F.�. E=�8F�=F�F�F� F+�&F.�+F.�.G�Gc��[SS5n[R"U5sSSS5 $!,(df  g=f![a 0s$f=f)Nznurturing_config.jsonrX�rNrcrd� Exception�r;rhs r)r7�LeadNurturer._load_configds>�� ��-�s�3�q��y�y��|�4�3�3��� ��I� �s#� ?�.� ?� <�?�?� A� A� new_configc�$�U=(d 0Ulgr1)r8)r;rss r)� reload_config�LeadNurturer.reload_configks�� �&�B�� r(c��[SS5n[R"U5sSSS5 $!,(df  g=f![a S/S.s$f=f)N�gmail_sync_state.jsonrX)�last_checked_iso�processed_message_idsrorqs r)r9�LeadNurturer._load_sync_statensG�� K��-�s�3�q��y�y��|�4�3�3��� K�(,�r�J� J� K�s#� ?�.� ?� <�?�?�A�Ac��[SS5n[R"URUSS9 SSS5 g!,(df  g=f![a gf=f)Nrxr@���indent)rNrc�dumpr:rprqs r)�_save_sync_state�LeadNurturer._save_sync_stateusE�� ��-�s�3�q�� � �$�/�/�1�Q�7�4�3�3��� � � �s+� A �!8�A � A�A �A � A�Ac��0nURR5Hmup#URUR(aURR 5OSUR UR URURS.X'Mo [SS5n[R"XSS9 SSS5 g!,(df  g=f)zSave lead tracking dataN)rrrrrrr\r@r}r~) r4rerr� isoformatrrrrrNrcr�)r;rkr�leadrhs r)� _save_leads�LeadNurturer._save_leads|s���� ��:�:�+�+�-�K�E��+�+�AE�AR�AR�� 1� 1� ;� ;� =�X\�"&�"5�"5�#'�#7�#7�"�o�o���� $�M� �.��&�� ,�� �I�I�m�q� 1�-� ,� ,�s �B9�9 Cc���0n[SR55US'[SR55US'[SR55US'[SR55US'U$) z,Load email templates for different scenariosu� Hi {{first_name}}, Did you know many dental practices lose 20–30% of new patient inquiries because follow-ups slip through the cracks? We've built an AI agent that automatically follows up with every lead via SMS/email and books them straight into your calendar. Clients typically see 5–9 extra appointments in the first 30 days. Have time for 10-min demo call this week? Thank you, Brandon Quantra Labs �initiala& Hi {{first_name}}, Following up on my message about our AI lead follow-up system for dental practices. I know you're busy, but this could be a game-changer for {{company}}. Quick question: What's your biggest challenge with patient follow-ups right now? Best, Brandon Quantra Labs � followup_1a� Hi {{first_name}}, I understand you might not be ready to discuss this right now. Just wanted to share that Dr. Sarah Johnson at Smile Care Clinic increased her new patient bookings by 40% in the first month using our system. If you're interested in a quick 5-minute demo, just reply with "demo" and I'll send you a calendar link. No pressure - I'll stop following up after this. Best, Brandon Quantra Labs � followup_2a Hi {{first_name}}, Great to hear from you! I'd love to show you how our AI system works. Here's a quick calendar link to book a 10-minute demo: [Calendar Link] Looking forward to showing you how this can help {{company}} capture more patients. Best, Brandon Quantra Labs � interested)rr_)r;r6s r)r5�LeadNurturer._load_templates�s���� � (�) � �E�G� � �)��"#+� , � �E�G� #� �,��#+�, � �E�G�#� �,��"#+�, � �E�G�#� �,�� �r(c�^�URRS05RSS5nS/nU(a�SnURRS5(a=[R"URS5n[ UR 55nU(aURSU35 OURS5 S RU5n[URRS /55nSnURR5R5RS XWS S 9R5nURS/5n U GHqn U RS5n U (aX�;aM#URR5R5RS U SS9R5n U RS05RS/5n SnSnU HFnURS5nUS:XaURS5nM-US:XdM5URS5nMH U(dM�[ R""SU5nU(a UR%S5R'5nOUR'5nUUR(;dGMDUR+UU=(d SU 5 UR-U 5 GMt URS5nU(dOGM�[R."5R15URS'[U5n[3U5S:�aUSSnUURS 'UR55 g![a SnGN�f=f![6an[9SU35 SnAgSnAf[an[9SU35 SnAgSnAff=f) zICheck Gmail for responses to our outreach with pagination and idempotency� automation�check_responses_interval_hours�zin:inboxNryzafter:z newer_than:1d� rz�me�d)�userId�q� pageToken� maxResults�messages�id�full)r�r��format�payload�headers�name�From�value�Subjectz<(.+?)>�r� nextPageTokeni�i ���z$Gmail API error checking responses: zError checking responses: )r8rfr:rrgr&� timestamprp�append�join�setr/�usersr��list�execute�re�search�groupr`r4�_process_response�add�utcnowr��lenr�r rb)r;�newer_than_hours� query_parts�after_ts�dt�query� processed_ids� page_token�resultsr��message�msg_id�msgr��sender�subject�headerr��sender_email_match� sender_email� latest_ids�he�es r)�check_for_responses� LeadNurturer.check_for_responses�s7��J 4�� � ��� �b�1�5�5�6V�XZ�[� �&�,�K�����?�?�&�&�'9�:�:�(�%�3�3�D�O�O�DV�4W�X��#&�r�|�|�~�#6����&�&���z�':�;� �&�&��7��H�H�[�)�E����� 3� 3�4K�R� P�Q�M��J���,�,�,�,�.�7�7�9�>�>��5�3�?���'�)��#�;�;�z�2�6��'�G�$�[�[��.�F�!�V�%<� ��,�,�,�,�.�7�7�9�=�=�T�f�]c�=�d�l�l�n�C�!�g�g�i��4�8�8��B�G�G�!�F�"�G�")��%�z�z�&�1���6�>�%+�Z�Z��%8�F�!�Y�.�&,�j�j��&9�G� #*��v�-/�Y�Y�z�6�-J�*�-�+=�+C�+C�A�+F�+L�+L�+N�L�+1�<�<�>�L�'�4�:�:�5� �2�2�<���B�PS�T�)�-�-�f�5�5 (�8%�[�[��9� �!��I�N3;�/�/�2C�2M�2M�2O�D�O�O�.� /��m�,�J��:���$�'���.� �7A�D�O�O�3� 4� � !� !� #��q%�(�#'��(��t� ?� �8���=� >� >��� 4� �.�q�c�2� 3� 3�� 4�s]�AM*�<M�FM*�M*�9AM*�B<M*� M'�#M*�&M'�'M*�* N,�4N� N,�N'�'N,rr�r�c��^�URUnU=RS- sl[R"5UlUR U5nUR 5mURRS05RS/SQ5nURRS05RS/SQ5n[U4SjU55(a�SUl U=R[URRS05RS S 55- sl U=R[URRS05RS S 55- sl URRS 05RSS5(aURUS5 OL[U4SjU55(aSUl U=RS -sl OU=RS- sl U=RS[R"5RS5SU3- sl[!SUR"SUR$35 g)zProcess a response from a leadr��response_keywordsr�)r��yes�demo�call�meeting�schedule�book�not_interested)znot interestedz no thanks�stop� unsubscribe�removec3�,># �UH oT;v� M g7fr1r��.0�word�response_lowers �r)� <genexpr>�1LeadNurturer._process_response.<locals>.<genexpr>0s����C�2B�$�~�%�2B���� lead_scoring�response_bonus� �interest_bonus�r��auto_respond_to_interestTc3�,># �UH oT;v� M g7fr1rr�s �r)r�r�6s����I�4H�D��'�4H�r�r}� z%Y-%m-%dz: Response received - zProcessed response from � at N)r4rr�nowr�_get_message_bodyr`r8rf�anyrrr&�_send_automated_responser�strftimerbrr) r;rr�r�r��body�interested_words�not_interested_wordsr�s @r)r��LeadNurturer._process_response"s�����z�z�%� �� ���q� ��$�L�L�N����%�%�g�.������� �;�;�?�?�+>��C�G�G� �WU�V��#�{�{���/B�B�G�K�K�L\�_[� \�� �C�2B�C� C� C�&�D�K� �O�O�s�4�;�;�?�?�>�2�#F�#J�#J�K[�]_�#`�a� a�O� �O�O�s�4�;�;�?�?�>�2�#F�#J�#J�K[�]^�#_�`� `�O��{�{���|�R�0�4�4�5O�QU�V�V��-�-�e�\�B�� �I�4H�I� I� I�*�D�K� �O�O�q� �O� �O�O�q� �O� � � ��8�<�<�>�2�2�:�>�?�?U�V]�U^�_�_� � �(����(9��d�l�l�^�L�Mr(c��URS05nSnSU;a�[URS/55nSnU(aUR5nURSS5nSU;a!URURS/55 US:XaU"U5nU(aU$OUS:XaU(dU"U5nU(aMU(a[R "SSU5$gURS5nUS:XaU"U5$US:Xa U"U5n [R "SSU 5$g![ an [S U 35 S n A gS n A ff=f) z'Extract message body from Gmail messager�c��URS05RS5nU(dg[R"U5RSSS9$![a gf=f)Nr�rlrrY�ignore)�errors)rf�base64�urlsafe_b64decode�decoderp)�partrls r)� decode_part�3LeadNurturer._get_message_body.<locals>.decode_partFs\���x�x���+�/�/��7�����!�3�3�D�9�@�@��QY�@�Z�Z�� ����s�#A� A�A�partsr�mimeTypez text/plainz text/htmlz<[^<]+?>zError extracting message body: N)rfr��pop�extendr��subrprb) r;r�r�r��stack�html_candidater��mime�text�htmlr�s r)r��LeadNurturer._get_message_bodyAsR��& 9��k�k�)�R�0�G� ��'�!��W�[�[��"�5�6��!#��� �9�9�;�D��8�8�J��3�D��$��� � �T�X�X�g�r�%:�;��|�+�*�4�0���#'�K� ���,�^�)4�T�):���e�"��6�6�*�b�.�A�A�"���{�{�:�.���<�'�&�w�/�/��[�(�&�w�/�D��6�6�*�b�$�7�7�)� ��� 9� �3�A�3�7� 8� 8��� 9�s0�BD(�!D(�D(�!D(�%D(�( E �2E�E � template_typec��URUnURUnSnURURURS9n[ 5nXS'UR RS5=(dD URR5RSS9R5RS5nUR RS5=(d S n U (aU S US 3OUUS 'XWS 'URU5 [R"UR55R!5n URR5R#5R%SSU 0S9R5 ['SUSUR35 g![(an ['SU 35 Sn A gSn A ff=f)z.Send automated response based on template typez1Re: AI Lead Follow-up System for Dental Practices�rr�Tor�r��r�� emailAddress� sender_namer� <�>r�r��raw�r�r��Sent z response to zError sending response: N�r4r6�renderrrr r8rfr/r�� getProfiler�� set_contentr��urlsafe_b64encode�as_bytesr�r��sendrbrp� r;rrr��templater�r�r�r�r �encodedr�s r)r��%LeadNurturer._send_automated_responsels����z�z�%� ���>�>�-�0��E���������L�L�� ��  2��.�C���I��;�;�?�?�>�:�I�d�l�l�>P�>P�>R�>]�>]�ei�>]�>j�>r�>r�>t�>x�>x�zH�?I�L��+�+�/�/�-�8�>�B�K�?J�[�M��L�>��;�P\�C��K�$� �N� �O�O�D� !��.�.�s�|�|�~�>�E�E�G�G� �L�L� � � � )� )� +� 0� 0���W�%� 1� ��g�i� �E�-�� �d�o�o�5F�G� H��� 2� �,�Q�C�0� 1� 1�� 2�s�EF� F=�%F8�8F=c�4�[R"5nURR5GHdup#URR S05R SS5(dM9UR S;dMKUR(dM^XR- RnURR S05n[UR SS55n[UR SS 55n[UR S S 55nXF:�a2URS :Xa"URUS 5 SUl XlGMXG:�dGM"URS:XdGM5URUS5 S Ul XlUS ::dGM]SUlGMg g)z-Run follow-up sequence for leads that need itr��auto_send_follow_upsT)r� contacted�follow_up_schedule�followup_1_days��followup_2_days��max_follow_upsr}rr�r�r�r�N) rr�r4rer8rfrr�daysr&r�_send_follow_up) r;r�rr��days_since_contact� cfg_schedule�fu1_days�fu2_days� max_follows r)�run_follow_up_sequence�#LeadNurturer.run_follow_up_sequence�sJ���l�l�n���:�:�+�+�-�K�E��;�;�?�?�<��4�8�8�9O�QU�V�V���{�{�2�2�t�7H�7H�7H�&)�,=�,=�&=�%C�%C�"�#�{�{���/C�R�H� ��|�/�/�0A�1�E�F���|�/�/�0A�1�E�F�� ��!1�!1�2B�A�!F�G� �&�1�d�6J�6J�a�6O��(�(�� �=�+,�D�(�(+�%�'�3��8L�8L�PQ�8Q��(�(�� �=�+,�D�(�(+�%�!�Q��&6�� �+.r(c��URUnURUnSnURURURS9n[ 5nXS'UR RS5=(dD URR5RSS9R5RS5nUR RS5=(d S n U (aU S US 3OUUS 'XWS 'URU5 [R"UR55R!5n URR5R#5R%SSU 0S9R5 ['SUSURSUR35 g![(an ['SU 35 Sn A gSn A ff=f)zSend follow-up emailz'Following up - AI Lead Follow-up Systemrrr�r�rrr rr r r�r�r r rz to r�zError sending follow-up: Nrrs r)r$�LeadNurturer._send_follow_up�s����z�z�%� ���>�>�-�0��;���������L�L�� ��  3��.�C���I��;�;�?�?�>�:�I�d�l�l�>P�>P�>R�>]�>]�ei�>]�>j�>r�>r�>t�>x�>x�zH�?I�L��+�+�/�/�-�8�>�B�K�?J�[�M��L�>��;�P\�C��K�$� �N� �O�O�D� !��.�.�s�|�|�~�>�E�E�G�G� �L�L� � � � )� )� +� 0� 0���W�%� 1� ��g�i� �E�-���T�_�_�,=�T�$�,�,��P� Q��� 3� �-�a�S�1� 2� 2�� 3�s�E!F(�( G �2G�G c ���[UR5n[SURR555n[SURR555n[SURR555n[ S5 [ SU35 [ SU35 [ SU35 [ SU35 [ US :�a S X2- S -S S 3OS5 [ US :�a SXC- S -S S 3OS5 [ URR5SSS9SSn[ S5 UH5n[ SUR SURSUR35 M7 g)z Generate a lead nurturing reportc3�H# �UHoRS:wdMSv� M g7f)rr�N�r�r�r�s r)r��4LeadNurturer.generate_lead_report.<locals>.<genexpr>�s���R�&9�d�[�[�E�=Q���&9���"� "c3�H# �UHoRS:�dMSv� M g7f)rr�N)rr1s r)r�r2�s ���U�&9�d�=P�=P�ST�=T���&9�r3c3�H# �UHoRS:XdMSv� M g7f)r�r�Nr0r1s r)r�r2�s���Z�':�t�k�k�\�>Y���':�r3u 📊 LEAD NURTURING REPORTz Total Leads: z Contacted: z Responded: z Interested: rzResponse Rate: r�z.1f�%zResponse Rate: N/AzInterest Rate: zInterest Rate: 0%c��UR$r1)r)�xs r)�<lambda>�3LeadNurturer.generate_lead_report.<locals>.<lambda>�s��a�l�lr(T)�key�reverseNr�u 🏆 TOP LEADS BY SCORE:z r�z - Score: ) r�r4�sum�valuesrb�sortedrrr)r;� total_leadsr� respondedr�� top_leadsr�s r)�generate_lead_report�!LeadNurturer.generate_lead_report�s[���$�*�*�o� ��R�d�j�j�&7�&7�&9�R�R� ��U�d�j�j�&7�&7�&9�U�U� ��Z�t�z�z�'8�'8�':�Z�Z� � �,�.� � �k�]�+�,� � �I�;�'�(� � �I�;�'�(� � �Z�L�)�*� �I�PQ�M���!4�S�!8�#�>�a�@�Wk�l� �Y�QR�]���!5�c�!9�3�?�q�A�Xk�l��4�:�:�,�,�.�4J�TX�Y�Z\�[\�]� � �*�,��D� �B�t���'�t�D�L�L�>��D�O�O�CT�U� V�r(c���[S5 [S5 UR5 [S5 UR5 UR5 UR 5 [S5 g)z Run the complete nurturing cycleu%🔄 Starting lead nurturing cycle...u📧 Checking for responses...u"📤 Running follow-up sequence...u✅ Nurturing cycle complete!N)rbr�r*r�rC)r;s r)�run_nurturing_cycle� LeadNurturer.run_nurturing_cycle�s^�� �5�6� �.�/� � � �"� �2�3� �#�#�%� ���� �!�!�#� �-�.r()r8r4r/r:r6)zcredentials.jsonz token.jsonN)r r!r"r#r$rr<r2rrr3r7rur9r�r�rr5r��dictr�r�r�r*r$rCrFr'rr(r)r+r+%s��2��2�s�2�lo�2�7�S�7�c�7�(!�T�#�t�)�_�!�F�d�3��8�n��'��S�#�X��'�K�$�s�C�x�.�K��2� F��c�8�m�!4�F�PL4�\N�s�N�S�N�4�N�>)��)�#�)�V2�c�2�#�2�>7�63�S�3��3�<W�*/r(r+�__main__)#�__doc__r]rcrD�timer�rr�typingrrrr� dataclassesr � email.messager r��google.oauth2.credentialsr �googleapiclient.discoveryr �googleapiclient.errorsr �google_auth_oauthlib.flowr�google.auth.transport.requestsr�jinja2rrr+r �nurturerrFrr(r)�<module>rVs����  � � � � �(�,�,�!�&� �1�+�,�6�2�� � � � � �G/�G/�R �z�� ��~�H� � � �"� r(

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/brandononchain/GMAIL-MCP-Agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server