With Google App Maker, I can make a form. I can create a Submit button that emails to a particular email address. And I can pass individual field values into the email.
But I want to be able to send the whole completed form exactly how it looks when the user fills out the form in the email. (If need be, sending it as an image is okay. But sending it as an editable form is even better.)
Server script function that will allow you to embed images into a message
function sendEmail(recipient, subject, body, options) {
var ImageBlob = DriveApp
.getFileById('id')
.getBlob()
.setName("ImageBlob");
GmailApp.sendEmail(recipient, subject, body, {
htmlBody: options.html,
inlineImages: { image: ImageBlob }
});
// Parameters :
// sendEmail(recipient, subject, body)
// Name Type Description
// recipient String Comma separated list of email addresses
// subject String Subject of the email
// body String Body of the email
}
Related
I am working on a web app with an existing user base. Email verification was not initially implemented in the sign in flow.
I have successfully added code for sending verification email for all new sign ups but I also wanted to make a small page (or modal) where current users would be shown a button that would send the verification link to their inbox
The current sign up flow where I created the user with createUserWithEmailAndPassword I was able to get access to the user.user.sendEmailVerification method to do so, but cannot find any way to access this method to implement the feature for existing users.
Is there a way to access the sendEmailVerification method after the user has been created?
I am assuming that it would be available within the onAuthStateChange trigger but implementing that would lead to a bad UX (as I do not want to prompt the users everytime they login)
Edit:
I know the documentation states that we can use the firebase.auth().currentUser to get the current user but that, for some reason did not work.
Also, I found references online suggesting to no longer use that method and they mentioned to use the onAuthStateChange method instead, which is why I was looking into that approach
You can try this method:
const btnVerifyEmail = document.getElementById("btn-verify-id")
btnVerifyEmail.onclick = function () {
const user = firebase.auth().currentUser;
user.sendEmailVerification().then(function() {
// Email sent.
console.log("Email Sent")
}).catch(function(error) {
// An error happened.
console.log(error)
});
}
It's mentioned in the documentation right here
The sendEmailVerification() should not be called in the onAuthStateChanged event because it would blast out an email on every page load if the user's email isn't verified.
You should instead display a notification on the page if User.emailVerified is false that contains a link to send the user an email.
Here's a working example:
// On page load watch for auth state changes
firebase.auth().onAuthStateChanged(function(user) {
// If the user is logged in
if (user) {
// If the user's email isn't verified
if (!user.emailVerified) {
// Show the notification bar that informs the user that they need to validate
// their email by clicking a link. Let's pretend the link looks like this:
// Send me a verification email
showNotification();
}
}
});
// Function attached to your link's onclick event
function sendEmailVerification() {
// Retrieve the current user
const user = firebase.auth().currentUser;
// If user's email is already verified, exit
if (user.emailVerified) {
return;
}
// Tell Firebase to send the verification email and discard the promise
user.sendEmailVerification().then().catch();
}
Dharmaraj's answer is good but this is a full example.
I want to send an email with a content related to my data such as in following piece of code I found on Datasource script of Google AppMaker Project Tracker template. But I don't understand how it works. How that data.modifiedBy reflect to the record in my datasource?
Any help from the floors? Thanks ..
Look at the Notifications server side script in the template.
It has method notifyAboutItemChanges_ which is passing the data to this record.
function notifyAboutItemChanges_(changes) {
var settings = getAppSettingsRecord_()[0];
if (!settings.EnableEmailNotifications) {
return;
}
var data = {
appUrl: settings.AppUrl,
itemType: changes[0].Type,
itemKey: changes[0]._key,
itemName: changes[0].Name,
modifiedBy: changes[0].ModifiedBy,
changes: changes
};
// Email subject.
var subjectTemplate =
HtmlService.createTemplate(settings.NotificationEmailSubject);
}
This function is passing this data to your settings record.
So no magic here :) You need to pass the data to your record which will be replaced at run time with the values.
For more details on Email refer this sample app.
A Meteor web app being used by a logged in user "merchant" who needs to create a link and sms/email it to his customer. The link opens a form. The customer fills up the form and submits it so that the data gets inserted with a property merchantId, since many merchants can send to many customers.
This single page app is not using a Router but able to sms/email. How can linking a form between a merchant and a customer be accomplished elegantly so that the data from the correct customer gets "linked" to the correct merchant? Thanks
Merchant Part
You can trigger after a successful send of the email/sms a meteor method, that stores a record of the sent email/sms in a collection (in this example named Record). This could be the schema for it:
Record Collection Schema (Server/Client)
{
merchantId:String, // the id of the sender
customer:String, //id or name or address or phone num of receiver
opened:Boolean, //when the link is opened can be set to true
link:String, // the link to be send,
type:Number, //0=sms, 1=email,
expires:Date, //in case the link is not opened
}
You can for example create a Meteor method to insert the record after send:
Insert Record (Server)
Meteor.methods({
insertRecord:function(recordData) {
//... check recordData by schmema and permissions here
return Records.insert(recordData);
}
})
Sending the Email/SMS
So the merchant part of the app sends the link via sms/email and calls the insertRecord method to store the record of the saved .
Save Record (Client or Server)
const callback=function(err, res) {
if (res) { // assume your sent was successful here
Meteor.call("insertRecord", {
//... your record credentials
});
}
}
// a little bit of pseudocode
if (sms)
sms.send(form, callback);
else
email.send(form, callback);
Customer Part
When the customer opens the link it triggers a templatethat will render your form. You can initially run a meteor method to check the Record collection for a document that matches the link url.
Get Record by Url Method (Server)
Meteor.methods({
getRecordByUrl:function(url) {
//... do your input checks here
return Records.findOne({link:url});
},
});
Template for Form (Client)
Template.customerForm.onCreated(function(){
const instance = this;
instance.state = new ReactiveDict();
instance.state.set("record", null);
instance.autorun(function(){
// if no record loaded yet
if (!instance.state.get("record")) {
Meteor.call("getRecordByUrl", window.location.href, function(err, res) {
if (err || !res) {
//...handle err
}
this.state.set("record", res);
}.bind(instance));
}
});
});
Template.customerForm.helpers({
getRecord() {
return Template.instance().state.get("record");
},
getMerchantId() {
const record = Template.instance().state.get("record");
return record.merchantId;
}
});
You can then use this document to add the merchantId to the form either as a hidden input or via html data attribute.
{{#if getRecord}}
<form id="...">
<input type="hidden" name="merchantId" value="{{getMerchantId}}" />
<!-- other inputs here -->
</form>
{{/if}}
The examples can of course be optimized but I think this way it clearer to understand.
At the moment this is a general question with no code as I am looking for a BEST practices example to my question:
User issues an email change request. (done)
A link is sent to the new address to confirm the new email. (done)
User clicks the confirmation link and the DB update is complete. (done)
What also needs to happen is when the confirmation link is sent for the change, an email should also be sent to the original email address where the user can click a link to reverse the process for whatever reason. I would think also that even if the new email address was accepted, if the original link denies the change it reverts and 2) if the original email reverts and then the new email link is confirmed, that the request would then be denied.
Any direction or code on this matter would be greatly appreciated.
Seems like a simple bit field in the database user record would suffice, or an associated database record would work too. When both emails are sent, mark the field for that user, let's call it "ChangeEmailSent" to 1. When either email is clicked, the field should be updated to 0. The actual changing of the email should only occur if the field is 1.
Some pseudo-code if you like
private void CancelEmailChange(email)
{
var user = Database.GetUser(email);
user.ChangeEmailSent = false;
Database.Save();
}
private void ProcessEmailChange(email)
{
var user = Database.GetUser(email);
if (user.ChangeEmailSent)
{
user.email = getNewEmailAddress(); //whatever logic for a new email
user.ChangeEmailSent = false;
Database.Save();
}
}
I want to check address filed have correct address then send email. My code working but i want to execute my code after contact from 7 validation. if my code return true then form will submit and send email otherwise show alert and should not be submit.
$('.wpcf7-submit').on('click', function (e) {
var address = $('input[name="your-address"]').val();
//e.preventDefault();
if(city !=="") {
jQuery.post(gs_cf7_url, {data:address, action:'gs_cf7_check_lat_lag'}, function (response){
if(response=="no") {
alert('Sorry we couldnt find the location');
} else {
//$(".wpcf7-submit").unbind("submit").submit();
//$(".wpcf7-submit").unbind("submit");
}
});
}
});
I am looking a hook such as add_action('wpcf7_before_send_mail', 'save_form'); if there as any javascript hook?
The logic of Contact From 7 is as follows. On Submit click it fires ajax, performs all validation in php code and returns to js internal function $.wpcf7AjaxSuccess = function(data, status, xhr, $form). This function checks data.invalids and if true, shows error message(s).
This means it is too late to perform your checks after Contact Form 7 validation, because when php code accepts all data as valid, it sends email and returns control to $.wpcf7AjaxSuccess.
As a workaround, you can mark address field as required in CF7, monitor .focusout() event on your field (input[name="your-address"]) and clear it if address entered is not valid. On submit click, CF7 will not send the email then and will require your field.
Try to change your code in this way:
$('input[name="your-address"]).focusout( function () {
var address = $('input[name="your-address"]').val();
//e.preventDefault();
if(city !=="") {
jQuery.post(gs_cf7_url, {data:address, action:'gs_cf7_check_lat_lag'}, function (response){
if(response=="no") {
alert('Sorry we couldnt find the location');
$('input[name="your-address"]').val('');
} else {
//$(".wpcf7-submit").unbind("submit").submit();
//$(".wpcf7-submit").unbind("submit");
}
});
}
});
I didn't check it since I don't have other pieces of your code (gs_cf7_check_lat_lag), so please treat it as idea how to make a workaround.