Pour notre application Web, nous utilisons actuellement le plan gratuit de Firebase et devons envoyer des e-mails sur divers événements/déclencheurs. Le problème est que je pensais que Mailgun fonctionnerait parfaitement pour cette tâche avec leurs fonctions cloud, mais il semble qu'il soit possible d'utiliser leur API uniquement avec le plan payant de Firebase que nous n'avons pas l'intention d'utiliser pour le moment lorsque notre application est encore en développement. . Donc, nous sommes en quelque sorte coincés sans savoir comment implémenter la fonctionnalité de messagerie avec Firebase avec un montant minimum (nous pouvons toujours payer ou payer plus quand nous sommes un peu clairs sur la rentabilité de notre application). .. Est-ce que quelqu'un peut m'aider.
Merci! Piyush Soni
J'utilise l'hébergement Firebase et les fonctions cloud dans mon site de portfolio personnel. J'ai créé une fonction cloud (événement http) pour envoyer des emails depuis la section formulaire de contact, je n'ai pas activé l'option de facturation mais le devis gratuit (exécutions de la fonction cloud) est toujours suffisant pour mes besoins actuels. J'envoie des e-mails de la manière suivante:
Fonction cloud:
const functions = require('firebase-functions');
const nodemailer = require('nodemailer');
const rp = require('request-promise');
//google account credentials used to send email
const mailTransport = nodemailer.createTransport(
`smtps://[email protected]:[email protected]`);
exports.sendEmailCF = functions.https.onRequest((req, res) => {
//recaptcha validation
rp({
uri: 'https://recaptcha.google.com/recaptcha/api/siteverify',
method: 'POST',
formData: {
secret: 'your_secret_key',
response: req.body['g-recaptcha-response']
},
json: true
}).then(result => {
if (result.success) {
sendEmail('[email protected]', req.body).then(()=> {
res.status(200).send(true);
});
}
else {
res.status(500).send("Recaptcha failed.")
}
}).catch(reason => {
res.status(500).send("Recaptcha req failed.")
})
});
// Send email function
function sendEmail(email, body) {
const mailOptions = {
from: `<[email protected]>`,
to: email
};
// hmtl message constructions
mailOptions.subject = 'contact form message';
mailOptions.html = `<p><b>Name: </b>${body.rsName}</p>
<p><b>Email: </b>${body.rsEmail}</p>
<p><b>Subject: </b>${body.rsSubject}</p>
<p><b>Message: </b>${body.rsMessage}</p>`;
return mailTransport.sendMail(mailOptions);
}
Mise à jour comprenant le formulaire de contact et les scripts:
<form class="rsForm" action="/sendEmailCF" method="post">
<div class="input-field">
<label>Name</label>
<input type="text" name="rsName" value="">
<span class="line"></span>
</div>
<div class="input-field">
<label>Email</label>
<input type="email" name="rsEmail" value="">
<span class="line"></span>
</div>
<div class="input-field">
<label>Subject</label>
<input type="text" name="rsSubject" value="">
<span class="line"></span>
</div>
<div class="input-field">
<label>Message</label>
<textarea rows="4" name="rsMessage"></textarea>
<span class="line"></span>
</div>
<input type="hidden" name="rsLang" value="en" />
<span class="btn-outer btn-primary-outer ripple">
<input class="formSubmitBtn btn btn-lg btn-primary" type="submit" data-recaptcha="global" value="Send">
</span>
<div id="recaptcha-global"></div>
</form>
Script pour gérer le formulaire:
$('.formSubmitBtn').on('click', function (e) {
glForm = $(this).closest('.rsForm');
var recaptchaId = 'recaptcha-' + $(this).data('recaptcha');
var rsFormErrors = false;
glFormAction = glForm.attr('action');
var rsFormFields = glForm.find('.input-field');
var rsFormName = glForm.find("[name='rsName']");
var rsFormEmail = glForm.find("[name='rsEmail']");
var rsFormMessage = glForm.find("[name='rsMessage']");
// Button ripple effect
ripple($(this).parent(), e.pageX, e.pageY);
// Reset form errors
rsFormFields.removeClass('error');
rsFormErrors = false;
// Validate form fields
if(!rsFormName.val()) {
rsFormErrors = true;
rsFormName.parent().addClass('error');
}
if(!rsFormEmail.val() || !isValidEmail(rsFormEmail.val())) {
rsFormErrors = true;
rsFormEmail.parent().addClass('error');
}
if(!rsFormMessage.val()) {
rsFormErrors = true;
rsFormMessage.parent().addClass('error');
}
if(rsFormErrors) {
// if has errors - do nothing
return false;
} else {
if(rca[recaptchaId] === undefined){
rca[recaptchaId] = grecaptcha.render(recaptchaId, {
'sitekey' : 'sitekey',
'callback' : onExecutedCaptcha,
'size' : 'invisible',
'badge':'inline'
});
} else {
grecaptcha.reset(rca[recaptchaId]);
}
grecaptcha.execute(rca[recaptchaId]);
return false;
}
});
Script pour gérer la réponse recaptcha et la publication du formulaire:
function onExecutedCaptcha(token) {
var sendingMsg = null, textMsg = null, textErr = null;
var lang = glForm.find("[name='rsLang']").val();
if(lang == 'es') {
sendingMsg = 'Enviando mensaje...';
textMsg = 'Tu mensaje se ha enviado con \u00e9xito!';
textErr = 'Algo ha salido mal. Intenta mas tarde';
} else {
textMsg = 'Your email was sent successfully!';
textErr = 'Oops! Something went wrong. Please try again.';
sendingMsg = 'Sending email...';
}
swal({
text: sendingMsg,
button: false,
closeOnClickOutside: false,
closeOnEsc: false,
});
$.post( glFormAction,
glForm.serialize(),
function (response) {
grecaptcha.reset();
var data = jQuery.parseJSON( response );
swal.close();
if(data){
swal({
text: textMsg,
icon: "success",
});
glForm.find("input[type=text], input[type=email], textarea").val("");
} else {
swal({
text: textErr,
icon: "error",
});
}
}
);
}
Si vous passez au plan Blaze, vous ne serez facturé que pour ce que vous utilisez et pour les fonctions cloud en particulier, vous obtiendrez toujours le nombre d'exécutions gratuites.
Je ne connais pas les détails de votre application, mais pendant le développement de la plupart des applications, il est peu probable que vous encouriez plus de quelques dollars par mois en frais (et potentiellement seulement quelques centimes).