Impossible to Send Multiple Emails from Gmail after May 30th Update - email

I have code which has remained essentially unchanged for months. The code extracted an email address and email password from an .env file and was used for a few difference cases. Whenever a single user signs up, they would receive an email; and whenever an owner signs many employees up, each of them would receive and email.
The email account we used to send these emails was a Gmail, and was created before the May 30th update and allowed less secure apps access. This allowed it to work sending an individual an email when they signed up, and provided there was a 1 second delay between each employee signed up, it was able to handle the en masse emailing as well.
The email account we use has since been changed, this new email was created after the May 30th update. I jumped through all of the extra hoops to enable less secured apps on this new account, so it sends individual sign up emails with no issue. However, as soon as I attempt to execute the en masse emails (even with the one second delay) I get the following error:
Error: Invalid login: 535-5.7.8 Username and Password not accepted.
Now, this really makes no sense because it is a copy and paste job of the email syntax that DOES work meaning this code below works...
try{
// Creates the Transporter
const transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: `${process.env.SIGNUP_EMAIL}`,
pass: `${process.env.SIGNUP_PASS}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.SIGNUP_EMAIL}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
throw new Error('Something went wrong, please try again \n' + error)
}
})
} catch(error){
console.log(error)
}
But this code DOES NOT (breaks on the first attempt no matter how many others there are after)
try{
const transporter = nodemailer.createTransport({
service: "Gmail",
auth: {
user: `${process.env.SIGNUP_EMAIL}`,
pass: `${process.env.SIGNUP_PASS}`
}
})
// Creates the Mail Object
const mailOptions = {
from: `${process.env.SIGNUP_EMAIL}`,
to: `${actualEmail}`,
subject: `Thank you for joining the TOM Team!`,
text: `We have recieved your Account Signup and are please to welcome you to the TOM Experience! \nUpon recieving this email, you will have a new TOM Account for the mobile app. Please use this email, and the password "${passwordToUse}" to login and get started!`
}
// Sends the mail
transporter.sendMail(mailOptions, (error, response) => {
if (error){
console.log(error)
throw new Error('Something went wrong, please try again \n' + error)
}
})
}
catch(err){
console.log(err)
throw new Error(`Something went wrong emailing ${actualEmail}. Please check this is the proper address.`)
}
Is it just impossible to send gmails en masse now? Even with a 1 second delay? Even if not, why is the very first email failing? I truly have no idea why I'm facing these errors

I'm not sure why this is, but increasing the wait time from 1000 milliseconds to 1500, and then back to 1000 did the trick.
I'm not sure, maybe the new email just needed to get baby-stepped into sending multiple at a time.

Related

Firebase email trigger not working on gmail

I use firebase email trigger and trying to send an email to my gmail account and another account which is not gmail. I received email only on my another account, gmail doesn't work.
Here is my code.
db.collection('mail').add({
to: 'user#gmail.com',
cc: 'user#example.com',
message: {
subject: 'Welcome',
html: 'Hello',
},
})
Here is my mail collection response
Response looks fine.
I received email only on user#example.com account.
I'd be very grateful if some could help me.
Thanks in advance.
The Trigger Email extension for Firebase makes no distinction in how it handles gmail destinations vs other email addresses, so it is very unlikely that this difference happens in the sending of the email.
More likely the email is getting caught in either the spam filter of gmail, or in another spam filter along the way to gmail. I recommend checking your gmail spam box first.
I have changed from email and it works now.
Thanks
Be sure to check in the firebase/firestore itself,
the errors will show in the document itself:
[![error code in firestore][1]][1]
as mentioned, do check your trigger-email settings, that they are linked to the correct collection:
[![collection linked to trigger-email][2]][2]
// Firestore data converter
export const contactFormConvertor = {
toFirestore: (contactform: ContactformDTO) => {
return {
to: <INSERT email you wish to receive the mail on>,
name: contactform._name,
from: <INSERT email you use to send the mail from>,
replyTo: contactform._email,
message: {text: contactform._message + '\n\nkind regards, ' + contactform._name,
subject: contactform._subject}
};
},
fromFirestore: (snapshot: { data: (arg0: any) => any; }, options: any) => {
const data = snapshot.data(options);
return new ContactformDTO(data.name, data.email, data.subject, data.message);
}
};```
[1]: https://i.stack.imgur.com/08cIQ.png
[2]: https://i.stack.imgur.com/m4Sod.png

Application creates classroom invitation, but no email is being sent to student

After creating a classroom invitation the method classroom.create returns with the return status 200 but the user never receives email with the invitation message.
I have given the the client id associated with the service account that I am using, the scopes classroom.roster and mail.google.com, but nothing seems to work.
Am I missing something?
Thank you very much,
Andres
This is the fragment of code that creates the invitation:
//get authorization client
const auth = await google.auth.getClient({
scopes
});
//impersonate teacher account
if (auth instanceof google.auth.JWT) {
auth.subject = 'teacher_email#dom.edu';
}
const options = { auth,
requestBody: {
courseId: '19220887720',
role: 'STUDENT',
userId: 'student_email#dom.edu'
}
};
//send invitation
try {
const invitation = await classroom.invitations.create(options);
console.log('invitation was sent:', invitation);
} catch (err) {
console.error('error: ' , err);
}
Response: status 200.
The invitation is really created. Response includes an invitation id and If you check on the ClassRoom home page->people you can see the correct student was invited.
Based from this forum, students need to have the same settings on in their account, which they may not by default. They should also choose to be a student first.
Also, notification e-mails of Google Classroom are sent from classroom.google.com domain. See Email notifications - Classroom Help for further details.

Parse.com resend verification email

I am using the email verification feature that Parse offers and would like my users to be able to resend the email verification if it fails to send or they cannot see it. Last I saw, Parse does not offer an intrinsic way to do this (stupid) and people have been half-hazzerdly writing code to change the email and then change it back to trigger a re-send. Has there been any updates to this or is changing the email from the original and back still the only way? Thanks
You should only need to update the email to its existing value. This should trigger another email verification to be sent. I haven't been able to test the code, but this should be how you do it for the various platforms.
// Swift
PFUser.currentUser().email = PFUser.currentUser().email
PFUser.currentUser().saveInBackground()
// Java
ParseUser.getCurrentUser().setEmail(ParseUser.getCurrentUser().getEmail());
ParseUser.getCurrentUser().saveInBackground();
// JavaScript
Parse.User.current().set("email", Parse.User.current().get("email"));
Parse.User.current().save();
You have to set the email address to a fake one save and then set it back to the original and then parse will trigger the verification process. Just setting it to what it was will not trigger the process.
iOS
if let email = PFUser.currentUser()?.email {
PFUser.currentUser()?.email = email+".verify"
PFUser.currentUser()?.saveInBackgroundWithBlock({ (success, error) -> Void in
if success {
PFUser.currentUser()?.email = email
PFUser.currentUser()?.saveEventually()
}
})
}
Poking around the source code for Parse server, there doesn't seem to be any public api to manually resend verification emails. However I was able to find 2 undocumented ways to access the functionality.
The first would be to use the internal UserController on the server (for instance from a Cloud function) like this:
import { AppCache } from 'parse-server/lib/cache'
Cloud.define('resendVerificationEmail', async request => {
const userController = AppCache.get(process.env.APP_ID).userController
await userController.resendVerificationEmail(
request.user.get('username')
)
return true
})
The other is to take advantage of an endpoint that is used for the verification webpage:
curl -X "POST" "http://localhost:5000/api/apps/press-play-development/resend_verification_email" \
-H 'Content-Type: application/json; charset=utf-8' \
-d $'{ "username": "7757429624" }'
Both are prone to break if you update Parse and internals get changed, but should be more reliable than changing the users email and then changing it back.
We were setting emails to an empty string, but found that there was a race condition where 2 users would hit it at the same time and 1 would fail because Parse considered it to be a duplicate of the other blank email. In other cases, the user's network connection would fail between the 2 requests and they would be stuck without an email.
Now, with Parse 3.4.1 that I'm testing, you can do (for Javascript):
Parse.User.requestEmailVerification(Parse.User.current().get("email"));
BUT NOTE that it will throw error if user is already verified.
Reference:
http://parseplatform.org/Parse-SDK-JS/api/3.4.1/Parse.User.html#.requestEmailVerification
To resend the verification email, as stated above, you have to modify then reset the user email address. To perform this operation in secure and efficient way, you can use the following cloud code function:
Parse.Cloud.define("resendVerificationEmail", async function(request, response) {
var originalEmail = request.params.email;
const User = Parse.Object.extend("User");
const query = new Parse.Query(User);
query.equalTo("email", originalEmail);
var userObject = await query.first({useMasterKey: true});
if(userObject !=null)
{
userObject.set("email", "tmp_email_prefix_"+originalEmail);
await userObject.save(null, {useMasterKey: true}).catch(error => {response.error(error);});
userObject.set("email", originalEmail);
await userObject.save(null, {useMasterKey: true}).catch(error => {response.error(error);});
response.success("Verification email is well resent to the user email");
}
});
After that, you just need to call the cloud code function from your client code. From Android client, you can use the following code (Kotlin):
fun resendVerificationEmail(email:String){
val progress = ProgressDialog(this)
progress.setMessage("Loading ...")
progress.show()
val params: HashMap<String, String> = HashMap<String,String>()
params.put("email", email)
ParseCloud.callFunctionInBackground("resendVerificationEmail", params,
FunctionCallback<Any> { response, exc ->
progress.dismiss()
if (exc == null) {
// The function executed, but still has to check the response
Toast.makeText(baseContext, "Verification email is well sent", Toast.LENGTH_SHORT)
.show()
} else {
// Something went wrong
Log.d(TAG, "$TAG: ---- exeception: "+exc.message)
Toast.makeText(
baseContext,
"Error encountered when resending verification email:"+exc.message,
Toast.LENGTH_LONG
).show()
}
})
}

Send mail for multiple user and the each recipents have only his email address not the others

I am new bie for send grid. I have checked this url for two emails "https://sendgrid.com/api/mail.send.js..." and got the mail successfully in both emails.
The mail received by the users from the above URL have both email address in "TO" field like
For ex. User Test To: test#example.com;test2#example.com. and For User test2 To: test#example.com;test2#example.com.
As per my requirement i want to send mail for multiple user and the each recipents have only his email address not the others.
For ex. User Test To: test#example.com and For User test2 To: test2#example.com.
Can this scenario is possible with send grid.
Thanks
You can send the same email to multiple recipients by using the SendGrid SMTP API's to parameter.
To do this you'll set an X-SMTPAPI: header in your message, this header will include the JSON to communicate with SendGrid's SMTP API. The header will look as such:
X-SMTPAPI: { "to": [ "test#example.com", "test2#example.com" ] }
Each recipient will receive a unique email, addressed only to them.
Be aware: you'll still need to set a To: header for the message to send, however you can set this to yourself or one of the recipients (and then exclude them from the JSON list).
Send grid being a standard SMTP server will respond as if you are sending email from gmail, yahoo or outlook.
The scenario is not possible that I am aware of. I have only incorporated it into 2 applications, so I am certain there are better experts.
As an alternative you could test using the blind copy, The problem with that is would need a main address in the To field, which may not fill your requirement.
Send email on Azure Mobile Service /NodeJS
var sendgrid = new SendGrid('KEY');
sendgrid.send({
to: toEMail, // ["email1#mail.com", "email2#mail.com",...]
from: fromEMail,
subject: subject,
text: body
}, function (success, message) {
console.log("send mail: " + subject);
// If the email failed to send, log it as an error so we can investigate
if (!success) {
console.error(message);
}
});
possible on Sendgrid. You can use the normal bcc on sendgrid via personalization, but we dont like it because the To: is always required. So my solution is sendgrid transactional email. This will send 1 email to multiple users (using sendgrid / php / laravel ):
$email = new \SendGrid\Mail\Mail();
$email->setFrom("sender#mail.com", "Sender Name");
$email->setSubject("Your subject");
$email->addTo(
"email.1#mail.com",
"User One",
[],
0
);
$email->addTo(
"email.2#mail.com",
"User Two",
[],
1
);
$email->addTo(
"email.3#mail.com",
"User Three",
[],
2
);
$email->addContent("text/plain", "your body");
$email->addContent("text/html", "<strong>your body</body>");
$sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY'));
try {
$response = $sendgrid->send($email);
return response()->json($response, 200);
} catch (Exception $e) {
return response()->json($e->getMessage(), 400);
}

verify email using accounts.ui package

I want to send a verification email when some user is created. I use the accounts-password package, so any Accounts methods are called in my code.
I read in documentation that I need to call:
Accounts.sendVerificationEmail(userId, [email])
but the problem is that I don't know when to call it.
I tried to call in the callback function of Accounts.onCreateUser(func) but the user had not been created yet in the database.
Any ideas?
on the serverside:
Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});
got the answer from the comments above.
sendVerificationEmail is only available server-side. What I usually do is to use a setInterval inside onCreateUser to wait for Meteor to create the user before sending an email.
Read More: Verify an Email with Meteor Accounts.
// (server-side)
Accounts.onCreateUser(function(options, user) {
user.profile = {};
// we wait for Meteor to create the user before sending an email
Meteor.setTimeout(function() {
Accounts.sendVerificationEmail(user._id);
}, 2 * 1000);
return user;
});
You need specify mail in enviroment variables.
Then use Accounts.sendVerificationEmail(userId, [email]) in callback of Account.onCreateUser sorry for mistake and delay.
Like this (below is full example js file):
Template.register.events({
'submit #register-form' : function(e, t) {
e.preventDefault();
var email = t.find('#account-email').value
, password = t.find('#account-password').value;
// Trim and validate the input
Accounts.onCreateUser({email: email, password : password}, function(err){
if (err) {
// Inform the user that account creation failed
} else {
// Success. Account has been created and the user
// has logged in successfully.
Accounts.sendVerificationEmail(this.userId, email);
}
});
return false;
} });
if(Meteor.isServer){
Meteor.startup(function(){
process.env.MAIL_URL='smtp://your_mail:your_password#host:port'
}
}
I refered to this pages :
http://blog.benmcmahen.com/post/41741539120/building-a-customized-accounts-ui-for-meteor
http://sendgrid.com/blog/send-email-meteor-sendgrid/
How come my Meteor app with accounts package is not sending a verification email?