Raise asyncio.TimeoutError from None concurrent.futures._base.TimeoutError

Hiā€¦ I am trying to send a mail using smtp server ā€¦The mail is being sent but after that the chat is not continuing

Can you share the code from action server that sends the mail and the stories.md file?

@lluchini

actions.py : from rasa_sdk.forms import FormAction from typing import Text,Dict,Any,List,Union from rasa_sdk import Action,Tracker from rasa_sdk.executor import CollectingDispatcher from rasa_sdk.events import SlotSet from rasa_sdk.events import AllSlotsReset from rasa_sdk import Action

class FormActionInfo(FormAction):

def name(self) -> Text:
    """Unique identifier of the form"""

    return "gmail_form"
@staticmethod
def required_slots(tracker: Tracker) -> List[Text]:
    """A list of required slots that the form has to fill"""

    return ["SenderMail","Password","RecipientMail", "Subject", "Format"]

def submit(
    self,
    dispatcher: CollectingDispatcher,
    tracker: Tracker,
    domain: Dict[Text, Any],
    ) -> List[Dict]:
    """Define what the form has to do
    after all required slots are filled"""
# utter submit template
    dispatcher.utter_message(template="utter_submit",SenderMail=tracker.get_slot('SenderMail'),Password=tracker.get_slot('Password'),
                             RecipientMail=tracker.get_slot('RecipientMail'),Subject=tracker.get_slot('Subject'),Format=tracker.get_slot('Format'))
    
    return []

def slot_mappings(self):
# type: () -> Dict[Text: Union[Dict, List[Dict]]]
    """A dictionary to map required slots to
    - an extracted entity
    - intent: value pairs
    - a whole message
    or a list of them, where a first match will be picked"""

    return {"SenderMail":[self.from_text()],
            "Password":[self.from_text()],
            "RecipientMail":[self.from_text()],
            "Subject": [self.from_text()],
            "Format":[self.from_text()]
           }

class SendMail(Action):

def name(self) -> Text:
    return "action_send_mail"

def run(self, dispatcher: CollectingDispatcher,
    tracker: Tracker,
    domain: Dict[Text, Any]) -> List[Dict[Text, Any]]:
    Subject = tracker.get_slot('Subject')
    Body = tracker.get_slot('Format')
    Recipient = tracker.get_slot('RecipientMail')
    
    import os
    import email,smtplib,ssl        


    server = smtplib.SMTP_SSL('smtp.gmail.com', 465) 
    server.starttls
    server.login(tracker.get_slot("SenderMail"), tracker.get_slot("Password"))  
   
   
    msg ="Subject: {} \n\n {} " .format(Subject,Body)

    server.sendmail(                     
    tracker.get_slot("SenderMail"), 
    [Recipient], 
    msg)                         
    server.quit()  

    dispatcher.utter_message(" Email sent ! ")
    return [] #just in my case, u can return ntg



def run(self, dispatcher, tracker, domain):
    return [AllSlotsReset()]

@lluchini

stories.md

happy path

  • get_started
    • utter_get_started

say goodbye

  • goodbye
    • utter_goodbye

happy path2

  • send_mail
    • gmail_form
    • form{ā€œnameā€: ā€œgmail_formā€}
    • form{ā€œnameā€: null}
    • utter_confirm
    • action_send_mail
  • yes
    • utter_goodbye

IITTP

  • IITTP

    • utter_IITTP
    • utter_do_you_need *deny
    • utter_no
  • IITTP_location

    • utter_IITTP_location
    • utter_do_you_need *deny
    • utter_no
  • IITTP_year

    • utter_IITTP_year
    • utter_do_you_need *deny
    • utter_no
  • IITTP_branches

    • utter_IITTP_branches
    • utter_do_you_need *deny
    • utter_no
  • IITTP_hostels

    • utter_IITTP_hostels
    • utter_do_you_need *deny
    • utter_no

IITTP_only2

  • IITTP
    • utter_IITTP
    • utter_do_you_need *deny
    • utter_no

IITTP_location2

  • IITTP_location
    • utter_IITTP_location
    • utter_do_you_need *deny
    • utter_no

IITTP_year2

  • IITTP_year

    • utter_IITTP_year
    • utter_do_you_need *deny
    • utter_no

IITTP_branches2

  • IITTP_branches

    • utter_IITTP_branches
    • utter_do_you_need *deny
    • utter_no

IITTP_hostels2

  • IITTP_hostels

    • utter_IITTP_hostels
    • utter_do_you_need *deny
    • utter_no

IITTP_only2

  • IITTP
    • utter_IITTP
    • utter_do_you_need *yes
    • utter_yes

IITTP_location2

  • IITTP_location
    • utter_IITTP_location
    • utter_do_you_need *yes
    • utter_yes

IITTP_year2

  • IITTP_year

    • utter_IITTP_year
    • utter_do_you_need *yes
    • utter_yes

IITTP_branches2

  • IITTP_branches

    • utter_IITTP_branches
    • utter_do_you_need *deny
    • utter_no

IITTP_hostels2

  • IITTP_hostels

    • utter_IITTP_hostels
    • utter_do_you_need *yes
    • utter_yes

yes

  • yes

    • utter_yes

fallback story

  • out_of_scope
    • action_default_fallback

Hello @Akhil1278 ,

Iā€™m far from being and specialist but letā€™s goā€¦

Your story ā€œhappy path2ā€ seems to be missing some things, as you did to the IITTP histories, using yes/deny to teach the flow to RASA.

happy path2

  • send_mail
    • gmail_form
    • form{ā€œnameā€: ā€œgmail_formā€}
    • form{ā€œnameā€: null}
    • utter_confirm
  • yes
    • action_send_mail
    • utter_goodbye

happy path3

  • send_mail
    • gmail_form
    • form{ā€œnameā€: ā€œgmail_formā€}
    • form{ā€œnameā€: null}
    • utter_confirm
  • deny
    • utter_goodbye

And if you donā€™t want to use stories, you can also use the followup actions (check this topic) after sending the mail, so the RASA core will follow the action you specified and not predict the next one.

Let me know if that helped you.

Cya!

1 Like

@lluchiniā€¦ Thanksā€¦It is working nowā€¦My smpt server is always sending mail through bccā€¦Is there any way i change it such that is sends the mail using to?

@Akhil1278,

Iā€™m glad that I was able to help you out! :grin:

About the mail recipient fields, probably the method/library you are using can do that, can you tell me from where is this class method below you are using?

@lluchini,

def run(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]) ā†’ List[Dict[Text, Any]]: Subject = tracker.get_slot(ā€˜Subjectā€™) Body = tracker.get_slot(ā€˜Formatā€™) Recipient = tracker.get_slot(ā€˜RecipientMailā€™)

    import os
    import email,smtplib,ssl        


    server = smtplib.SMTP_SSL('smtp.gmail.com', 465) 
    server.starttls
    server.login(tracker.get_slot("SenderMail"), tracker.get_slot("Password"))  
   
   
    msg ="Subject: {} \n\n {} " .format(Subject,Body)

    server.sendmail(                     
    tracker.get_slot("SenderMail"), 
    [Recipient], 
    msg)                         
    server.quit()  

    dispatcher.utter_message(" Email sent ! ")
    return []

@Akhil1278

I believe that this is what youā€™re looking forā€¦ :clinking_glasses:

python: how to send mail with TO, CC and BCC?

Cya!

@lluchini Thanksā€¦