I am trying to create a connection that will send a message/email to someone if an item is added to a Collector map that is sitting on our ArcGIS Online account. I have taken a look around, and see that there are some items you can use on servers, but I cannot find any information about this sort of thing being done with ArcGIS Online. Does anyone know whether it is possible to set up a trigger in ArcGIS Online? I am quite new to Collector and ArcGIS Online, so if you do know of something that might help, if you could explain it "for a newbie", I would really appreciate it!
Thanks 😃
I have used the REST API via python to obtain the last edit date for a feature. See thread https://community.esri.com/thread/161245 for info. You would set up a python script to query your feature for any new updates since the script was last run, sleep for a specified period and requery. If the script finds something, it would send an email.
That sounds like it might be just the thing we need. Thanks for your help Randy!
I did this for a Survey123 Form by adding a field to the Hosted Feature Service database called FormEmailed and have it default to No. I then run a script at night that uses a ArcMap layout connected to data driven pages with a definition query of FormEmailed = No (I use the Export to PDF from the ddp to get a pdf). I use python smtp to send the email with pdf attachment. Then I use ArcRest to set the FormEmailed = Yes. This way I can always go back into a record and change it to No and it will send it out again.
Let me know if you want to see the code. Getting the JSON just right is the hardest part.
Hope that helps.
I would be interested in receiving that code.
You have no info on your profile so I have to post it here.
Note change the prt statements as that is a private library we use. also need all the paths marked fixthis. must also install ArcRest
'''-------------------------------------------------------------------------------
Purpose: Reads in all the form maps, creates PDFs for the forms, emails them out, then updates the FormEmailed field in the HFS.
The HFS MUST be the first layer in the map and MUST be part of a group layer (this is how it normally comes in).
The HFS MUST have a field called FormEmailed that is yes or no (in lowercase).
The form map mxd MUST have a form element with the name FormName.
The form map mxd MUST have a form element with the name PDFTitle and that should be a field from the HFS.
-------------------------------------------------------------------------------'''
import arcpy, os, string , urllib, urllib2, json, contextlib, smtplib, mimetypes, datetime, sys, time, traceback
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
from arcrest.security import AGOLTokenSecurityHandler
from arcrest.agol import FeatureLayer
from arcrest.common.filters import LayerDefinitionFilter
# Testing flags
sendEmailsFlag = 1
markAsEmailed = 1
deleteTempPDF = 1
# login info
AGOusername = "put here"
AGOpassword = "put here"
emailSMTP = "fixthis.smtp.com"
#smtpusername = ""
#smtppassword = ""
# Temp area to store pdfs to email. script then deletes them for cleanup. could keep if wanted just set flag above
pdfBase = r"fixthis"
# Directory of DDP maps
mapsDir = r"fixthis"
prt("---Start of Daily Forms Email Log File---\n")
prt("Forms Email Started: " + time.asctime())
prt ("\n====================================================================================================\n")
try:
# Run for each Form map in the Dir
mapsList = os.listdir(mapsDir)
for mapToUse in mapsList:
if mapToUse.endswith(".mxd"):
# Get map and ddp links
mxd = arcpy.mapping.MapDocument(os.path.join(mapsDir, mapToUse))
prt("Running map " + os.path.join(mapsDir, mapToUse))
ddp = mxd.dataDrivenPages
# Kick out a pdf for each record in the HFS. Note this assumes a definition query was set for formemailed=no
if ddp.pageCount > 0:
for i in range(1, ddp.pageCount + 1):
ddp.currentPageID = i
row = ddp.pageRow
elm = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "FormName")
formName = elm[0].text
fixDate = row.CreationDate
fixedDate = str(fixDate.month) + "-" + str(fixDate.day) + "-" + str(fixDate.year)
# There is not always a JobName so had to make a form element called PDFTitle that is used to name forms and subject lines
# This gives back
elm2 = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "PDFTitle")
titleName = elm2[0].text
fieldStart = titleName.find("field") + 7
fieldEnd = titleName.find('"', fieldStart)
findField = titleName[fieldStart:fieldEnd]
nameToUse = row.getValue(findField)
if nameToUse:
baseName = formName + " " + nameToUse + " " + fixedDate
else:
baseName = formName + " " + "Blank Name Given" + " " + fixedDate
pdfName = pdfBase + "\\" + baseName + ".pdf"
ddp.exportToPDF(pdfName, "RANGE", str(i))
if sendEmailsFlag == 1:
# Email the pdf
emailfrom = row.Creator
# email a copy to the creator always plus the field they picked
# Gets mad if a null, so check for empty field
# Weird but the msg["To"] must be a string but the call to the smtp server must be a list
emailto = row.Creator
emailRecList = row.Creator
if row.EmailCopyTo:
emailto = row.Creator + "," + row.EmailCopyTo
emailRecList = emailto.split(',')
# this is full path to pdf to attach
fileToSend = pdfName
# this is just the name without path which becomes the actual name of the attached file
justfileName = baseName + ".pdf"
msg = MIMEMultipart()
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = baseName + " Attached"
msg.preamble = "Where is this"
ctype, encoding = mimetypes.guess_type(fileToSend)
if ctype is None or encoding is not None:
ctype = "application/octet-stream"
maintype, subtype = ctype.split("/", 1)
fp = open(fileToSend, "rb")
attachment = MIMEBase(maintype, subtype)
attachment.set_payload(fp.read())
fp.close()
encoders.encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment", filename=justfileName)
msg.attach(attachment)
server = smtplib.SMTP(emailSMTP)
#server.starttls()
#server.login(smtpusername,smtppassword) # password not needed for here
server.sendmail(emailfrom, emailRecList, msg.as_string())
server.quit()
prt("Sent email " + baseName + " to " + emailto)
# Delete the temp PDF for cleanup
if deleteTempPDF == 1:
os.remove(pdfName)
if markAsEmailed == 1:
# Update the formemailed flag to yes
# Get url of HFS from the layer in the map. Assumes first layer is group of HFS then second is HFS
hfsLayer = arcpy.mapping.ListLayers(mxd)[1]
hfsURL = hfsLayer.dataSource + "/" + "updateFeatures"
# Get token
agolSH = AGOLTokenSecurityHandler(username=AGOusername,password=AGOpassword)
updateAttr = [{"attributes" : {"objectid": row.objectid ,"formemailed" : "yes"}}]
data = {'f': 'json', 'features': updateAttr, 'token' : agolSH.token}
encodedData = urllib.urlencode(data)
request = urllib2.Request(hfsURL, encodedData)
response = urllib2.urlopen(request)
readResponse = response.read()
jsonResponse = json.loads(readResponse)
if not jsonResponse['updateResults'][0]['success']:
prt("FormEmailed field for form " + formName + " at ObjectID " + row.objectid + " was NOT updated successfully!")
ScriptFailed=True
else:
prt( "No recrods found in the Hosted Feature Service. There are no forms to email or not signed in to AGO.\n\n")
ScriptFailed=True
prt("\n")
prt("\n" + "Daily Forms Email Complete: " + time.asctime())
del mxd
except:
PythonMessages("Daily Forms Email Failed")
prt(traceback.format_exc())
prt(arcpy.GetMessages(2))
ScriptFailed=True
Doug,
I am trying to recreate what you are doing with the email of pdf from hfs data collected in survey123. When i am setting up my ddp in arcmap, i am getting empty for a value for my Data Driven Page Attribute fields instead of the data from my hfs.
Have you ran into this? Any ideas?
Thanks,
--gary
First make sure you are logged into AGO in ArcMap. No red exclamation on the HFS.
Second you must login to AGO first then add the HFS. If you open a map with the HFS then login it will not figure out you are now connected. This is my best guess as to your issue.
Third are you adding the filed using Insert -> Dynamic Text -> Data Driven Page Attribute
Then the text box should look like this
<dyn type="page" property="attribute" field="UnitName" domainlookup="true"/>
You should be in layout view.
Doug,
Everything looks the same except we are pulling our data from Portal.
I am logged into portal, added the data from File/ArcGIS Portal window.
Insert/Dynamic Text/Data Driven Page Attribute
Text box looks like this:
I am in layout view.
When I add the same data that has been copied into our SDE, everything works.
Going to have to dig into Portal and see what may be causing this to fail.
Thanks for your response I appreciate your help. If I get this figured out I will elt you know what the problem was.
--gary
Gary H. Bowles
GIS Database Administrator II | Seneca Resources
Office : 412-548-2544 | Cell Phone: 412-334-5273
I have only used AGO for now. I will test if I get a chance. Only thing I can think of is make sure Query is enabled on the HFS.