onCreate send email to self in AppMaker? - google-app-maker

Still learning about app maker and found this presentation at Google I/O '17 "Build Powerful Custom Apps Fast with App Maker on G Suite"
At timestamp 15.24 sec some code is shown on the screen showing how to send an email to yourself once someone creates a new item can.
https://youtu.be/Q84HQgI3Dd8?t=15m27s
Question
Can anyone advise where and how this code can be implemented its pretty cool and would be a great feature to add when a record is created
Thanks in advance and no worries if you cant help

You are looking for model events:
https://developers.google.com/appmaker/models/events
In App Maker models typically have onCreate, onSave, onLoad, onDelete events. It is the best place to handle email notifications. Here is a link to App Script email API:
https://developers.google.com/apps-script/reference/mail/mail-app

I strongly recommend you to go to the Codelab for App Maker. The section Building a form to send an email describes the whole process.
The steps to highlight are:
Step 11 - Set the onClick property of the button as a custom action with the code:
var widgets = widget.parent.descendants;
var to = widgets.To.value;
var subject = widgets.Subject.value;
var msg = widgets.Msg.value;
widgets.EmailStatus.text = 'Sending email...';
SendEmail(to, subject, msg)
Step 13 - Add the following ClientScript code:
function clearEmailForm(){
var formWidgets = app.pages.Basic.descendants;
formWidgets.EmailStatus.text = "";
formWidgets.Msg.value = "";
formWidgets.To.value = "";
formWidgets.Subject.value = "";
}
function SendEmail(To, Subject, Msg){
var status = app.pages.Basic.descendants.EmailStatus;
google.script.run.withSuccessHandler(function(result) {
status.text = 'Email sent...';
clearEmailForm();
})
.SendEmail(To, Subject, Msg);
}
Step 14 - Now add the corresponding code to the ServerScript.
function SendEmail(to, subject, msg){
MailApp.sendEmail(to, subject , msg);
}

Related

Xamarin Forms - Geofencing with Shiny not triggering when in geofence

I have created a xamarin forms application and one of the requirements is as follows: The user should be able to press a button and create a geofence. When the geofence is created, the application constantly checks if the user is in a geofence. It that's true, the mobile app should show a notification sayinf: you have entered geofence.
I use Shiny to implement the feature based on this tutorial: "https://allancritchie.net/posts/shiny-geofencing".
But the problem is that it isn't doing anything. I have set the geofence 50 meters from my house, and the radius for checking to 200 meter, so when I build the app, a couple of seconds/minuts I should receive a nofitication right? Or do I need to go out of the fence first and then in? How can I fix this issue...
my code:
// shiny doesn't usually manage your viewmodels, so we'll do this for now
var geofences = ShinyHost.Resolve<IGeofenceManager>();
var notifications = ShinyHost.Resolve<INotificationManager>();
Register = new Command(async () =>
{
// this is really only required on iOS, but do it to be safe
var access = await notifications.RequestAccess();
if (access == AccessState.Available)
{
await geofences.StartMonitoring(new GeofenceRegion(
"CN Tower - Toronto, Canada",
new Position(52.079779, 4.337133),
Distance.FromMeters(200)
)
{
NotifyOnEntry = true,
NotifyOnExit = true,
SingleUse = false
});
}
});
public class GeofenceDelegate : IGeofenceDelegate
{
private readonly INotificationManager _notifications;
public GeofenceDelegate(INotificationManager notifications)
{
_notifications = notifications;
}
public async Task OnStatusChanged(GeofenceState newStatus, GeofenceRegion region)
{
if (newStatus == GeofenceState.Entered)
{
await GeofenceEntered(region);
}
else if (newStatus == GeofenceState.Exited)
{
await GeofenceLeft(region);
}
}
}
I have exactly the same code as the tutorial, and the geofence is created when I click a button if I debug it. So everything looks fine to me..
I had a similar issue and just assumed that when you start inside a fence it won't recognize you as entering/or exiting since you are already inside it.
I had to walk out/in of the created fence to trigger the 'OnStatusChanged' method.
Important to note is, that it wouldn't enter the method unless my app activated the phones GPS-system (e.g. re-requesting the current position periodically), but im not sure if that is caused by my old ass phone (running Android6.1) or if it is mend to work that way.
Also note, that i didn't use the shiny.notifications and just showed a popup when the method was run (for testing purposes) like this:
public async Task OnStatusChanged(GeofenceState newStatus, GeofenceRegion region)
{
await Application.Current.MainPage.DisplayAlert(newStatus.ToString(), $"{region.Identifier}", "Ok");
}
Hope this helps ;)

Google Form make POST request on submission

Is there a way to call an external API Endpoint on Google Forms every time the form is filled out?
First:
you'll need to set up your App script project and you'll do that by:
Visit script.google.com to open the script editor. (You'll need to be signed in to your Google account.) If this is the first time you've been to script.google.com, you'll be redirected to a page that introduces Apps Script. Click Start Scripting to proceed to the script editor.
A welcome screen will ask what kind of script you want to create. Click Blank Project or Close.
Delete any code in the script editor and paste in the code below.
This video and the doc will help
Second
you'll need to create an installable trigger, you can add it to the form directly or to the spreadsheet that has the responses
function setUpTrigger(){
ScriptApp.newTrigger('sendPostRequest') /* this has the name of the function that will have the post request */
.forForm('formkey') // you'll find it in the url
.onFormSubmit()
.create();
}
Check the doc
Third
create the sendPostRequest function and add the UrlFetchApp to it
function sendPostRequest(e){
// Make a POST request with form data.
var resumeBlob = Utilities.newBlob('Hire me!', 'text/plain', 'resume.txt');
var formData = {
'name': 'Bob Smith',
'email': 'bob#example.com',
'resume': resumeBlob
};
// Because payload is a JavaScript object, it is interpreted as
// as form data. (No need to specify contentType; it automatically
// defaults to either 'application/x-www-form-urlencoded'
// or 'multipart/form-data')
var options = {
'method' : 'post',
'payload' : formData
};
UrlFetchApp.fetch('https://httpbin.org/post', options);
}
Check the doc
Try something like this in your app script:
var POST_URL = "enter your webhook URL";
function onSubmit(e) {
var form = FormApp.getActiveForm();
var allResponses = form.getResponses();
var latestResponse = allResponses[allResponses.length - 1];
var response = latestResponse.getItemResponses();
var payload = {};
for (var i = 0; i < response.length; i++) {
var question = response[i].getItem().getTitle();
var answer = response[i].getResponse();
payload[question] = answer;
}
var options = {
"method": "post",
"contentType": "application/json",
"payload": JSON.stringify(payload)
};
UrlFetchApp.fetch(POST_URL, options);
};
Be sure to replace the POST_URL variable with your webhook, you can use requestcatcher.com to test this out.
Add a trigger to the script by clicking "Triggers" in the side menu
Open the menu (top-right dots)
Click in Script Editor
Paste the above code (changing the POST_URL)
Click in the clock icon (left-side menu), which means Triggers.
On the right-bottom corner, click in the blue Add trigger button (a form will show as the image below).
It should show onSubmit under Choose which function to run.
Make sure Select event type is set as On form submit.
Click Save button.
After that, submit your form and watch for the request to come in.
This is pretty straightforward with Google Scripts.
Just create a new project bound to your spreadsheet and create 2 elements:
A function that will contain all relevant data to make the call (see docs for making a HTTP request from Google Apps Script)
A trigger linked to the spreadsheet. You can set it to run each time an edit occurs or form is submitted
VoilĂ , your sheet will call whatever endpoint you wish on submission. You can even parse the spreadsheet to return that data to your endpoint

Set email body content in google appmaker

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.

Where is spreadsheet with data

Is it possible to access the Google drive table as which contains the data for an app maker model? I mean - is it possible to open it as a Spreadsheet?
Yes. You can use a spreadsheet as a datasource. I used a simple spreadsheet just to collect 3 items. I was playing with the Email Sender tutorial and I wanted to collect a list of the emails I'd already sent. I created the fields and went into the datasources tab and added this code to the queryRecords() function.
var ss=SpreadsheetApp.openById('id');
var sh=ss.getSheetByName('RecentEmails');
var rg=sh.getRange(2,1,sh.getLastRow(),sh.getLastColumn());
var vA=rg.getValues();
var reRecords=[];
for(var i=0;i<vA.length;i++){
var reRecord=app.models.RecentEmails.newRecord();
reRecord.Recipient=vA[i][0];
reRecord.Date=vA[i][1].toString();
reRecord.Message=vA[i][2];
reRecords.push(reRecord);
}
return reRecords;
The above function loads the datasource.
Then I connected a table upto the datasource and the data will update whenever the page is loaded.
I loaded the data into the table with a function like this:
function archiveSentEmails(to,when,what)
{
var ss=SpreadsheetApp.openById('id');
var sh=ss.getSheetByName('RecentEmails');
sh.appendRow([to,when,what]);
}
It gets placed inside the serverside script where the MailApp.sendMail function is located.
When you push the Send EMail button it calls this clientside function which calls the serverside function via google.script.run.
function sendMessage(to, subject, msg){
var status = app.pages.Email.descendants.EmailStatus;
google.script.run
.withFailureHandler(function(error) {
// An error occurred, so display an error message.
status.text = error.message;
})
.withSuccessHandler(function(result) {
// Report that the email was sent.
status.text = 'Email sent...';
clearEmailForm();
loadDebugElements();
app.datasources.RecentEmails.load();//this lines refreshes the widgets attached to the datasource
})
.sendEmailMessage(to, subject, msg);
}
and I placed the command app.datasources.RecentEmails.load in the withSuccessHandler so that the table of recent emails will update everytime it sends an email and that way you don't have to have a button to initiate updating the table after every email is sent.

MailChimp.Net User is not subscribed

I'm trying to call MailChimp Subscribe with MailChimp.Net NuGet package to add user to list in MailChimp.
The request is performed with success as far as I can see from MailChimp dashboard but the user is not subscribed in the list.
Did anyone faced such issue?
var myMergeVars = new MergeVar();
myMergeVars.Add("FNAME", "Testy");
myMergeVars.Add("LNAME", "Testerson");
var mc = new MailChimpManager("MYKEY");
// Create the email parameter
var email = new EmailParameter()
{
Email = "test.spektor#gmail.com"
};
EmailParameter results = mc.Subscribe("LISTID", email);
The request should be made with doubleOptIn: false option, otherwise user will receive an email with confirmation on his email box.
var result = mc.Subscribe(listId, emailParameter, myMergeVars, doubleOptIn: false, updateExisting: true);

Resources