Get users contact info based on role

I have a timer script that sends out an email each week and includes a run time report from an sql query and attaches a file to the email, the recipient addresses are currently being pulled from some tags where I have stored their email addresses.

I have 2 questions;

#1 rather than have the recipients stored in tags how can I pull contact info from ignition users where they belong to a particular role - for example im looking for something like:
“system.users.get contact info(email address) where role = (supervisor)”

#2 is this weekly email notification im scripting something that is also possible using the notification block? ie. being able to send the notification every Sunday at midnight and include various sql queries and include attachments?

Thank you.

For question #1, I’d take a look at the documentation for system.user.getUsers(). This will return a list of User objects, which have the functions User.getRoles() and User.getContactInfo()

no problem returning roles… but I cant seem to get anywhere with getContactInfo - keep getting object has no attribute ‘ContactInfo’. can you give an example how syntax for getContactInfo is used?

any advice on returning only users that belong to a certain role?

Thank you.

You can’t get only users with a certain role, but you can select only the users you want from your result. Here’s some Q&D code as an example:

emails = [] users = system.user.getUsers("") for user in users: if "supervisor" in user.getRoles(): contacts = user.getContactInfo() for contact in contacts: if contact.contactType == "email": emails.append(contact.value) for email in emails: print email

[quote=“KathyApplebaum”]You can’t get only users with a certain role, but you can select only the users you want from your result. Here’s some Q&D code as an example:

emails = [] users = system.user.getUsers("") for user in users: if "supervisor" in user.getRoles(): contacts = user.getContactInfo() for contact in contacts: if contact.contactType == "email": emails.append(contact.value) for email in emails: print email[/quote]

Ah, got it thank you very much!

using your example this is what I came up with which yields a usable string for email recipients

import sys emails = [] users = system.user.getUsers("") for user in users: if "Supervisors" in user.getRoles(): contacts = user.getContactInfo() for contact in contacts: if contact.contactType == "email": emails.append(contact.value) emails = repr([x.encode(sys.stdout.encoding) for x in emails]).decode('string-escape') system.tag.writeToTag('Email_Recipients',emails)

…however the script wont run in a gateway timer script (runs fine in script tester though). the error I get is

java.lang.IllegalArgumentException: java.lang.IllegalArgumentException: Authentication profile "" not found

any idea how to get this to work?

Thank you.

This could be a bug. Acording to this, you must specify the user source in the function getUsers, but if you use “” as argument, the function resolve using the default user source assigned to the project.

Maybe, in the gateway scope, the function can’t resolve what user source is the default.

You can workaround this, hardcoding the user source, for example: system.users.getUsers(“default”), when “default” is your desired user source.

Regards,

[quote=“pdibenedetto”]This could be a bug. Acording to this, you must specify the user source in the function getUsers, but if you use “” as argument, the function resolve using the default user source assigned to the project.

Maybe, in the gateway scope, the function can’t resolve what user source is the default.

You can workaround this, hardcoding the user source, for example: system.users.getUsers(“default”), when “default” is your desired user source.

Regards,[/quote]

you are correct, thank you. when I define the exact user source the script runs. however now I have found that encode line (second to last) is not executing in the gateway so the email string is returning a “u” before each email address…

I’m not familiar enough with the functions that you use in that line, but, I guess the problem must be that sys.stdout.encoding is returning some different string in gateway context than designer context.

What are you trying to do? Convert the unicode emails strings in ascii format?

If so, you can replace that line with this one:

emails = [str(email) for email in emails]

Or, if you prefer, mantain your line, but replace sys.stdout.econding by ‘ascii’.

I don’t know what you are trying to do with this string (the string representation of the list object) writed in a tag, but If you trying to “save” the list in a tag for later recover, you could mantain unicode format writed in the tag and recover the object using eval function. Some example:

import sys
emails = []
users = system.user.getUsers("")
for user in users:
   if "Supervisors" in user.getRoles():
      contacts = user.getContactInfo()
      for contact in contacts:
         if contact.contactType == "email":
            emails.append(contact.value)
system.tag.writeToTag('Email_Recipients',emails)

# recover list object in emails2 var  from tag value (maintaining unicode format)
emails2 = eval(system.tag.getTagValue('Email_Recipients'))

Also, I don’t know what Ignition version are you using, but in newer version it’s recommended to be used system.tag.write and system.tag.read instead of system.tag.writeToTag and system.tag.getTagValue.

Hope this helps.

Regards,

Is there a way to link this method to an on call roster? I tried creating a list of users from system.alarm.getRosters() which worked, but comparing users from the .getUsers isn’t working. Also, I have been unable to pull any of the contact data listed above such as type or value. Thanks!

Note that there are two examples in there. One if you want to match any role in the roleFilter, and one to match all roles.

rosterUsers = system.alarm.getRosters()['roster_name']
 
roleFilter = set(['Role1', 'Role2', 'Role3'])

userDict = {}

for name in rosterUsers:
	user = system.user.getUser('user_source', name)
	# Test for any role
	if user != None and len(roleFilter.intersection(set(user.getRoles()))) > 0:
	# Test for all roles
	#if user != None and len(roleFilter.intersection(set(user.getRoles()))) == len(roleFilter):
		userDict[name] = user.getContactInfo()

emails = []
for user in userDict:
	for contact in userDict[user]:
		if contact.contactType == 'email':
			emails.append(contact.value)

print emails

This worked perfectly and was able to use the emails list in a system.net.sendEmail function. Thanks for your help!

Could you please tell me how were you pulling the email addresses from a tag? I am trying to do that. Thanks!

Whats the best way to get a single users email address from their User Management contact info? And output as a string?

You can do something like:

userSource = 'Your user source'
userName = 'user name you want contact info from'
data = system.user.getUser(userSource,userName)
conInfo = data.getContactInfo()
for x in range(len(conInfo)):
	i = str(conInfo[x])
	if 'email' in i:
		email = i.split(' ')
		email = email[1]
		print email
1 Like

Thanks bpreston. That is a little simpler than what I had originally. Still seems like this should be able to be done with a few less lines.

Here is what I ended up using. Just added in some error handling.

userSource = 'Your user source'

try: 
	userName = 'user name you want contact info from'
    conInfo = system.user.getUser(userSource ,userName).getContactInfo()
	for x in range(len(conInfo)):
		i = str(conInfo[x])
		if  'email' in i:
			email = i.split(' ')
			email = email[1]
except:
      email = 'Email or user does not exist'

print email
1 Like