Order of emails is changed when sending multiple emails with CFMail - coldfusion

I have an issue while sending the below two emails through CF 2016. When I run my code I'm receiving the "Password" email first and then the "Username" mail second. The order of sending is getting changed. I need to get "Username" mail first and then "Password" mail. How can I resolve this?
<cfmail to="#toEmail#" from="#fromEmail#" subject="Username" type="html">
Your username is #username#
</cfmail>
<cfmail to="#toEmail#" from="#fromEmail#" subject="Password" type="html">
Your password is #password#
</cfmail>

You can disable mail spooling on a per cfmail basis with spoolEnable. It does slow down the page though. Try it on only the first email. That will send out the first email immediately. Then let the second email get spooled for idle/later delivery.
<cfmail to="#toEmail#" from="#fromEmail#" subject="Username" type="html" spoolEnable="no">
Your username is #username#
</cfmail>
<cfmail to="#toEmail#" from="#fromEmail#" subject="Username" type="html">
Your username is #username#
</cfmail>

You could always to do something like this:
<cfmail to="#toEmail#" from="#fromEmail#" subject="Username" type="html">
Your username is #username#
</cfmail>
<cfthread name="SendPassword" action="run">
<cfscript>
sleep(appropriate number of milliseconds);
</cfscript>
<cfmail to="#toEmail#" from="#fromEmail#" subject="Password" type="html">
Your password is #password#
</cfmail>
</cfthread>
Look at your spool settings to get the appropriate number of milliseconds.

Related

this.smtpServersettings is sending mail to undelivered options instead of gmail

I want to send a email to real gmail ID's to the end users. So I used smtp.gmail.com as mail server with my own email user name & password. But if I use this.smtpServersettings in my application.cfc it's not sending a email. All the mail's are went to undelivered options. My sample code,
App.cfc :
<cfset this.name='mailfn8'>
<cfset this.smtpServersettings={server:"smtp.gmail.com",username:"mygmail#gmail.com",password:"mypassword"}>
My.cfm :
<cfmail from='sender#gmail.com' to='receiver#gmail.com' subject='test' type='html' port="587" usetls="true">
I'm seding a email by using this.smtpServersettings options.
</cfmail>
But the credentials are working great in below scenario,
-- If I set my details in application scope and use that values in cfmail tag
-- Directly set it in coldfusion mail server setting
For example,
App.cfc :
<cfset this.name='mailfn8'>
<cffunction name='onApplicationStart'>
<cfset application.server='smtp.gmail.com'>
<cfset application.username='mygmail#gmail.com'>
<cfset application.password='mypassword'>
</cffunction>
My.cfm :
<cfmail from='sender#gmail.com' to='receiver#gmail.com' server= '#application.server#' username='#application.userName#' password='#application.password#' subject='test' type='html' port="587" usetls="true">
I'm seding a email by using application scope.
</cfmail>
The above working fine. So why this.smtpServersettings is send email to undelivered option instead of gmail. ? .Do I need to enable any other setting if I use this.smtpServerSetting ? Please help me on this. Correct me if I'm understood anything wrong. Thank you !.
The smtpServerSettings struct does not support port and usetls.
https://tracker.adobe.com/#/view/CF-4204467
My suggestion is to create your own struct in application scope then pass to cfmail tag with argumentCollection attribute.

If Else query is empty

I am using CFLDAP to have users get authenticated using active directory. I am trying to write an if statement in case the users information does not come back as authenticated. I thought I could check by using <cfif AuthenticateUser.RecordCount gt 0> which is working as long as the information is correct but if the wrong information is entered and nothing is authenticated it is not running the else statement. Any help with this would be greatly appreciated!
<cfldap action="query"
name="AuthenticateUser"
attributes="dn,mail,givenname,sn,samaccountname,memberof"
start="DC=domain,DC=net"
filter="(&(objectclass=user)(samAccountName=#trim(form.user_name)#))"
server="servername"
Port="389"
username="tc\#trim(form.user_name)#"
password="#trim(form.user_pass)#">
<cfoutput>#AuthenticateUser.RecordCount#</cfoutput>
<!--- Get all records from the database that match this users credentials --->
<cfquery name="userVerify" datasource="test">
SELECT *
FROM dbo.Users
WHERE user_name = <cfqueryparam value="#AuthenticateUser.samaccountname#" cfsqltype="cf_sql_varchar" />
</cfquery>
<cfif AuthenticateUser.RecordCount gt 0>
<!--- This user has logged in correctly, change the value of the session.allowin value --->
<cfset session.allowin = "True" />
<cfset session.employee_number = userVerify.employee_number />
<!--- Now welcome user and redirect to "index.html" --->
<script>
self.location="../dashboard/dashboard.cfm";
</script>
<cfelse>
<!--- this user did not log in correctly, alert and redirect to the login page --->
<script>
alert("Your credentials could not be verified, please try again!");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
I have also tried: <cfif len(AuthenticateUser)>
This is how I do it. I try to run a query against our domain using the supplied username and password. If the supplied username and password are not valid, an error is generated.
<cftry>
<cfldap action="Query"
name="ADResult"
attributes="dn"
start="DC=domain,DC=net"
filter="sAMAccountName=administrator"
server="servername"
scope = "subtree"
username="#arguments.username#"
password="#arguments.password#" />
<cfset isAuthenticated = true />
<cfcatch type="any">
<cfset isAuthenticated = false />
</cfcatch>
</cftry>
<cfreturn isAuthenticated />
I wrap this up in a function called "authenticate" and expose it via a web service that I call from my apps. If I then need additional details about the user (mail, givenName, etc), I have another function in the same web service that I will call after I am sure the user has been authenticated. Note that in this other function I'm using my administrator username and password to run the query.
<cfldap action="Query"
name="ADResult"
attributes="mail,givenName"
start="DC=domain,DC=net"
filter="sAMAccountName=#arguments.username#"
server="servername"
scope = "subtree"
username="administrator"
password="myAdminPassword" />
I take the results of this, populate a query object or a structure, and return that to the calling function.
So the entire process sort of looks like this:
<cfset objAD = createobject("webservice", "http://mywebservice.com") />
<cfset isAuthenticated = objAD.authenticate(form.username, form.password) />
<cfif isAuthenticated>
<cfset userDetails = objAD.getUserDetails(form.username)>
</cfif>
Hope this helps.
This is a formatted comment. You are trying to do too much at once. Go one step at a time. Start with this:
<cfdump var="before cfldap tag<br />">
<cfldap action="query"
name="AuthenticateUser"
etc
>
<cfdump var="after cfldap tag<br />">
<cfdump var = "#AuthenticateUser#">
<cfdump var="after cfdump<br />">
Run this code with both valid and not valid credentials. Look at what you get. React accordingly.
I think it throws an error when the query fails. Try this:
<cftry>
<cfldap action="query"
name="AuthenticateUser"
attributes="dn,mail,givenname,sn,samaccountname,memberof"
start="DC=domain,DC=net"
filter="(&(objectclass=user)(samAccountName=#trim(form.user_name)#))"
server="servername"
Port="389"
username="tc\#trim(form.user_name)#"
password="#trim(form.user_pass)#">
<cfset LoginStatus = "Success">
<cfcatch type="any">
<cfset LoginStatus = "Failed">
</cfcatch>
</cftry>
Then your cfif would be something like this:
<cfif LoginStatus eq "Success">
<!--- This user has logged in correctly, change the value of the session.allowin value --->
<cfset session.allowin = "True" />
<cfset session.employee_number = userVerify.employee_number />
<!--- Now welcome user and redirect to "index.html" --->
<script>
self.location="../dashboard/dashboard.cfm";
</script>
<cfelse>
<!--- this user did not log in correctly, alert and redirect to the login page --->
<script>
alert("Your credentials could not be verified, please try again!");
self.location="Javascript:history.go(-1)";
</script>
</cfif>
I think this works on CF9.

How do I attach a file from a server in a mail using coldfusion8?

This is my code to get the file from user and attach it to the mail.
<cfset destination = expandPath('Uploads/')>
<cffile action='upload' filefield='file_upload' destination='#destination#' result='upload' >
<cfmail to="id" from="id" subject="test">
<cfmailparam file="destination">
</cfmail>
When I run this I get an error, The resource destination was not found.
Could you please help?
You can do some thing like this
<cfset destination = expandPath('Uploads/')>
<cffile action='upload' filefield='file_upload' destination='#destination#' result='upload' >
<cfmail to="#id#" from="#id#" subject="test">
<cfmailparam file="#destination#/#upload.serverFile#" >
</cfmail>
For more information you can see cfmailparan and cffile action="upload"

Confusion on when to use cfoutput in cfmail

I am not 100% on when to use cfoutput and how cfoutput can be used in the following example. Should the whole cfmail be wrapped in a cfoutput?
Background: I have a function that sends an email based on an if statement. The message of the email has variables that come from a cfquery.
<cffunction name="emailUpdate" access="public" returntype="string">
<cfargument name="usr_email" required="yes">
<cfargument name="status_update" required="yes">
<cfargument name="form_id" required="yes">
<cfquery name="emailformData" datasource="RC">
SELECT *
FROM Basic_Info
WHERE ID = <cfqueryparam value="#ARGUMENTS.form_id#">
</cfquery>
<cfoutput query="emailformData">
<cfmail
from="forms#email.us"
to="#usr_email#"
subject="Status Update">
<cfif status_update EQ 'Submitted'>
Form Submitted: The following quote request ID: #emailformData.ID# has been submitted on
#emailformData.Submission_Date# for the following party #emailformData.Sold_to_Party#. You will receive automated
updates via email when your submission changes status. <b>- Admin Team</b>
<cfelseif status_update EQ 'Assigned'>
Form Assigned by Admin Request ID: #emailformData.ID# for the following party #emailformData.Sold_to_Party# was
assigned to Admin ID #emailformData.Admin_ID# on #DateFormat(Now())#, #TimeFormat(Now())#.
Below is their direct contact information for any change requests or status updates. <b>- Admin Team</b>
<cfelseif status_update EQ 'Returned'>
Returned by Admin Form ID: #emailformData.ID# for the following party #emailformData.Sold_to_Party# was
returned by Admin ID #emailformData.Admin_ID# on #DateFormat(Now())#, #TimeFormat(Now())#
for the following reasons. Admin Notes: #emailformData.Admin_Notes#.
<b>- Admin Team</b>
<cfelseif status_update EQ 'Completed'>
Form Completed Form ID: #emailformData.ID# for the following party #emailformData.Sold_to_Party# has been
marked as COMPLETED on #DateFormat(Now())#, #TimeFormat(Now())#. The following Quote Number has been
assigned to this form #emailformData.Quote_Num#. The quote will be emailed to you. If the Admin added any closing notes to the form they will appear below:
#emailformData.Admin_Notes#
<b>- RFQ Admin Team</b>
</cfif>
</cfmail>
</cfoutput>
</cffunction>
You don't need it, unless perhaps you're doing looped output of a cfquery. e.g. if your emailformData query returned multiple rows (and it obviously doesn't), you might do:
<cfmail ...>
Here's the email data #form.name# asked for:
<cfoutput query="emailformData">
#emailformData.Sold_to_Party#
</cfoutput>
Sent on #dateFormat(now())#
</cfmail>
See Sample uses of the cfmail tag on the Adobe site, and this discussion on Ray Camden's site

ColdFusion Try Catch on loop through mail function

I've got a list of email addresses that an email is sent to. The mail function loops through the list from the database but if it encounters a malformed email address, it halts and breaks out of the loop. I've tried using try/catch to catch the error and was hoping it'd continue through the loop but it's not worked as I'd hoped. The code is below. If anyone has any ideas, or maybe a regex that I can sift through the email addresses before the loop to filter out bad ones, that'd be awesome.
Thanks.
<!---Try to send the mail(s)--->
<cftry>
<cfmail to="<#Auctioneer.email#>" from="#emailSite#" subject="#Email.subject#" server="#emailServer#" query="Auctioneer" type="html">
<!---Some email content--->
</cfmail>
<cfcatch type="Application">
<cflog text="#cfcatch.detail#" file="mail" type="Error" application="yes">
<cfmail to="admin#website.co.uk" from="#emailSite#" subject="Invalid E-Mail Address" type="html">
Email address not valid error.
#Auctioneer.email#
<cfdump var="#cfcatch.detail#">
</cfmail>
</cfcatch>
</cftry>
What you want is to loop through the addresses, validate them and send mails only for valid entries. Something like this
<cfloop query="getEmails">
<cfif isValid("email", Auctioneer.email)
...send valid email...
<cfelse>
...send invalid email, or better log in database...
</cfif>
</cfloop>
P.S. No need to put <> in to.
You could try validating the e-mail addresses in the query first.
For me, though, I never liked having the CFMAIL tag manage the query. It always seemed to cause more trouble than it's worth. I usually do something like this:
<cfoutput query="Auctioneer">
<cftry>
<cfmail to="#email#" from="#variables.emailSite#" subject="#variables.subject#" server="#application.emailServer#" type="html">
<!---Some email content--->
</cfmail>
<cfcatch type="Application">
<cflog text="#cfcatch.detail#" file="mail" type="Error" application="yes">
<cfmail to="admin#website.co.uk" from="#variables.emailSite#" subject="Invalid E-Mail Address" type="html">
Email address not valid error.
#email#
<cfdump var="#cfcatch.detail#">
</cfmail>
</cfcatch>
</cftry>
</cfoutput>
I would personally loop through them, catch the error and continue the loop.
for(var i = 1; i < Auctioneer.recordCount; i++) {
try {
//send email
} catch (Any e) {
//log
continue;
}
}