I'm still pretty new to Javascript, but I was wondering what would be the best way to fire the Facebook conversion pixel (below) without actually loading a "confirmation"/"Thank You" page?
<script type="text/javascript">
var fb_param = {};
fb_param.pixel_id = 'XXXXXXXXXXX';
fb_param.value = '0.00';
fb_param.currency = 'USD';
(function(){
var fpw = document.createElement('script');
fpw.async = true;
fpw.src = '//connect.facebook.net/en_US/fp.js';
var ref = document.getElementsByTagName('script')[0];
ref.parentNode.insertBefore(fpw, ref);
})();
</script>
<noscript><img height="1" width="1" alt="" style="display:none"
src="https://www.facebook.com/offsite_event.php?id=XXXXXXXXXX&value=0¤cy=USD" /></noscript>
Facebook says that we should plug this into our "Thank You pages" that visitors see after they convert (fill out a form, make a purchase, etc). However, some of our forms are popups or forms on sidebars next to content that we don't want readers to be directed away from by a confirmation page.
With Google Analytics, I can create an "invisible" pageview by firing _gaq.push(['_trackPageview']); code that can tell GA that it should count that invisible pageview as a goal completion.
Is there something similar to that that's general enough to tell my site to fire the FB pixel?
EDIT: I've updated my code as what I had mentioned previously did not work. Thanks to #Flambino to pointing out.
This is my revised answer using a pixel rather than a script to pass the conversion pixel. I reference the How to track a Google Adwords conversion onclick? SO post:
<head>
<script type="text/javascript">
function facebookConversionPixel(fb_pixel, fb_value){
var image = new Image(1,1);
image.src = "//www.facebook.com/offsite_event.php?id=" + fb_pixel + "&value=" + fb_value + "¤cy=USD";
}
</script>
</head>
<body>
FBCONV
</body>
From the FB docs "How to track in-page events":
After the base code snippet is installed, you can track in-page actions, such as clicks on a button, by making a _fbq.push('track') call for the conversion pixel through registering different event handlers on an HTML DOM element. For example:
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');" />
Just move the entire original code into the event of your choice. Then just change 1 part of the code. The thing you will have to do is make the fb_param global instead of local.
See below at the comment
$('.button').click(function() {
window.fb_param = {}; // must be global by adding `window.`
fb_param.pixel_id = '123456789';
fb_param.value = '0.00';
fb_param.currency = 'USD';
(function(){
var fpw = document.createElement('script'); fpw.async = true; fpw.src = '//connect.facebook.net/en_US/fp.js';
var ref = document.getElementsByTagName('script')[0];
ref.parentNode.insertBefore(fpw, ref);
})();
});
I was having similar kind of issue and I would like to run multiple adds to track pixels codes and some reason I was not able to track. What I did is that, in the current page I have added pixel code in footer and javascript function
to call when my ajax button get submitted.
First refer to Facebook documentation page
https://developers.facebook.com/docs/ads-for-websites/conversion-pixel-code-migration#multi-conv-events
How to track Multiple Conversion Events
After the base code snippet is installed, you can track multiple conversions within the same web page by making multiple _fbq.push('track') calls for each conversion pixel ids. For example:
_fbq.push(['track','<pixel_id1>',{'value':'10.00','currency':'USD'}]);
_fbq.push(['track','<pixel_id2>']);
How to track In-Page Events
After the base code snippet is installed, you can track in-page actions, such as clicks on a button, by making a _fbq.push('track') call for the conversion pixel through registering different event handlers on an HTML DOM element. For example:
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', '<pixel_id>', cd]);
}
<button onClick="trackConversionEvent('10.00','USD');" />
Also, add the facebook pixel tracking code chrome addon and refer the facebook pixel helper page: https://developers.facebook.com/docs/ads-for-websites/pixel-troubleshooting
See my below solution/answer
Facebook tracking code in the current page
(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', 'yourid', {'value':'1.00','currency':'USD'}]);
<!-- Facebook Conversion -->
<script>(function() {
var _fbq = window._fbq || (window._fbq = []);
if (!_fbq.loaded) {
var fbds = document.createElement('script');
fbds.async = true;
fbds.src = '//connect.facebook.net/en_US/fbds.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(fbds, s);
_fbq.loaded = true;
}
})();
window._fbq = window._fbq || [];
window._fbq.push(['track', 'yourid', {'value':'1.00','currency':'USD'}]);
</script>
And the javascript code to call when ajax form submit or button click
<script>
function trackConversionEvent(val, cny) {
var cd = {};
cd.value = val;
cd.currency = cny;
_fbq.push(['track', 'yourid1', cd]);
_fbq.push(['track', 'yourid1', cd]);
}
</script>
and the call the function when ajax called
jQuery(form).ajaxSubmit({
type:"POST",
data: $(form).serialize(),
url:"process.php",
success: function() {
**trackConversionEvent**('1.00','USD');
}
......
Facebook has updated their pixels, so I created my own custom function to call that will dynamically put the parameters together to submit to Facebook.
Step 1. On every page, make sure you've initialised your pixel in the head element of the page.
Step 2. Add this custom function I created (it's a bit verbose as it is the first draft, so I'm sure there are ways to optimise it for your benefit).
triggerFacebookPixel: function(type, price, product_id, product_name, product_category, num_items) {
//See https://developers.facebook.com/docs/ads-for-websites/pixel-events/v2.8#events for documentation
//type = "ViewContent"|"AddToCart"|"Search"|"AddToWishlist"|"InitiateCheckout"|"AddPaymentInfo"|"Purchase"|"Lead"|"CompleteRegistration"
//product_id = Numeric Product ID. String or Integer accepted for single product events, or an array of integers for multiple products.
//price = Decimal/Float number of individual product's price or total price paid in conversion, or the user's status for 'CompleteRegistration'
//product_name = Optional. String of individual product's name or string of search query
//product_category = Optional. String of product category, hierarchy's accepted. E.g. "Clothing > Shirts > Men's > T-Shirts"
//num_items = Optional. Total number of products.
var data = {
value: typeof(price) == 'string' ? parseFloat(price) : price,
currency: 'USD'
}
switch (type) {
case 'Search':
data.content_ids = product_id;
data.search_string = product_name;
if (product_category !== undefined && product_category != '') {
data.content_category = product_category;
}
break;
case 'Lead':
data.content_name = product_name;
data.content_category = product_category;
break;
case 'CompleteRegistration':
data.status = product_id;
data.content_name = product_name;
break;
default:
//Product Specific Calls
//ViewContent|AddToCart|AddToWishlist|InitiateCheckout|AddPaymentInfo|Purchase
if (num_items == 1) {
data.content_ids = [typeof(product_id) == 'string' ? parseInt(product_id) : product_id];
data.content_category = product_category;
data.content_name = product_name;
} else {
data.content_ids = product_id;
}
//"num_items" is only a parameter used in these two types
if (type == 'InitiateCheckout' || type == 'Purchase') {
data.num_items = num_items
}
//"content_type" is only a parameter used in these three types
if (type == 'Purchase' || type == 'AddToCart' || type == 'ViewContent') {
data.content_type = 'product';
}
break;
}
fbq('track', type, data);
}
Step 3. Call that function with the appropriate parameters.
For your thank you pop-up after a purchase, the pixel is fired differently if the user purchases 1 item as opposed to multiple items. Basically, Facebook accepts parameters for product names and categories if it's just one product, but doesn't accept those parameters if it's multiple products.
For the following examples, here is some sample product data of a user purchasing 1 item:
Product Name: "My Super Awesome T-Shirt"
Product ID: 182
Product Category: "Clothing > Shirts > T-Shirts"
Total amount user paid (including shipping/handling & tax): $10.84
And here's the function you'd call on the confirmation:
triggerFacebookPixel('Purchase', 10.84, 182, 'My Super Awesome T-Shirt', 'Clothing > Shirts > T-Shirts', 1);
When a user purchases multiple items, the pixel handles it differently, excluding the product names and categories and only sending their ID's. So let's pretend our user purchased these two items:
Product ID's: 182 and 164 (the shirt and something else)
Total amount user paid (including shipping/handling & tax): $24.75
This is how you'd use the function:
triggerFacebookPixel('Purchase', 24.75, [182, 164], '', '', 2);
For other standard events as defined by Facebook regarding products, you can use this same function for "ViewContent", "AddToCart", "AddToWishlist", "InitiateCheckout", and "AddPaymentInfo". Just change "Purchase" to any of those key words in your call.
The other events aren't necessarily related to products: "Lead", "Search", and "Complete Registration". You can still use this function for those key words like this.
Example: user searched for "blue shirts":
triggerFacebookPixel('Search', 0, [], 'blue shirts');
If you want to pass a product category in the user search function, you can pass that as a string at the end. I can't think of a use-case scenario where you'd know what category the user is searching for. Unless you used this in the event that the product appears in the search results and the user clicked on it from the search page. That might be what this function is actually for but the documentation isn't quite clear on that. If that's the case for you, then simply change the 0 and empty array to the actual values (price and product ID, respectively) of the product that was clicked on from the search results page, and add its category as a string as the last parameter after the search string.
Example: user submitted a form that signed them up to your newsletter:
triggerFacebookPixel('CompleteRegistration', 0, 'Signed Up', 'Newsletter');
Facebook's documentation states that "CompleteRegistration" should be used when a registration form is completed, e.g. complete subscription/signup for a service. The "Signed Up" string is the "status" parameter and the "Newsletter" string is the "content_name" parameter.
Example: user submitted a form that signed them up for a free 30-day trial of some service you offer (so they are now a lead), where the name of the service is "Free 30-Day Trial Service" and it's in the sub-category "Free Trials" under the category "My Services":
triggerFacebookPixel('Lead', 0, 'Free 30-Day Trial Service', 'My Services > Free Trials');
Facebook's documentation states that "Lead" is when a sign up is completed, e.g. click on pricing, signup for trial. I assumed that the name of the service is the parameter "content_name" and the category of the service is the "content_category" parameter.
Related
This is the flow I created through Google Apps Script.
Someone writes their information in google form
The information is stored into spreadsheet
Invoice is created within spreadsheet with the newest information received
The invoice is turned into PDF format automatically
The newest invoice is attached to the auto sending email
The person receives an auto-email with the invoice attached as soon as they submit the google form
The problem is that, when someone submits the google form, they receive an invoice but what they receive is the invoice from the information one before. This then repeats. When someone submits, the information inside the invoice is from the person one before.
I am a starter at Google Script so I have no idea why this is happening.
This is the code I use to send the auto email. I have minimized the code.
function for_users2() {
var title = "【お問い合わせありがとうございます】";
var name = '名前';
var mail = 'メールアドレス';
var address = "";
var sheet = SpreadsheetApp.getActiveSheet();
var row = sheet.getLastRow();
var column = sheet.getLastColumn();
var range = sheet.getDataRange();
var TIMESTAMP_LABEL = 'タイムスタンプ';
for (var i = 1; i <= column; i++ ) {
var item = range.getCell(1, i).getValue();
var value = range.getCell(row, i).getValue();
if ( item === TIMESTAMP_LABEL ) {
item = 'お問い合わせ日時';
}
if ( item === 'お問い合わせ日時' ) {
value = Utilities.formatDate(value, 'Asia/Tokyo',"YYYY'年'MM'月'dd'日'HH'時'mm'分'ss'秒'");
}
body += "■"+item+"\n";
body += value + "\n\n";
if ( item === name ) {
body = value+" 様\n\n"+body;
}
if ( item === mail ) {
address = value;
}
}
body += body2;
var token = ScriptApp.getOAuthToken();
var pdf = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO/export?exportFormat=pdf&format=pdf&size=A4&portrait=true&fitw=true&sheetnames=false&printtitle=false&pagenumbers=false&gridlines=false&fzr=false&gid=00000000000", {headers: {'Authorization': 'Bearer ' + token}}).getBlob().setName('請求書');
GmailApp.sendEmail(
address,
title,
body,
{
attachments: [pdf],
name: 'Automatic Emailer Script'
}
);
}
There is no error. It's just that the invoice attached is from one previous customer.
Thank you to the people who have answered my question. Special thanks to Tanaike who have suggested a workaround where I was able to use as a starter to GAS.
As I used Utilities.sleep(5000), whenever someone submits google form, the invoice produced (PDF format) is updated to the newest info. Since the program I created isn't aimed for very heavy processes, it may be the reason why it worked perfectly fine.
If SpreasheetApp.flush() doesn't seem to be working then you should certainly move to the onFormSubmit - Installable Trigger.
Triggers - Form Submit
This way you can process the exact values from the form and use the same function you are using now. Instead of fetching the last row values, you can fetch the values from the form submission using this.
var name = e.namedValues['Name'][0]; var email = e.namedValues['Email'][0];
I have a set of scripts that I'm using that interact with each other. I use a client, user event and suitelet script to create a button that, when pressed, opens a popup with a list of items filtered by vendor.
It works fine when I'm in edit however when I use it while creating a record problems arise. Since the record to be created has no vendor or id I can't retrieve an item by vendor. What I'm trying to do is to have the Suitelet retrieve the info from the vendor field that is entered prior to it being saved. Therefore I can filter all the items by vendor and add the necessary items in one go. Is this possible? Am I able to access the info before it is submitted.
Below are the Client and Suitelet. The User Event is just a call to the suitelet so for the sake of brevity I left it out.
Client Script
function addItemButtonCallback(data){
nlapiSelectNewLineItem('item');
nlapiSetCurrentLineItemValue('item', 'item', data);
nlapiCommitLineItem('inventoryitem');
}
function addItemButton() {
var id = nlapiGetFieldValue('id');
if (id != "") {
var url = nlapiResolveURL('SUITELET', 'customscript_val', 'customdeploy1') + '&poId='+id;
window.open(url, '_blank', 'width=500,height=500');
}
}
Suitelet
function suitelet(request, response){
if(request.getMethod() == 'GET') {
var form = nlapiCreateForm('Add Item');
form.addSubmitButton('Submit');
var itemfield = form.addField('custpage_val', 'select', 'Item');
var id = request.getParameter('id');
var rec = nlapiLoadRecord('purchaseorder', id);
var vend = rec.getFieldValue('entity');
var search = nlapiSearchRecord(...search parameters...);
for (result in search){
if (search[result].getValue('vendor') == vend){
itemfield.addSelectOption(search[result].id, nlapiLookupField('inventoryitem', search[result].id, 'itemid'));
}
}
response.writePage(form);
} else {
var data = request.getParameter('custpage_item');
response.write('<html><body><script>window.opener.addItemButtonCallback("'+data+'"); window.close();</script></body></html>');
}
}
Use nlapiGetFieldValue('entity') on the clientscript and pass it to the Suitelet using a query parameter just like you are doing with poId (if you do this you might not even need poId after all + no need to load the record on the suitelet).
Also, you might want to optimize your code by running one search passing an array of itemids instead of calling nlapiLookupField for each item.
You might need to modify your beforeLoad so the entity is inserted dynamically when the button is pressed (I cant remember if clientscript button does this) . Something like this:
var suiteletURL = nlapiResolveURL('SUITELET', 'customscript_val', 'customdeploy1');
var script = "var entity = nlapiGetFieldValue('entity'); var url = '" + suiteletURL + "'&entityId=' + entity;window.open(url, '_blank', 'width=500,height=500')";
var button = form.addButton('custpage_addItemButton', 'Add Item', script);
I have a custom object in Salesforce called Website_Role__c. This object has a list of people associated with a store with different roles (Owner, Mentor, etc.).
Using JavaScript in a Salesforce button on Account:
The desired behavior is a user clicks the button and a dialog pops up with the list of people in the Website_Role__c for that Account. There would be a checkbox next to each person allowing the user to select them.
We are using eSign (formerly EchoSign). This button is a "Send with eSign" button that will be used to send an agreement to the list of people from Website_Role__c.
This is where I am at now:
/*My Attempt*/
{
!REQUIRESCRIPT("/soap/ajax/19.0/connection.js")
} //adds the proper code for inclusion of AJAX toolkit
var url = parent.location.href; //string for the URL of the current page
var records = {!GETRECORDIDS($ObjectType.Website_Role__c)
}; //grabs the Website Role records for the currently selected store
var updateRecords = []; //array for holding records that this code will ultimately update
if (records[0] == null) { //if the button was clicked but there was no record selected
alert("Please select at least one person to send to."); //alert the user that they didn't make a selection
} else { //otherwise, there was a person selected
for (var a = 0; a < records.length; a++) { //for all records
var update_Website_Role__c = new sforce.SObject("Website_Role__c"); //create a new sObject for storing updated record details
//This is where I get lost. Not sure if this is even the correct approach
}
//??
parent.location.href = url; //refresh the page
}
I would greatly appreciate any help you can provide.
Thank you
Try something like this:
{!REQUIRESCRIPT("/soap/ajax/29.0/connection.js")}
var query = sforce.connection.query("SELECT Owner__c, Mentor__c FROM Website_Role__c WHERE Account__c ='{!Account.Id}'");
var records = query.getArray("records");
alert("Owner is: " + records[0].Owner__c);
This assumes you have a reference field on your Website_Role object that points to the Account.
Check here for some more examples
https://developer.salesforce.com/docs/atlas.en-us.ajax.meta/ajax/sforce_api_ajax_more_samples.htm
I have a web page that asks the user for a paragraph of text, then performs some operation on it. To demo it to lazy users, I'd like to add an "I feel lucky" button that will grab some random text from Wikipedia and populate the inputs.
How can I use Javascript to fetch a sequence of text from a random Wikipedia article?
I found some examples of fetching and parsing articles using the Wikipedia API, but they tend to be server side. I'm looking for a solution that runs entirely from the client and doesn't get scuppered by same origin policy.
Note random gibberish is not sufficient; I need human-readable sentences that make sense.
My answer builds on the technique suggested here.
The tricky part is formulating the correct query string:
http://en.wikipedia.org/w/api.php?action=query&generator=random&prop=extracts&exchars=500&format=json&callback=onWikipedia
generator=random selects a random page
prop=extracts and exchars=500 retrieves a 500 character extract
format=json returns JSON-formatted data
callback= causes that data to be wrapped in a function call so it can be treated like any other <script> and injected into your page (see JSONP), thus bypassing cross-domain barriers.
requestid can optionally be added, with a new value each time, to avoid stale results from the browser cache (required in IE9)
The page served by the query is something that looks like this (I've added whitespace for readability):
onWikipedia(
{"query":
{"pages":
{"12362520":
{"pageid":12362520,
"ns":0,
"title":"Power Building",
"extract":"<p>The <b>Power Building<\/b> is a historic commercial building in
the downtown of Cincinnati, Ohio, United States. Built in 1903, it
was designed by Harry Hake. It was listed on the National Register
of Historic Places on March 5, 1999. One week later, a group of
buildings in the northeastern section of downtown was named a
historic district, the Cincinnati East Manufacturing and Warehouse
District; the Power Building is one of the district's contributing
properties.<\/p>\n<h2> Notes<\/h2>"
} } } }
)
Of course you'll get a different article each time.
Here's a full, working example which you can try out on JSBin.
<HTML><BODY>
<p><textarea id="textbox" style="width:350px; height:150px"></textarea></p>
<p><button type="button" id="button" onclick="startFetch(100, 500)">
Fetch random Wikipedia extract</button></p>
<script type="text/javascript">
var textbox = document.getElementById("textbox");
var button = document.getElementById("button");
var tempscript = null, minchars, maxchars, attempts;
function startFetch(minimumCharacters, maximumCharacters, isRetry) {
if (tempscript) return; // a fetch is already in progress
if (!isRetry) {
attempts = 0;
minchars = minimumCharacters; // save params in case retry needed
maxchars = maximumCharacters;
button.disabled = true;
button.style.cursor = "wait";
}
tempscript = document.createElement("script");
tempscript.type = "text/javascript";
tempscript.id = "tempscript";
tempscript.src = "http://en.wikipedia.org/w/api.php"
+ "?action=query&generator=random&prop=extracts"
+ "&exchars="+maxchars+"&format=json&callback=onFetchComplete&requestid="
+ Math.floor(Math.random()*999999).toString();
document.body.appendChild(tempscript);
// onFetchComplete invoked when finished
}
function onFetchComplete(data) {
document.body.removeChild(tempscript);
tempscript = null
var s = getFirstProp(data.query.pages).extract;
s = htmlDecode(stripTags(s));
if (s.length > minchars || attempts++ > 5) {
textbox.value = s;
button.disabled = false;
button.style.cursor = "auto";
} else {
startFetch(0, 0, true); // retry
}
}
function getFirstProp(obj) {
for (var i in obj) return obj[i];
}
// This next bit borrowed from Prototype / hacked together
// You may want to replace with something more robust
function stripTags(s) {
return s.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, "");
}
function htmlDecode(input){
var e = document.createElement("div");
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
</script>
</BODY></HTML>
One downside of generator=random is you often get talk pages or generated content that are not actual articles. If anyone can improve the query string to limit it to quality articles, that would be great!
I manage a website for an organization that has separate chapter sites. There is a membership signup form that is on the main website that each chapter links to. On the form there is a dropdown box that allows a person to choose the chapter they want to join. What I would like to do is have each chapter website use a specific link to the form that will preselect their chapter from the dropdown box.
After searching the web, I found that I will probably need to use a Javascript function to utilize a Query String. With all my searching, I still can't figure out the exact code to use. The page is a basic HTML page...no php and it is hosted on a linux server.
Any help would be greatly appreciated.
If you format your url like this:
www.myorg.com?chapter=1
You could add this script to your html head:
function getparam(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.href);
if (results == null)
return "";
else
return results[1];
}
function loadform()
{
var list = document.getElementById("mychapterdropdown");
var chapter = getparam("chapter");
if (chapter>=0 && chapter < list.options.length)
{
list.selectedIndex = chapter;
}
}
The in your html body tag:
<body onload="loadform();" >
Could probably add more validation checks but that's the general idea.
It sounds like what you are looking for are GET or POST requests. For instance, if your user selects "Chapter A" from your form and hits select, you can allow redirects from another site (for instance http://www.yoursite.com/form.html?chapter=A) to allow Chapter A to be preselected. In Javascript this is done by
var chapter="";
var queryString = location.search.substring(1);
if ( queryString.length > 0 ) {
var getdata = queryString.split("&");
var keyvalues;
for(var i=0; i < getdata.length; i++){
keyvalues = getdata.split("=");
}
} else {
chapter = "Not Found";
}
document.getElementById( "ChapterID").value = keyvalues['chapter'];
This is untested, so don't hold me to it :).
maybe something using parse_url
$params = parse_url()
$query = $params['query'];
$query_pairs = explode('&',$query);
$key_val = array();
foreach($query_pairs as $key => $val){
$key_val[$key] = $val;
}
http://www.php.net/manual/en/function.parse-url.php
You would probably have to use an dynamic ajax content. Use the following javascript to read the querystring, then load the html file in that div using this javascript.