Using AdWords to determine best book title

I love the simplicity and speed of this concept... I believe this idea could be used for the name evaluation for almost anything  - from company to product to URL to brand names - almost anything could be run through this algorithym.


Wired: Speaking of testing, I assume you market-tested the title of the book?
Ferriss: Oh yeah, with about 4,000 people, in three separate rounds. Testing is how I ended up with the title of The 4-Hour Workweek as well. That was one of about 12 titles I tested using Google AdWords.
I bid on keywords or phrases associated with the book content, like “world travel,” “401K,” etc.
And then the ads that were displayed had the title of the book as the headline and the subtitle as the ad text. And then I just looked at the clickthrough rates.
Wired: What was on the pages when people clicked through?
Ferriss: Nothing. Just “under construction”.

From this Wired article:


7 essential geek skills for the modern marketing master


1. Facebook

2. Web analytics


4. Email

5. Mobile devices

6. PPC (Pay-per-click)

7. Excel


Using oAuth Twitter protocol with VBScript Classic ASP

Update: My twitter feed stopped working when the API was modified October 10, 2012. Luckily changing the code was straight forward and required simply updating the destination for the various post/get statements with the new HTTPS urls as so:

' TWITTER CONSTANTS (add to suite)
'' Const TWITTER_OAUTH_URL_ACCESS = "http://twitter.com/oauth/access_token"
 Const TWITTER_OAUTH_URL_ACCESS = "https://api.twitter.com/oauth/access_token"

'' Const TWITTER_OAUTH_URL_AUTHENTICATE = "http://twitter.com/oauth/authenticate"
 Const TWITTER_OAUTH_URL_AUTHENTICATE = "https://api.twitter.com/oauth/authenticate"

'' Const TWITTER_OAUTH_URL_REQUEST_TOKEN = "http://twitter.com/oauth/request_token"
 Const TWITTER_OAUTH_URL_REQUEST_TOKEN = "https://api.twitter.com/oauth/request_token"

'' Const TWITTER_OAUTH_URL_UPDATE_STATUS = "http://twitter.com/statuses/update.json"
 Const TWITTER_OAUTH_URL_UPDATE_STATUS = "https://api.twitter.com/1.1/statuses/update.json" '--updated 10/18/2012

The recent move from REST to oAuth protocol for the twitter API left some developers (like me) scratching our heads. Most of the sample code was written either for PHP or .NET folks - leaving those poor bastards who are still writing VBScript out in the cold.

Luckily for us - Scott at http://scottdesapio.com/VBScriptOAuth/ has put together a great resource for migration to the new platform.

Start with the link above then note that you must:
1. update the _config file with vars supplied by twitter dev site AFTER you register your app. Note that at the time of registration you must provide your call back url (which in the example from scott would be something like http://www.logsitall.com/oAuthASPExample/twitter/callback.asp)

2. update line 40 of base.js file

3. update base.js to refer to your domain, not

4. comment out the if statement that seeks to assign window focus to at the end of the base.js file

When you are done, you'll have a system that requests the token from twitter and then uses this token in conjunction with the token's associated with your app to make posts to twitter status feeds.
From a dB standpoint - i think you only need to store the user token - then pair this with the app tokens (which are persistent) in order to make twitter updates on behalf of your users.

Good luck and happy coding.

LogsItAll example:



The value of education

I've grown increasingly jaded about the cost of higher education in this country vs. the economic value. As I start to blog and post, I'm collecting articles and responses under the tag "education ROI"

Original Article:

Bill_Patton [Moderator] 5 days ago



Bjpower2 [Moderator] 19 hours ago in reply to Bill_Patton


cross domain tracking GA

been having trouble with cross domain tracking issues - turns out that the documentation on the google site was wrong... classic. This was the response from the big G:

Hello Bill,

Thank you for your email. We greatly appreciate any feedback or suggestions for ways we can improve Google Analytics.

Please note that I have informed the concerned team about the error in the documentation. As you mentioned, the article is incorrect:

<a href="https://www.secondsite.com/?login=parameters"
onclick="_gaq.push(['_link', 'http://www.firstsite.com']); return false;">Login Now</a>

It should be:

'https://www.secondsite.com/?login=parameters']); return false;">Login Now</a>

Thanks for bringing this to our attention. Please note that this documentation will soon be edited.

If you have additional questions, please visit our Help Center at http://adwords.google.com/support/aw/, where you'll find answers to many frequently asked questions. We look forward to providing you with the most effective advertising available.


The Google AdWords Team


Idiots guide to android app development

Still a work in progress. Got stuck at:
could not find virtual device when i created my avd. Turns out to be some crap with windows file structure.


more to come if i can ever get this to work at all.

after updating the environment var following the above link - i now get

"An internal error occurred during: "Launching HelloAndroid".

So far, google android developing sucks.



Implementing the new Facebook Social Plugins







The result?


to summarize:

First, set up a new application:

1. Go to: http://www.facebook.com/developers

Happy coding.



Conversion tracking 101

1. tag ads (in other words use the link i just sent to append the destination that visitors go to when clicking your banner ads).
[3:47:56 PM] bill patton: 2. Set up the "goals" within your GA account.
[3:48:42 PM] bill patton: **each goal would be something like "submitted custom quote" or "submitted regular quote". You'll set up a goal for each of your contact/conversion types.
[3:49:08 PM] bill patton: This is done at the root level within your GA account by deciding which page defines a conversion (usuall a 'thank you page' or similar).
[3:50:06 PM] bill patton: 3. Once you have set up the goals and tags within GA and your advertising vendor you'll see within your GA account "traffic sources" - campaigns.
[3:50:26 PM] bill patton: Within each campaign you will see the # of visits and the # of conversions - giving your the conversion info you are looking for.
[3:51:11 PM] bill patton: 4. for bonus credit - calculate your average revenue per conversion - you can associate a $$ value for each conversion rule - this will then let you start calculating the value/click vs. the cost/click you are paying for.


Google Re-Marketing and Post Impression Conversion Tracking

Google has recently implemented two interesting display (content network) specific options.

1. Post Impression Conversion tracking
2. Re-marketing (Audience targeting)

Post impression tracking allows you to track web based conversions that happen after an individual view (as opposed to clicks) a display ad. Since we are finding that content network buys garner huge impressions but low clicks as a general rule - this promises to allow us to attach some value to the impressions.

The re-marketing concept allows you to define a page on a clients website (for instance the lodging options page for a resort) that would in turn 'cookie' visitors to this page and add them to an audience that you define. You can then use this audience rule to limit the distribution of specific ads. In the case of lodging page visitors you would be able to run a discount lodging offer that would be exposed only to those individuals who have visited your lodging page. By adding a second "negative" criteria of "not part of the audience defined as those who have visited an online booking confirmation page" you can show this discount offer only to those who have visited the lodging options page but have not purchased.

To date i've put together one small campaign using these two techniques - has anyone else experimented with these techniques from within the adwords platform - and seen conversion/response rate lifts?

Importing GA data to excel using excellentanalytics

Just started testing this service - so far VERY promising. More to come...

Excellent Analytics


Why XM radio sucks...

Remember when XM radio was the coolest thing since sliced bread? For woodchucks like me - living in the last of one (bad country) radio station plus public radio - commercial radio was a wasteland of odd talk show programming and songs about dying dogs and fishing.

Enter XM radio - suddenly for a couple of hundred dollars/year plus a minimal investment in hardware your radio could pull in hundreds of radio stations -all crystal clear and commercial free! That giant sucking sound you heard was from all the teens and commuting adults migrating towards the satellite sounds from the sky and away from bad radio. Ahh... how things change!

Today my iPhone can pull in (for free - at least for incrementally free) Slacker, Pandora, AOL radio and more - all for free. And not only are they free - but most respond to my preferences and deliver music that I actually like.

After letting my XM subscription lapse - i was enticed back into the fold with an introductory offer which i jumped on. Here in northern vermont, cell reception is spotty and the thought of consistent 3g is still mostly a fantasy.

XM radio was once again a mainstay of my morning commute - however unlike years past i had no use for it at home or the office. Once within wifi range, my iPhone and laptop connected to the home stereo system (used to broadcast netflix movie sound) provided better radio sounds and more diversity.

A few month ago my promotional period expired and i suddenly found myself with fewer stations to choose from. Out of the dozens missing there was really only one (BB King Blues) that i really missed.

Here comes the kicker - even though i only listen to 6 stations on XM - i need to upgrade my sound package for an addition $100+/year just to get the one extra station i want. When you hold XM and their pricing model against the other options - which truly offer a guest of one experience - XM suddenly seems old school, outdated and overpriced.

As 3g coverage expands, smart phone based radio is going to continue the march towards territory that used to be reserved for XM - leaving them in the dust.

Unless XM radio can use their large number of radio stations and a hardware/smartphone way to deliver a custom listening experience to me - i'll be lost to them as a consumer for ever.

if you are still holding XM/sirius stock - i'd suggest a covered short sale.

ps. happily listening to pandora as i write this.


Patagonia becomes Patagucci

Each season when the new Patagonia catalog arrives I, like millions of other hard core uber groovy outdoor oriented upper income carefully targeted consumers, open the catalog to bask in the glory that is Patagonia. Oh, to be cool enough to get onto those glorious pages. What a goal. Of course, we can bask a little bit by shelling out several hundred dollars for a few ounces of carefully recycled plastic and thread. But we will never truly be worthy.

Maybe I'm getting jaded in my old age, but as the years have gone by I'm starting to view this whole process as highly suspect. I remember what it was like to be hard core - living in a VW camper bus and eating ramen. Oddly enough I don't remember Patagonia threads playing much of a role in my life. In fact, the notion of paying $400 for a down filled yuppie designed jacket would have seemed insane - when the same $400 would have bought a much needed new engine for the bus, or even better, another month of not having to work.

This season's catalog has some awesome photography featuring the likes of john Long and Lynne Hill - and copy that talks in noble terms about caring for the environment and the dangers of materialistic behavior. The cool dudes of the '70s weren't wearing designer organic jeans cut to flatter, they were wearing blown out khakis, cut to tatters.

I find it the height of hypocrisy to read the preachy copy promoting anti-materialism on the pages of the meticulously crafted catalog (optimized to generate maximum ROI per square inch of soy printed recycled pager) next to photos of overpriced garments sold in places like Newbury street.

While Chouinard iron works may have produced core gear at one time, today the vast majority of Patagonia clothing I see being bought by Newbury street shoppers is worn not by hard core dudes and dude'ettes but rather by people shopping for a jacket that matches the upholstery color of their range rover or using their daddy's black amex for lattes' and some snuggly fleece.

I still like Patagonia gear - but today I first look to other brands and outlets for my gear - going to Patagonia only when they have a technical feature set that i can't find elsewhere. To do anything else risks my becoming a caricature of the poser that Patagonia markets to today.


The bachelor



google analytics advanced segmentation for funnel analysis

many of you probably are already using goals and funnel visualization to analyze the performance of various conversion events on your website (shopping cart conversions, form completions, etc.)

One way to take your analysis to the next level is to use advanced segmentation to create a custom segment for each critical stage in your funnel - and then look for differences.

we recently observed that the time spent on one required page during a checkout process was 2 minutes longer for the segment of users who made it all the way through the process - as compared to those who didn't.

the conclusion? the required page was taking too long to complete - so our users were abandoning it.

advanced segmentation can be an amazing way to develop insights into web use - give it a try!


Adding live chat to conversion pages

One of the holy grails of web development is increasing conversion rates on key pages - new user registration, vacation booking, product purchasing, etc. In addition to traditional approaches, why not try adding a live chat client to the page - so that your customer support people can be there "virtually" during important conversion processes?

www.olark.com is one of many providers of this service. For the past couple of weeks i've been testing their web based service with good results. On this post you'll see a 'click here for...' overlay in the lower right hand corner of the page.

The concept is simple - create an account on olark.com - couple this with a chat client (they use jabber) and paste a few lines of javascript just before the close body tag on your key pages and you are ready to roll. Because i find myself having to offer support during off hours it was important for me to be able to offer chat support from my iPhone - this required two additional steps.

1. after configuring the olark account i used Meebo.com on olark's recommendation. Meebo.com is a universal web based chat client.

2. I tested a few iPhone chat apps and finally settled on meebo's own free iphone app - no ads, stable and free. Since the app stays 'online and available' by default - i was essentially able to offer 24/7 live chat support.

The verdict? Although my users don't take advantage of the feature very often - those that do are grateful. It is a bit tricky to remember to log off during my sleep hours or time away from the phone - so i've ammended my chat instructions to read "if you don't get an immediate response, please email..."

Good luck and happy coding.


Working with data type Duration Google Visualizations

i have a website that works with duration measures (length of workout
for instance). Values are stored in the dB as total seconds and
displayed to the user as HH:MM:SS.0

When attempting to migrate to the Google visualizations for displaying
data and charts, I have tried a variety of methods to work with this
type of information with mixed success- some things i tried were
pretty stupid in retrospect, as I progressed, my mistakes become more

Initial data table display
1. store "HH:MM:SS.0" as datatype=string
Appears correctly to the user, however doesn't sort correctly (sorts
alpha) and can't be charted. Bad idea.


2. store as time of day datatype=timeofday
This requires converting my seconds to the javascript time of day
array. This appeared correctly to the user (HH:MM:SS.0) and sorted
correctly - however since you can not plot timeofday datatype, when it
came time to display progress reports and ATL's this fell short.

3. Store as datatype=number but use the display value as HH:MM:SS.0
e.g. data.setCell(0,2,495,'8:15');
495 are the total seconds, 8:15 is what appears to the user

This works well for most chart types and gives me a great deal of
control over the way times are displayed (value labels are created
server side) - and the chart lines are drawn correctly - however in
the annotated timeline - the values that appear to the user on data
point mouse over are still the total seconds (495) instead of the
desired display value (8:15)

4. Store as datatype=number, but store the value as decimal minutes
This allows the axis that is shown to the user during charting to use
minutes as the unit (which is good) however on mouse click tooltip the
value that is shown to the user is the decimal minute value - which is

5. store as datatype=number, but store the value as minutes.seconds -
e.g. instead of storing 495 seconds as:
8.25 (decimal)

store as

8.15 (8 minutes, 15 seconds). Then use a formatter to make the decimal
separator ":" instead of the default "."

This supports correct sorting, correct graphing, correct ATL display
and makes a bit more sense to the user. It ceases to work when going
over 59.59 (over 1 hour duration). I have not figured out a way to
force the ATL to modify the decimal separator character.

If anyone else has struggled with similar issues i'd love to hear your
solution - if not maybe this will save some testing on some one else's

getting started with google table visualization


getting started: visit and book mark these two pages


The second rule - don't forget the first...

define # rows: data.addRows(6);
add data/cells:
data.setValue(0, 1, 30000);





The final result?

Using CDO on hostmysite.com with VBscript

If you are still stuck using VBscript (like me) and are using hostmysite.com on their .net servers - then you might find this useful. The standard VBscript email coding doesn't work - so you have to use a hybrid of sorts to get it to run. The code below works well...

Call the Sub - passing in the message you want.

Sub SendEmail(message)

Dim iMsg
Dim iConf
Dim Flds
Dim strHTML

Const cdoAnonymous = 0 'Do not authenticate
Const cdoBasic = 1 'basic (clear-text) authentication
Const cdoNTLM = 2 'NTLM

set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")

Set Flds = iConf.Fields

' Set the CDOSYS configuration fields to use port 25 on the SMTP server.

With Flds

 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "mail71.safesecureweb.com"
 .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "root@logsitall.com"
 .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "XXXX"


End With

' Build HTML for message body.

strHTML =  message

' Apply the settings to the message.
With iMsg
 Set .Configuration = iConf
 .To = "billp@hmc2agency.com"

 .Cc = "wkpatton@aol.com"

 .From = "admin@logsitall.com"
 .Subject = "Subject line using sub"
 .HTMLBody = strHTML

End With


' Clean up variables.
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

'MsgBox "Mail Sent!"

End Sub

VBScript Paypal IPN (Instant Payment Notification)

With paypal you can have a specific URL called as soon as a customer completes any transaction through the PayPal "instant payment notification" system. Getting this going requires the creation of the URL that paypal will 'talk to' as well as an understanding of the system. I use hostmysite.com (hosting.com) and code in VBscript - so i also had to figure out how to run CDO messaging with VBscript.

Read this to get started:



1. create a sandbox account at https://developer.paypal.com/us/cgi-bin/devscr?cmd=home/main -- this will allow you to test ping your IPN page.

2. Create the IPN page itself. Paypal offers examples using most languages - mine is VBscript - my page looks like this:
Sub SendEmail(message)

Dim iMsg
Dim iConf
Dim Flds
Dim strHTML

Const cdoAnonymous = 0 'Do not authenticate
Const cdoBasic = 1 'basic (clear-text) authentication
Const cdoNTLM = 2 'NTLM

set iMsg = CreateObject("CDO.Message")
set iConf = CreateObject("CDO.Configuration")

Set Flds = iConf.Fields


With Flds

 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "XXXXX"
 .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"


End With

' Build HTML for message body.
strHTML = message

' Apply the settings to the message.
With iMsg
 Set .Configuration = iConf
 .To = "billp@CCC"

 .Cc = "wkpatton@CCC.com"

 .From = "admin@logsitall.com"
 .Subject = "Subject line"
 .HTMLBody = strHTML

End With


' Clean up variables.
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing

End Sub

Dim Item_name, Item_number, Payment_status, Payment_amount
Dim Txn_id, Receiver_email, Payer_email
Dim objHttp, str

'read post from PayPal system and add 'cmd'
str = Request.Form & "&cmd=_notify-validate"

'post back to PayPal system to validate
'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP")
'set objHttp = Server.CreateObject("Msxml2.ServerXMLHTTP.4.0")
set objHttp = Server.CreateObject("Microsoft.XMLHTTP")

'--when using with real site

'--when using with sandbox site
objHttp.open "POST", "https://www.sandbox.paypal.com/cgi-bin/webscr", false

objHttp.Send str

'assign posted variables to local variables
Item_name = Request.Form("item_name")
Item_number = Request.Form("item_number")
Payment_status = Request.Form("payment_status")
Payment_amount = Request.Form("mc_gross")
Payment_currency = Request.Form("mc_currency")
Txn_id = Request.Form("txn_id")
Receiver_email = Request.Form("receiver_email")
Payer_email = Request.Form("payer_email")
Txn_type = Request.Form("txn_type")

'Check notification validation
if (objHttp.status <> 200 ) then

 'HTTP error handling

  Call SendEmail("Paypal confirmation 200 - payer is " & Payer_email)

 elseif (objHttp.responseText = "VERIFIED") then
  'check that Payment_status=Completed
  'check that Txn_id has not been previously processed
  'check that Receiver_email is your Primary PayPal email
  'check that Payment_amount/Payment_currency are correct
  'process payment

  Call SendEmail("Paypal confirmation Verified - payer is " & Payer_email & " and transaction type is: " & Txn_type)

 elseif (objHttp.responseText = "INVALID") then
  'log for manual investigation

  Call SendEmail("Paypal confirmation INVALID - payer is " & Payer_email)


end if

set objHttp = nothing

The code itself basically posts back a response to paypal - then i call a sub to send an email to me when done.

Tips and tricks: You have to use a different post back address when using the sandbox vs. the like site - you can see both - i've commented out the URL for the live version.
'--when using with real site

'--when using with sandbox site

3. Set up your account to call the IPN page.

Happy coding.

Update: In trying to deploy this for a client using wordpress I ran into a problem/conflict with a plugin called "Bad Bahavior". Turns out that this wordpress plugin was blocking the IPN call because the IPN call wasn't propertly formed HTML ("no header"). In order to make the IPN process work I had whitelist the PayPal IP address within the Bad Behavior settings. Once this was done, all was AOK.


Data viz on click test

So what do you think about this?

Build off col 1 | Build off col 2| Build off col 3

Using filter val from col: 1

Click on any row to use the value in col 1 to filter and display a progress report



Explicit div width settings - google viz tables

i recently ran into an issue with the <div> that contains data tables
on my website. The basic structure was:
<parent div.>
   <left hand column div sets width to 690, background color
    <viz table div no width specified, no inline style></div viz
   </div left hand column>
                               <right side bar div width specific
230></div right side bar div>
</div parent>

I initially found that unless i removed the background color from the
parent div style- the viz table div made links in the side bar div un-

The solution was to assign a specific width to the DIV that contains
the viz table. This prevented the viz table div from overlaying the
side bar div (even though the viz table width was itself specified -
the apparent real width of the viz table was the parent div width).

This was probably easily sorted out by someone with stronger CSS
skills - but it took me a bit of work to figure out.

Welcome to Brains not Brawn
