I'm trying to include legacy javascript code for affiliate tracking into an angularjs app
<script type="text/javascript">
//<![CDATA[
/*** Do not change ***/
var AWIN = {};
AWIN.Tracking = {};
AWIN.Tracking.Sale = {};
/*** Set your transaction parameters ***/
AWIN.Tracking.Sale.amount = '{{order_total}}';
AWIN.Tracking.Sale.orderRef = '{(order_id}}';
AWIN.Tracking.Sale.parts = '{{cats}}';
AWIN.Tracking.Sale.voucher = '';
AWIN.Tracking.Sale.currency = 'GBP';
AWIN.Tracking.Sale.test = '0';
AWIN.Tracking.Sale.channel = 'aw';
//]]>
</script>
I need to call the above code (filling in the place holders with angualr vars) and then call this:
<script src="https://www.dwin1.com/xxxx.js" type="text/javascript" defer="defer"></script>
What is the best way to do this? I've tried placing the code into an Angular function with no success I've also tried passing the vars down into $window and trying to insert them into the CDATA at my end with no success. Any ideas?
I should add this code sits in a HTML page wrapped in an angualrjs controller
what you are trying is not possible directly with angularjs. you need to do something like below
//Note: this is a new JS file included in your main html
(function() {
"use strict";
window.AWIN = {};
window.populateAwin = function(args) {
//<![CDATA[
/*** Do not change ***/
AWIN.Tracking = {};
AWIN.Tracking.Sale = {};
/*** Set your transaction parameters ***/
AWIN.Tracking.Sale.amount = args.order_total;
AWIN.Tracking.Sale.orderRef = args.order_id;
AWIN.Tracking.Sale.parts = args.cats;
AWIN.Tracking.Sale.voucher = '';
AWIN.Tracking.Sale.currency = 'GBP';
AWIN.Tracking.Sale.test = '0';
AWIN.Tracking.Sale.channel = 'aw';
//]]>
}
}());
you then need to call this function from your controller by passing required data as shown below
populateAwin({
order_total: $scope.order_total,
order_id: $scope.order_id,
cats: $scope.cats
});
Once this is done, you can proceed with inclusion of script dynamically as shown below from your controller
var scriptEl = document.createElement("script");
scriptEl.type = "text/javascript";
scriptEl.defer = "defer";
scriptEl.src = "https://www.dwin1.com/xxxx.js";
document.body.appendChild(scriptEl);
Related
I am using gnuplot-js https://github.com/chhu/gnuplot-JS when I am without my laptop at university.
Is it possible to use an external url for gnuplot.js file? I host index.html, gnuplot_api.js on https://mywebsite.com/ but I would like to use another url for gnuplot.js file (for example https://external.com/blabla/ok/no/gnuplot.js) because this file is really big!
Maybe this is the part I should edit on index.html. How? :
<script src='gnuplot_api.js'></script>
<script>
gnuplot = new Gnuplot('gnuplot.js');
gnuplot.onOutput = function(text) {
document.getElementById('output').value += text + '\n';
document.getElementById('output').scrollTop = 99999;
};
or maybe this part on gnuplot_api.js?:
var Gnuplot = function(js_filename) {
this.worker = new Worker(js_filename);
this.output = [];
this.error = [];
this.isRunning = false;
Thank you very much for your support
It appears Gnuplot use an onboard webworker, so the path provided to the constructor should be on the same domain than the script.
<script src='https://cdn.jsdelivr.net/gh/chhu/gnuplot-JS/www/gnuplot_api.js'></script>
<script>
gnuplot = new Gnuplot('https://cdn.jsdelivr.net/gh/chhu/gnuplot-JS/www/gnuplot.js');
</script>
I have a problem when trying to use a widget.
The script is as follows:
<script type="text/javascript">
baseUrl = "https://widgets.cryptocompare.com/";
var scripts = document.getElementsByTagName("script");
var embedder = scripts[ scripts.length - 1 ];
(function (){
var appName = encodeURIComponent(window.location.hostname);
if(appName==""){appName="local";}
var s = document.createElement("script");
s.type = "text/javascript";
s.async = true;
var theUrl = baseUrl+'serve/v3/coin/chart?fsym=TPAY*&tsyms=USD';
s.src = theUrl + ( theUrl.indexOf("?") >= 0 ? "&" : "?") + "app=" + appName;
embedder.parentNode.appendChild(s);
})();
</script>
When I access https://widgets.cryptocompare.com/serve/v3/coin/chart?fsym=TPAY*&tsyms=USD from my browser it displays all the data but when using the widget script it does not seem to like the fsym=TPAY&tsym=USD but because cryptocompare lists some currencies that have the same ticker they add a * to the second currency which uses the same ticker name.
Another example of this is PHORE PHR* as they have PHREAK PHR already listed. Funny enough the currencies I would like to use it TPAY* and PHR*.
Im trying to save the client IP address in a variable after retrieving it in JSON form from api.ipify.org. I can get the IP to show if I alert the result but cannot get it to save in a variable for some reason.
This works:
<script>
function getIP(json) {
alert(json.ip);
}
</script>
<script src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
But this does not work:
<script>
var clientIP = ''
function getIP(json) {
clientIP = json.ip;
return clientIP;
}
alert(clientIP);
</script>
<script src="https://api.ipify.org?format=jsonp&callback=getIP"></script>
I would like to be able to store the data in a variable so that I can attach it to an embed that will add it into its automated webhook POST.
<!-- begin video recorder code --><script type="text/javascript">
var IPADDRESSVARIABLE = 'SOME_IP_ADDRESS'
var size = {width:400,height:330};
var flashvars = {qualityurl: "avq/300p.xml",accountHash:"BUNCHOFRANDOMSTUFF", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload: IPADDRESSVARIABLE};
(function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
</script>
<div id="hdfvr-content"> </div>
<!-- end video recorder code -->
If I can get the IP address saved as a global variable then I can pass it into the 'payload' key of the 'flash vars'.
The second code example does not work because the variable is only given a value inside of a callback function, which means the alert,which runs synchronously, runs as soon as the javascript interpreter starts reading and running the code line by line, but the getIP function is only called later on when the jsonp request returns a response. Your first code example was the right way to go.
Your alert won't work because your code is not executing synchronously, getIP doesn't get called until after your alert statement. You need to trigger any functionality that depends on clientIP inside your getIP function. Here is an example:
function getIP(json) {
var event = new CustomEvent('iploaded', { detail: json.ip });
document.dispatchEvent(event);
}
document.addEventListener('iploaded', function(event) {
var IPADDRESSVARIABLE = event.detail;
var size = {width:400,height:330};
var flashvars = {qualityurl: "avq/300p.xml",accountHash:"BUNCHOFRANDOMSTUFF", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload: IPADDRESSVARIABLE};
(function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
});
// simulate jsonp callback
getIP({ ip: '127.0.0.1' });
Also, no need to return in getIP
Try this :
function getIP(json) {
return json.ip;
}
var json = { "ip": "111.22.33.44"}
var clientIP = getIP(json);
alert(clientIP);
I found a workaround! I stored the result of the IP function into a hidden div to act as a container. I then declared a variable inside the embed code and set it to the innerHMTL. It may not be the most elegant but it does exactly what I want it to!
//hidden container to store the client IP address
<div id = 'ipContainer' style='display:none'></div>
//function to retrieve the client IP address
<script>
function getIP(json) {
document.getElementById('ipContainer').innerHTML = json.ip;
}
</script>
//shortened version of the URL that returns the IP
<script src='http://www.api.ipify.org'><script>
//embed code for the video recorder
<script>
<!-- begin video recorder code --><script type="text/javascript">
var clientIP = document.getElementById('ipContainer').innerHTML;
var size = {width:400,height:330};
//I passed the clientIP variable into the payload element of the flashvars object
var flashvars = {qualityurl: "avq/300p.xml",accountHash:"RANDOM ACCOUNT HASH", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload:clientIP}; //Here i passed the clientIP which is nor stored as a variable
(function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
</script>
<div id="hdfvr-content"> </div>
<!-- end video recorder code -->
As Rob says, you're expecting the code to run synchronously but that isn't the case.
Here's a small edit of your code snippet that will work, basically I've wrapped the alert in a function, I then call that function once the getIP function has finished executing.
<script>
var clientIP = ''
function getIP(json) {
clientIP = json.ip;
alertClientIp();
}
function alertClientIp () {
alert(clientIP);
}
</script>
The code design of the above snippet is a bit nasty, if you only need to use the client IP once, then don't bother storing it as a variable, just pass it to the function which executes you "automated webhook POST" logic.
<script>
function getIP(json) {
clientIP = json.ip;
alertClientIp();
}
//Accept the client_ip as a param
function webhookLogic (client_ip) {
//Execute your logic with the client_ip,
//for simplicity I'll stick to your alert.
alert(client_ip);
}
</script>
With regards to your edit
It looks like you have the two sets of logic placed in two separate script elements, could you not merge them into one?
<script>
function getIP(json) {
clientIP = json.ip;
alertClientIp();
}
//Accept the client_ip as a param
function webhookLogic (client_ip) {
//Execute your logic with the client_ip,
//for simplicity i'll stick to your alert.
//Trigger your video wrapper code, unsure if
//if this method of execution will break your app...
videoWrapper(client_ip);
}
//Your video code from your latest edit
function videoWrapper (client_ip) {
var IPADDRESSVARIABLE = client_ip;
var size = {width:400,height:330};
var flashvars = {qualityurl: "avq/300p.xml",accountHash:"BUNCHOFRANDOMSTUFF", eid:2, showMenu:"true", mrt:120,sis:0,asv:1,mv:0, payload: IPADDRESSVARIABLE};
(function() {var pipe = document.createElement('script'); pipe.type = 'text/javascript'; pipe.async = true;pipe.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 's1.addpipe.com/1.3/pipe.js';var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(pipe, s);})();
}
</script>
If that chain of execution breaks your app then I think you need to go back to the drawing board with regards to the composition of your question, it's clear what you want to do but your question lacks a bit of meta-data as to how this logic all "fits together".
Is there a way via some lines of JavaScript to assign the value of a custom meta field in a Wordpress post/page to a JavaScript variable?
In other words, I've got a custom meta field in all my Wordpress posts and pages named "customamznsearch". I'd like to assign the value of that field to a JavaScript variable with the same name... or different name if need be.
Also, an added bonus would be to also define a static value for the variable if no data is available from that meta field.
This is the code that will be utilizing the "customamznsearch" variable.
<script type="text/javascript">
amzn_assoc_placement = "adunit0";
amzn_assoc_tracking_id = "livcouintheci-20";
amzn_assoc_ad_mode = "search";
amzn_assoc_ad_type = "smart";
amzn_assoc_marketplace = "amazon";
amzn_assoc_region = "US";
amzn_assoc_textlinks = "";
amzn_assoc_linkid = "0c1ce8995df23ae16ec99d3bb32502ec";
amzn_assoc_default_category = "SportingGoods";
amzn_assoc_default_search_phrase = customamznsearch;
</script>
<script src="//z-na.amazon-adsystem.com/widgets/onejs?MarketPlace=US"></script>
This code will be displayed in an Enhanced Text Widget in the footer of my page. The Enhanced Text widget should be fully capable of supporting Text, HTML, CSS, JavaScript, Flash, Shortcodes, and PHP.
After much research, the following snippet of code was what ended up working (please note that I decided to change the variable to 'amazonadserach'):
var amazonadsearch = "<?php global $post;
$amazonadsearch = get_post_meta($post->ID, 'amazonadsearch', true);
echo $amazonadsearch; ?>";
You can just output javascript code from php like this:
<script>
var customamznsearch = "<?php echo addcslashes($customamznsearch, '"'); ?>";
</script>
Or if you mean to get it from the <meta> tags, then:
function getMeta(metaName) {
var metas = document.getElementsByTagName('meta');
for (i=0; i<metas.length; i++) {
if (metas[i].getAttribute("name") == metaName) {
return metas[i].getAttribute("content");
}
}
return "";
}
var twitterTitle = getMeta("twitter:title");
I'm pretty new to javascript, and therein probably lies my problem. I'm trying to track AdWords conversions that occur within a widget on our site. The user fills in a form and the result from the widget is published in the same div without a page refresh. The issue I'm having is when I try to appendChild (or append in jQuery) both script elements in Google's code (shown below) the page gets 302 redirected to a blank Google page (or at least that's what it looks like through FireBug).
I'm able to provide a callback method for the results of the form, and that's where I'm trying to insert the AdWords tracking code. For reference, this is the code provided by Google:
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 993834405;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "bSpUCOP9iAIQpevy2QM";
/* ]]> */
</script>
<script type="text/javascript" src="http://www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt="" src="http://www.googleadservices.com/pagead/conversion/993834405/?label=bSpUCOP9iAIQpevy2QM&guid=ON&script=0"/>
</div>
</noscript>
Pretty standard stuff. So, what I'm trying to do is insert this into the results page using the callback method (which is provided). Frankly, I'm redirected no matter when I try to insert this code using js or jQuery (either on original page load or in the callback) so maybe the callback bit is irrelevant, but it's why I'm not just pasting it into the page's code.
I've tried a number of different ways to do this, but here's what I currently have (excuse the sloppiness. Just trying to hack my way through this at the moment!):
function matchResultsCallback(data){
var scriptTag = document.createElement('script');
scriptTag.type = "text/javascript";
scriptTag.text = scriptTag.text + "/* <![CDATA[ */\n";
scriptTag.text = scriptTag.text + "var google_conversion_id \= 993834405\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_language \= \"en\"\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_format \= \"3\"\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_color \= \"ffffff\"\;\n";
scriptTag.text = scriptTag.text + "var google_conversion_label \= \"bSpUCOP9iAIQpevy2QM\"\;\n";
scriptTag.text = scriptTag.text + "/* ]]> */\n";
$('body').append(scriptTag);
$('body').append("<script type\=\"text\/javascript\" src\=\"http://www.googleadservices.com/pagead/conversion.js\" />");
//I have also tried this bit above using the same method as 'scriptTag' with no luck, this is just the most recent iteration.
var scriptTag2 = document.createElement('noscript');
var imgTag = document.createElement('img');
imgTag.height = 1;
imgTag.width = 1;
imgTag.border = 0;
imgTag.src = "http://www.googleadservices.com/pagead/conversion/993834405/?label=bSpUCOP9iAIQpevy2QM&guid=ON&script=0";
$('body').append(scriptTag2);
$('noscript').append(imgTag);
}
The really odd thing is that when I only insert one of the script tags (it doesn't matter which one), it doesn't redirect. It only redirects when I try to insert both of them.
I've also tried putting the first script tag into the original page code (as it's not making any calls anywhere, it's just setting variables) and just inserting the conversions.js file and it still does the redirect.
If it's relevant I'm using Firefox 3.6.13, and have tried the included code with both jQuery 1.3 and 1.5 (after realizing we were using v1.3).
I know I'm missing something! Any suggestions?
Nowadays it is convenient to use the Asynchronous Tag at http://www.googleadservices.com/pagead/conversion_async.js that exposes the window.google_trackConversion function.
This function can be used at any time. For example after submitting a form, like in your case.
See https://developers.google.com/adwords-remarketing-tag/asynchronous/
Update 2018
Situation changed and it seems that you have more options now with the gtag.js: https://developers.google.com/adwords-remarketing-tag/
If you're using jQuery in your pages, why don't you use the getScript method of the same to poll the conversion tracking script after setting the required variables?
This is what I usually do, once I've received a success response from my AJAX calls.
var google_conversion_id = <Your ID Here>;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "<Your Label here>";
var google_conversion_value = 0;
if (100) {
google_conversion_value = <Your value here if any>;
}
$jQ.getScript( "http://www.googleadservices.com/pagead/conversion.js" );
This works just fine for me. If you want a more detailed example:
$.ajax({
async: true,
type: "POST",
dataType: "json",
url: <Your URL>,
data: _data,
success: function( json ) {
// Do something
// ...
// Track conversion
var google_conversion_id = <Your ID Here>;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "<Your Label here>";
var google_conversion_value = 0;
if (100) {
google_conversion_value = <Your value here if any>;
}
$.getScript( "http://www.googleadservices.com/pagead/conversion.js" );
} // success
});
If you use other libraries such as Mootools or Prototype, I'm sure they have similar in-built methods. This AFAIK is one of the cleanest approaches.
this simple code worked for me (the $.getScript version didn't).
var image = new Image(1,1);
image.src = 'http://www.googleadservices.com/pagead/conversion/' + id + '/?label=' + label + ' &guid=ON&script=0';
// This takes care of it for jQuery. Code can be easily adapted for other javascript libraries:
function googleTrackingPixel() {
// set google variables as globals
window.google_conversion_id = 1117861175
window.google_conversion_language = "en"
window.google_conversion_format = "3"
window.google_conversion_color = "ffffff"
window.google_conversion_label = "Ll49CJnRpgUQ9-at5QM"
window.google_conversion_value = 0
var oldDocWrite = document.write // save old doc write
document.write = function(node){ // change doc write to be friendlier, temporary
$("body").append(node)
}
$.getScript("http://www.googleadservices.com/pagead/conversion.js", function() {
setTimeout(function() { // let the above script run, then replace doc.write
document.write = oldDocWrite
}, 100)
})
}
// and you would call it in your script on the event like so:
$("button").click( function() {
googleTrackingPixel()
})
In your Adwords account - if you change the conversion tracking event to "Click" instead of "Page Load" it will provide you with code that creates a function. It creates a snippet like this:
<!-- Google Code for Developer Contact Form Conversion Page
In your html page, add the snippet and call
goog_report_conversion when someone clicks on the
chosen link or button. -->
<script type="text/javascript">
/* <![CDATA[ */
goog_snippet_vars = function() {
var w = window;
w.google_conversion_id = <Your ID Here>;
w.google_conversion_label = "<Your value here if any>";
w.google_remarketing_only = false;
}
// DO NOT CHANGE THE CODE BELOW.
goog_report_conversion = function(url) {
goog_snippet_vars();
window.google_conversion_format = "3";
window.google_is_call = true;
var opt = new Object();
opt.onload_callback = function() {
if (typeof(url) != 'undefined') {
window.location = url;
}
}
var conv_handler = window['google_trackConversion'];
if (typeof(conv_handler) == 'function') {
conv_handler(opt);
}
}
/* ]]> */
</script>
<script type="text/javascript"
src="//www.googleadservices.com/pagead/conversion_async.js">
</script>
Then in your code you just call:
goog_report_conversion();
Or for a link or image click:
click here
After trying everything the link Funka provided (http://articles.adamwrobel.com/2010/12/23/trigger-adwords-conversion-on-javascript-event) was what worked for me. Like he said it's scary to overwrite document.write, but
It seems like this is what you have to do unless you can load the script before the page load.
Since the script uses document.write so it needs to be re-written
document.write = function(node){ // exactly what document.write should of been doing..
$("body").append(node);
}
window.google_tag_params = {
prodid: pageId,
pagetype: pageTypes[pageType] || "",
value: "234324342"
};
window.google_conversion_id = 2324849237;
window.google_conversion_label = "u38234j32423j432kj4";
window.google_custom_params = window.google_tag_params;
window.google_remarketing_only = true;
$.getScript("http://www.googleadservices.com/pagead/conversion.js")
.done(function() {
// script is loaded.
});
See https://gist.github.com/c7a316972128250d278c
As you have seen, the google conversion tag only calls on a redraw. I had to make sure it was called when a part of a page was redrawn. (Due to some bad website design that I could not fix at the moment.) So I wrote a function to call from an onClick event.
Essentially, all you have to do is to call doConversion();
Here is what we ended up with:
// gothelp from from http://www.ewanheming.com/2012/01/web-analytics/website-tracking/adwords-page-event-conversion-tracking
var Goal = function(id, label, value, url) {
this.id = id;
this.label = label;
this.value = value;
this.url = url;
};
function trackAdWordsConversion(goal, callback) {
// Create an image
var img = document.createElement("img");
// An optional callback function to run follow up processed after the conversion has been tracked
if(callback && typeof callback === "function") {
img.onload = callback;
}
// Construct the tracking beacon using the goal parameters
var trackingUrl = "http://www.googleadservices.com/pagead/conversion/"+goal.id;
trackingUrl += "/?random="+new Date().getMilliseconds();
trackingUrl += "&value="+goal.value;
trackingUrl += "&label="+goal.label;
trackingUrl += "&guid=ON&script=0&url="+encodeURI(goal.url);
img.src = trackingUrl;
// Add the image to the page
document.body.appendChild(img);
// Don't display the image
img.style = "display: none;";
}
function linkClick(link, goal) {
try {
// A function to redirect the user after the conversion event has been sent
var linkClickCallback = function() {
window.location = link.href;
};
// Track the conversion
trackAdWordsConversion(goal, linkClickCallback);
// Don't keep the user waiting too long in case there are problems
setTimeout(linkClickCallback, 1000);
// Stop the default link click
return false;
} catch(err) {
// Ensure the user is still redirected if there's an unexpected error in the code
return true;
}
}
function doConversion() {
var g = new Goal(YOUR CODE,YOUR_COOKIE,0.0,location.href);
return linkClick(this,g);
}
I tried all the ways to manually include conversion.js, it all loaded the script, but didn't further execute what we needed inside the script, there's a simple solution.
Just put your conversion code in a separate HTML, and load it in an iframe.
I found code to do that at http://www.benjaminkim.com/ that seemed to work well.
function ppcconversion() {
var iframe = document.createElement('iframe');
iframe.style.width = '0px';
iframe.style.height = '0px';
document.body.appendChild(iframe);
iframe.src = '/track.html'; // put URL to tracking code here.
};
then just call ppcconversion() wherever in the JS you like to record it.
All I do is return the code (or in our case, an image) along with the "success" message in the callback.
When a contact form is submitted, or a registration form filled out and submitted, we post to a php script using jQuery, then output a "thank-you" message to a div:
"$first_name, Thanks for requesting more information. A representative will contact you shortly."
... followed by the 1x1 gif Google provides.
Here's the jQuery:
$.post('script.php',{'first_name':first_name,'last_name':last_name,'email':email,'phone1':phone1,'password':password,},function(data){
var result=data.split("|");
if(result[0] ==='success'){
$('#return').html(result[1] + $result[2]);
And the php...
echo 'success|'.$first_name.', Thanks for requesting more information.
A representative will contact you shortly.|<img height="1" width="1" alt="" src="http://www.googleadservices.com/pagead/conversion/xxxxxxxx/imp.gif?value=0&label=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&script=0"/>';
You might need to throw in a "document.location.reload();" if it isn't being picked up by google
For anyone still looking for a good solution to this, Google supports AJAX Conversions natively now through their Google Analytics API.
You can do it by making a event API call in Google Analytics. What you do is setup an Analytics event, tie it to a goal, then import that goal into AdWords as a conversion. It's a bit of a lengthy process but it's a clean solution.
Check out This Page for a tutorial
This works for me:
window.google_trackConversion({
google_conversion_id: 000000000,
conversion_label : "xxxxxxxxxxxx",
google_remarketing_only: false,
onload_callback : function(){
//do something :)
}
});