0

I have several functions in my script that use multiline strings for messages currently.

My script is a password reminder that checks if a user is within 30, 15, 3 days from expiration, if they are they are sent sms and email reminders to change their password. In this function I have the body section as a multiline string at the moment:

        def send_sms():
            client = Client(twilio_account_sid, twilio_auth_token)
            for d in notify_users:
                message = client.messages.create(
                    to=d['Number'],
                    from_=twilio_from_phone_number,
                    body=f"Hello {d['Name']}, you have {d['days']} days left to reset your password."
                         f"\n"
                         f"\n***To change your password, press CTRL + ALT + DEL and select change password***."
                         f"\n"
                         f"\n"
                         f"\n- MY COMPANY IT")
                print(message.sid)
            for d in expired_users:
                message = client.messages.create(
                    to=d['Number'],
                    from_=twilio_from_phone_number,
                    body=f"Hello {d['Name']}, your password has expired, please change it asap to avoid any issues that could occur with your account."
                         f"\n"
                         f"\n***To change your password, press CTRL + ALT + DEL and select change password***."
                         f"\n"
                         f"\n"
                         f"\n- MY COMPANY IT")
                print(message.sid)

basically I want to replace the body sections of these functions with a notify_msg or expired_msg variable

I tried to define this before the function like so:

notify_msg = (f"Hello {d['Name']}, you have {d['days']} days left to reset your password."
                     f"\n"
                     f"\n***To change your password, press CTRL + ALT + DEL and select change password***."
                     f"\n"
                     f"\n"
                     f"\n- MY COMPANY IT")
expired_msg = (f"Hello {d['Name']}, your password has expired, please change it asap to avoid any issues that could occur with your account."
                      f"\n"
                      f"\n***To change your password, press CTRL + ALT + DEL and select change password***."
                      f"\n"
                      f"\n"
                      f"\n- MY COMPANY IT")

but obviously this isn't going to work because "d" isn't defined. I thought about doing this within the forloop, but I want the same variables to be able to be used in my send_email() functions as well. What could I do to pass this in, so I don't have to repeat the same multiline strings several times?

Here is the same thing for the email function:

 #  Send email to users
        def send_emails():
            for d in notify_users:
                return requests.post(
                    "https://api.mailgun.net/v3/MYDOMAIN/messages", 
                    auth=("api", "MAILGUN_API_KEY"),
                    data={"from": "IT <mailgun@MYDOMAIN>",
                          "to": notify_list,
                          "subject": "Password Reminder",
                          "text": f"Hello {d['Name']}, you have {d['days']} days left to reset your password."
                                  f"\n"
                                  f"\n***To change your password, press CTRL + ALT + DEL and select change password***."
                                  f"\n"
                                  f"\n"
                                  f"\n- IT"})

        # Send email to expired users
        def send_exp_emails():
            for d in expired_users:
                return requests.post(
                    "https://api.mailgun.net/v3/MYDOMAIN/messages",
                    auth=("api", "MAILGUN_API_KEY"),
                    data={"from": "IT <mailgun@MYDOMAIN>",
                          "to": expired_list,
                          "subject": "Password Reminder",
                          "text": f"Hello {d['Name']}, your password has expired, please change it asap to avoid any issues that could occur with your account."
                                  f"\n"
                                  f"\n***To change your password, press CTRL + ALT + DEL and select change password***."
                                  f"\n"
                                  f"\n"
                                  f"\n- IT"})

As you see, I am repeating the same multiline strings 4 times in my script. Is there anything I can do to pass multiline string variables in the body instead of repeating the same lines? Thanks all.

UPDATED CODE

users = [
{'Name': 'Timmy Turner', 'Number':'3245234523', 'Email':'timmyt@gmail.com','days': 15},    
{'Name': 'Jimmy Fallon', 'Number':'3245234523', 'Email':'jimmyfallon@gmail.com','days': 30}
]
expired_users = [
{'Name': 'Timmy Turner', 'Number':'3245234523', 'Email':'timmyt@gmail.com','days': -4},    
{'Name': 'Jimmy Fallon', 'Number':'3245234523', 'Email':'jimmyfallon@gmail.com','days': -5}
]

msg = "Hello % , %. \n \n***To change your password, press CTRL + ALT + DEL and select change password***.\n\n\n- MY COMPANY IT"

def send_email():
    for d in users:
        return requests.post(
            "https://api.mailgun.net/v3/MYDOMAIN/messages",
            auth=("api", "MAILGUN_API_KEY"),
            data={"from": "IT <mailgun@mail.MYDOMAIN.net>",
                "to": emails,
                "subject": "Password Reminder",
                "text": msg % (d['Name'], f"you have {d['days']} days left to reset your password.")})

def send_expired():
    for d in expired_users:
        return requests.post(
            "https://api.mailgun.net/v3/MYDOMAIN/messages",
            auth=("api", "MAILGUN_API_KEY"),
            data={"from": "IT <mailgun@mail.MYDOMAIN.net>",
                "to": expired,
                "subject": "Password Reminder",
                "text": msg% (d['Name'], "your password has expired, please change it asap to avoid any issues that could occur with your account")})
troy
  • 46
  • 8
  • 1
    One way would be to create a separate module or text file with the message and import it into this module. Then as an import it would be accessible to all functions. – whege Oct 29 '21 at 16:58

2 Answers2

2

Use formatted strings:

msg = "Hello %s, %s. \n \n***To change your password, press CTRL + ALT + DEL and select change password***.\n\n\n- MY COMPANY IT"
print(msg % ("Troy", "your password has expired, please change it asap to avoid any issues that could occur with your account"))

Output:

Hello Troy, your password has expired, please change it asap to avoid any issues that could occur with your account. 
 
***To change your password, press CTRL + ALT + DEL and select change password***.


- MY COMPANY IT

Note: no need to put line breaks on separated strings

Pedro Maia
  • 2,666
  • 1
  • 5
  • 20
  • Hey does this work without having to have a print statement? Because how this works for Mailgun and Twilio is, it goes into the body, I don't necessarily want to print anything I just need to body of the message to = notify_msg or expired_msg? Does that make sense? – troy Oct 29 '21 at 18:28
  • 1
    Sure, in your case put like this on the data dict: `"text": msg % (d['Name'], "A message")` – Pedro Maia Oct 29 '21 at 18:36
  • 1
    Change "A message" with your message for notify or expired. – Pedro Maia Oct 29 '21 at 18:38
  • Man that makes alot of sense! Thanks for the quick information. – troy Oct 29 '21 at 19:15
  • Hey Pedro, I seem to be having an issue. I used that syntax to pass the msg variable into my email function, but although the function works, it only sends the first dictionary in the list. So, if my list of dictionaries is like `{'Name': 'Jimmy Fallon', 'Number':'3245234523', 'Email':'jimmyfallon@gmail.com','days': -5}, {'Name': 'Timmy Turner', 'Number':'3245234523', 'Email':'timmyt@gmail.com','days': 10}` well it will send each email in the lod, but the name will all be Jimmy fallon and the days will carry over too, am I missing something? Each email isnt unique. @Pedro Maia – troy Nov 02 '21 at 15:16
  • Are you sure you're using the new dictionary on each iteration? can you provide your new code? – Pedro Maia Nov 02 '21 at 16:06
  • Hey I updated my current code, this is just a test LoD and function call but this is to make sure it works first. I am not creating a new dictionary I don't think but for each dictionary in the list it should be iterating through it with the unique information, can you see anything wrong with why it wouldn't be doing this? It sends to each unique email, but doesn't pass in the name and days values properly @Pedro Maia – troy Nov 02 '21 at 16:16
  • 1
    You're returning the value on the first iteration which ends the function, also your message `msg` need to have `%s` not only `%`. – Pedro Maia Nov 02 '21 at 17:07
  • That's what I was thinking also it was %s but i have been changing things around, so I have tried it with %s, how would I have it iterate through the entire dictionary? – troy Nov 02 '21 at 17:13
  • Does this function really need a return value? if so create a `output` variable with an empty list and on each iteration append to it and on the end return the list, if you don't need a return value just remove `return` and it should work. – Pedro Maia Nov 02 '21 at 17:24
  • Ahh thank you, that part seems to be working however there is another issue. – troy Nov 02 '21 at 17:43
1

The two messages seem to have the same underlying general format. You can move that out into a generic template which is the same for all message types. Only perform the actual string-formatting/string-interpolation in the send_emails and send_exp_emails functions, when you have all necessary variables/data.

template = "Hello {}, {}" \
           "\n***To change your password, press CTRL + ALT + DEL and select change password***." \
           "\n\n\n- MY COMPANY IT"

name = "Bob"

def send_emails():
    remaining_days = 3
    message = "you have {} days left to reset your password.".format(remaining_days)
    print(template.format(name, message))

def send_exp_emails():
    message = "your password has expired, please change it asap to avoid any issues that could occur with your account."
    print(template.format(name, message))

send_emails()
send_exp_emails()
Paul M.
  • 10,481
  • 2
  • 9
  • 15