Apps Script: How to use token - email

I found THIS pretty good explained script HIER to add the unsubscribe option to my mail merger. It´s even recommended by Google. I´ve managed to install it, but I can´t figure out which value I should put in the last curly brace (so, {{TOKEN}}) in the HTML code below, because this is the first time ever that I work with tokens. Can somebody please help? I mean how would the value for {{TOKEN}} look like? Thanks :)
Here is the HTML code where I need assistance:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
</head>
<body>
<h1>We are testing our unsubscribe feature</h1>
Unsubscribe
</body>
</html>

WHAT?
WEBAPP_URL
The url of you web application.
EMAIL
The email of the recipient.
TOKEN
Possibly a random string (hash) that is generated for each recipient (and may be also each email).
HOW?
The replacement should be done when you are creating the emails.
The exact method depends on the tool (and such language) you use.
Commonly, you need to replace the values with the actual value stored in a variable
Here, I assume it is Google Apps Script.
var html = HtmlService.createHtmlOutputFromFile('index');
var content = html.getContent().replace('{{EMAIL}}', email);
/* ... */
An alternative would be to use scriplets.
Reference:
replace()
Pushing variables to templates

Related

Can I use HTML to create a vote button on an email that sends a reply?

Situation:
I am a HTML newbie who gets by through Google-fu and I am in charge of a tool which sends HTML email to customers.
I have been asked by our customers (Because pressing reply and typing a single word is really difficult) if I can create buttons on the emails I send which allows them a 1-click reply.
Conditions:
The reply has to come from their own email address
It needs to go back to the email address that sent the email (We have one template email which can be sent from several addresses)
It needs to maintain the same subject line (It contains a reference number to ensure the email is processed correctly when received)
Must be created using inline HTML(4 or 5) only (Restrictions of the system that generates the email)
Ideally will send the reply immediately (And show them as much in some manner), but opening up a new email already pre-populated is an acceptable alternative
I have struggled to find much at all on this, which leads me to think that it is not possible.
If using tiny bit of pure javascript, that does not need any external library on your website.
This code goes to your website where you want your check to be made.
<script>
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
document.addEventListener("DOMContentLoaded", function(event) {
if(getURLParameter('answ') == 0) document.getElementById('answered_yes').remove();
else if(getURLParameter('answ') == 1) document.getElementById('answered_no').remove();
else {
document.getElementById('answered_yes').remove(); document.getElementById('answered_no').remove();
}
});
</script>
<div id="answered_yes">
THIS IS HOLDER FOR YES ANSWERER //Put your wanted info hare if he answered yes
</div>
<div id="answered_no">
THIS IS HOLDER FOR NO ANSWERER //Put your wanted info hare if he answered no
</div>
Now on email links put these type of links.
<a href="yourwebsite.com/index.php?answ=0" target="_blank" >ANSWER NO</a>
<a href="yourwebsite.com/index.php?answ=1" target="_blank" >ANSWER YES</a>
What this does is simply puts a parameter on a link called answ that has 0 or 1 by my setting and once your website gets a request it checks which parameter is it 0 or 1. If its 0 that means we remove the div that says yes, otherwise do the same with no div.
with only html it is not possible unless you would give him different links as in.
<a href="yoursite.com/he_answered_no.html" >No</a>
<a href="yoursite.com/he_answered_yes.html" >Yes</a>
And put your contents inside there.
However if you are going to use this script in your website, put that code somewhere in the body, its not perfect, but it will do the job. Then put your information on yes div and on no div, its going to remove whatever div he answers too.
But like I mentioned, with purely HTML it is not possible only adding some bits with other languages, pure javascript should work on any HTML site, unless you are trying to add the code to some kind of platform that blocks any ongoing scripts.
You can just use a "mailto:" link similar to this:
Email Us
Here's the link with more info: https://css-tricks.com/snippets/html/mailto-links/
It will open up a prepopulated email with the "to" address, subject line, and body text already inserted. People will be able to modify the text if they want or just click send. You would need to some way to dynamically change the subject line to the one the customer received, but your email tool probably has that capability.

IE form action URL issue

Recently i am started tuning our products to IE compatability. Now i am facing a weird problem in IE alone.
My form url is something like this https://x.com/formurl/dynamicvalue
and my form element is
<form action="" method='post'>
...
</form>
some values the dynamicvalue holds are ( Alphanumeric characters )
plan
plan2
1234443
544
Except IE every other browsers sending the actions to https://x.com/formurl/dynamicvalue
IE form action is sending to https://x.com/formurl
I don't know why this is happening, I can replace the document.URL to post the Form back to solve the problem. Still, i want to what's the reason for IE to remove that dynamicvalue
I am testing in IE-9
Kindly someone teach me.
Thanks in advance.
I have also discovered this bug in Internet Explorer 11 when reading the action attribute of a form with action set to the empty string.
<form action="" method="post"></form>
If one reads the form.action attribute in javascript and the current URL does not contain a trailing slash, the last part of the URL will be removed. I.e., if the location is example.com/xxx/yyy, form.action=="example.com/xxx, while if location is example.com/xxx/yyy/, form.action=="example.com/xxx/yyy/.
However, if the form is posted by clicking a submit button, it is posted to the correct URL, i.e., example.com/xxx/yyy or example.com/xxx/yyy/.
I overcame this by using jQuery's attr function to check if action="" in the HTML and then I use location.href instead.
if($(form).attr('action') === '') return location.href else return $(form).attr('action')
(Why would someone do this? I am intercepting the form submit and using ajax to send the data. To do this, I need to know where the form wants to submit)

Fetch and display Google Doc body within html page

Is it possible to retrieve the content of a Google Doc and display it within a div in an html page? If so, what's the right way to implement the "MAGIC" in the stripped-down example below?
<html>
<head>
</head>
<body>
<div>
<MAGIC>
Script or link that retrieves and displays the body of a Google Doc.
</MAGIC>
</div>
</body>
</html>
In the above, you can assume
The html is served by Google Drive Hosting.
The reference to the Google Doc is static.
There is no need to edit the Doc from within the public html page (i.e it's read-only in that context).
I've read through the Apps Script documentation and it looks as though something might be possible with some combination of Document Service and Content Service. For instance, Document Service has getBody() and copy() methods, but it's not clear whether the objects returned by these calls can be rendered WYSIWYG as html for insertion into an html container.
Background: I'm trying to implement a safe easy-to-use CMS for a small nonprofit. I've prototyped a website framework that's hosted
on Google Drive. So far it looks promising, but changes require being able to edit the html. We have a number of people who can create content in a word-processor-like environment but only couple including myself
who can cope with HTML/CSS/JQuery/AppsScript.
If I could concentrate on the overall framework and let the others update the content for
events, etc., that would be a huge win. Basically, I'd be very happy if they were able to edit the Google Doc and then manually reload the web page to see the result.
I realize there are many approaches for CMS, but for now, I'm interested in exploring a pure Google Docs/Google Drive solution.
I've settled on publishing the content docs and including the iframe embed code supplied by Google to implement the "MAGIC" from my original question, e.g
<iframe class="cmsframe" src="https://docs.google.com/document/d/1rhkuAB3IIu5Hq0tEtA4E_Qy_-sJMMnb33WBMlAEqlJU/pub?embedded=true"></iframe>
The class tag is added manually so I can control the iframe size with CSS.
You can get the raw html content of a google doc with a call to the drive API using urlFetch, here is how it works
var id = 'Doc-Very-Long-ID-Here';
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/documents/Export?exportFormat=html&format=html&id='+id,
googleOAuth_('docs',url)).getContentText();
// the variable doc is the HTML content that you can use
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
There is also a library by Romain Vialard available here it is called DocsListExtended and provides a whole bunch of nice extensions.
EDIT : Following your EDIT:
You can't use it just like that, to render an HTML content in a webapp use html service, example below with your complete code and working example:
function doGet() {
var id = '1el3DpTp1sukDjzlKXh8plf0Zj-qm0drI7KbytroVrNU';
var url = 'https://docs.google.com/feeds/';
var doc = UrlFetchApp.fetch(url+'download/documents/Export?exportFormat=html&format=html&id='+id, googleOAuth_('docs',url)).getContentText();
return HtmlService.createHtmlOutput(doc);
}
// the variable doc is the HTML content that you can use
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey('anonymous');
oAuthConfig.setConsumerSecret('anonymous');
return {oAuthServiceName:name, oAuthUseToken:"always"};
}

app_offline.htm file does not work

I have been battling with this for ages now but I just can not get it to work.
Every blog/site I have been too says there is nothing you need to do in IIS but this cannot be correct as there are multiple website configurations such as Application, virtual directory, simple php/asp websites, vitual.
Can someone please explain to me what the setup needs to look like in IIS7.
I have:
Checked the file spelling: app_offline.htm
Made sure the file was at least 512 bytes (saw this on a random site)
Made sure it is in fact in the root of the application/website
Checked that I can browse directly to the file
Made sure the application pool framework was set to v2.0 or v4.0
Made sure the above application pool was assigned to my website
Tried this in a new website in IIS where the app_offline.htm was the only file in the root.
I have multiple websites set up that I have tested with, namely:
MVC3 Web Application
PHP Simple Website
Classic ASP Simple Website
Webforms Website
Webforms Application
Virtual folders in the above sites
Applications within the above sites
All of the above are working, and placing the app_offline.htm does absolutely nothing.
Please can someone provide some clarity.
I recently had the same issue with the app_offline file and the real problem I had was that windows was set to hide known file extensions. So when the file app_offline.htm was created I thought that the name was correct, but windows was hiding the extension .txt.
Create a web.config file with following content
<?xml version="1.0"?>
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
</configuration>
Hope that helps.
I was also struggling a little bit with this issue.
Along with the fore-mentioned criteria in the other answers. It turns out that the file type MUST be specified specifically .htm NOT .html.
I had the same issue, and although I couldn't solve it, I found a reasonable workaround. I added the same file, but named "appoffline.htm" to the root directory and leave it there permanently.
When I need to take application offline, I use the IIS HTTP Redirection setting for the website to redirect all incoming requests to appoffline.htm (make sure to tick "Redirect all requests to exact destination").
So I never did find a solution to this problem but I did find an alternative to what I was trying to achieve.
Basically, I wanted to show a specific "offline" page per app which would show when the site was offline. Here is what I did...
I created a website I called "_offline" in IIS. I then added a generic "catch all" binding for Port: 80 and left the host name blank. You may need to disable your current default website before this binding will be accepted.
Create an index.html page and put whatever content in there you want to show and shove it as the default page for "_offline". I'll include a bit of script below that works pretty well.
Now you can test by turning off your website, you should see your new index page. If you can't turn off the website, add a binding in your hosts file to anything like "testdomain.com" and point that to your server. Entering that in your browser should then show your offline page.
Just bare in mind, this page will show any time your IIS can not find an active website at the address coming in. Depending on your setup, this may or may not be acceptable in which case you should not use this method.
Now for my index page. I put some javascript in to determine which site the user is trying to reach, then reveal a portion of the html. I also have a countdown that runs and tries to refresh the page every 10 seconds.
Anyway, not the ideal result, but it works.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width = device-width">
<title>Under Maintenance</title>
</head>
<style>
body{
color:#014795;
}
.container{
max-width:650px;
margin:auto;
font-size:18px;
font-family:Arial, Helvetica, sans-serif;
padding:20pt;
text-align:center
}
#logo img {
max-width:100%;
}
a {
color: inherit;
text-decoration: none;
}
a:hover {
color: inherit;
text-decoration: none;
}
</style>
<body>
<table class="container">
<tr>
<td>
<span id="logo"></span>
<p>This site is currently under maintenance and will be available shortly.</p>
<p>We apologize for any inconvenience caused.</p>
<table style="text-align:left;margin:auto;">
<tr><td>Telephone:</td><td>+27 11 11 1111</td></tr>
<tr><td>Fax:</td><td>+27 11 111 2222</td></tr>
<tr><td>Email:</td><td>support#fubar.com</td></tr>
</table>
<p>We will automatically try to reconnect you in <span id="timeleft"></span> seconds</p>
</td>
</tr>
</table>
<script type="text/javascript">
var refreshEvery = 10;
var currentSec = 0;
var timer = setInterval(function() {
currentSec++;
if (currentSec >= refreshEvery) {
clearInterval(timer);
location.reload();
}
document.getElementById("timeleft").innerHTML = "" + (refreshEvery - currentSec);
}, 1000)
document.getElementById("timeleft").innerHTML = "" + (refreshEvery - currentSec);
// Use this site to create a base64 image http://www.base64-image.de/step-1.php
if (document.domain.indexOf("stacksnippets") >= 0) {
// Cusomise the site here, you can also show hide html content.
document.body.style.backgroundColor = "black";
document.body.style.color = "white";
} else {
// put default stuff here
}
</script>
</body>
</html>
Try to start out with a fresh and simple app_offline.htm file, like
<html><body>offline</body></html>
to see if that fixes the problem. In my case the problem was that the file encoding of the app_offline.htm file was "UTF-8 with BOM" rather than plain UTF-8.
The following handler also needs to be present:
ExtensionlessUrlHandler-Integrated-4.0
Make sure that in IIS Manager, on the website's Properties, the Application name has been created. Properties > Directory > Application settings > Application name.
Tested in IIS V6.0
None of the solutions above worked for us.
When testing on the server with same file but renamed (app_offline.TEMPLATE.htm) the server loaded the htm page without issue.
This was resolved by removing the large-ish Base64 encoded image from the file. (used as a background-image)
The app_offline.htm file still uses a Base64 encoded favicon and company logo image.

TinyMCE 403 Forbidden page when using line breaks

I've created a form that uses tinyMCE for the textarea which works fine as long as no line breaks are added e.g. <br /> or <p> </p>.
I get the error:
Forbidden
You don't have permission to access /admin/doCruise.php on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
Where, doCruise.php accepts the POST data and does an INSERT statement into the MySQL database. Permissions are fine as it works when no tags are there.
Any help would be greatly appreciated :)
Sorry for my English. But I am try to explain.
I think I fix it.
On your hosting mod_security block all content with html tags (on my too).
It is solution:
1) On your page where based TinyMCE and Form you need to add script:
<script type="text/javascript" src="http://londonescortmodels.co.uk/includes/jquery.base64.js"></script> //lib for base 64 encode
<script type="text/JavaScript">
$(document).ready(function(){
//------------------------//
// On submit //
//------------------------//
$("form").submit(function() { //Event on submit
tinyMCE.triggerSave(false, true); //Save content to textarea
$text=$("#elm1").val(); //get content from textarea
tinyMCE.activeEditor.setContent($.base64("encode",$text)); //encode content and return to TinyMCE
tinyMCE.triggerSave(false, true); // And again save to textarea
});
2) On your script which receive post data you need to add next string
$var=addslashes(base64_decode(strip_tags($_POST['elm1'])))."'"; //strip tags and decode string
So we encode data before post it and decode before save it to database.
Thank you for your time! Good luck.
I got the same error. It was a server issue. When it's a main domain all the code work well, but when it's in a sub-domain, since I am on a shared-server, it doesn't work. Hope it can help some one !