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

In today's business climate it should go without saying that any business that ignores the internet and associated technologies will be crushed and dismembered by competition that doesn't. In spite of the almost universal acceptance of this fact I consistently run into men and women in senior marketing positions within respected companies that have adopted a "that's not my job" attitude towards learning, adopting and understanding modern internet enabled marketing. If you are one of them (and you know it if you are...) then these 7 skills are written with you in mind.

1. Facebook
I'm simply boggled when I run into marketing directors who fear Facebook. Be you a VP, Director or Manager of marketing, if you don't embrace Facebook, learn it, use it, integrate into your personal life and then look at your competition through Facebook eyes you are, quite frankly, a dinosaur. Like those ancient reptiles, you and your career are rapidly approaching extinction and the slow fade into irrelevance. Simply delegating responsibility for Facebook use to subordinates or an agency is a cheap and ineffectual cop out. Until you "get it" at a personal level, throwing money at consultants is a waste of your marketing budget dollars, since you won't understand the efforts, results or potential.

2. Web analytics
Every website on the planet needs to have an analytic package (like Google analytics) installed. Most do. Unfortunately, what needs to be connected to the analytic package is a human brain. Yours! If your idea of information management is to have someone put a report on your desk once a week, you are destined to always be looking at out of date data. To short circuit this process, learn how to answer basic questions yourself. It isn't hard, and what you will quickly learn is that you and your strategic brain are the best person to pose questions and look for information. Too many marketing people simply dismiss this as "not my job" or think that by delegating it they have solved the problem. Don't be weak minded. Embrace the quant side of your job, learn the basics and you'll be able to get answers to your questions in seconds.

I can already see your eyes rolling. "I don't need to know this". "What a waste of my time". Wrong on both counts. HTML and web construction technology are the underpinnings of the entire world. If you don't have a basic vocabulary and understanding of what web pages consist of, then you are ignorant, vulnerable and out of date. Too many times I've seen smart people unwilling to learn even a little bit of tech, only to be taken advantage of by those who know more about it than they.

4. Email
Seriously. If you don't know how bulk email works, what the can-spam act involves, how to measure email performance, what makes good email design, how to benchmark your email program, how to integrate email into your communication plans, you might as well go home early and enjoy that second martini. In spite of advances in all sorts of groovy new technology, email is here to stay.

5. Mobile devices
If you are a senior marketing manager and are still carrying a dumb cell phone, dial zero and ask for your VCR back. Then take the rest of the day off. We live in a world where many people only have a cell number, email is considered old fashioned and formal and 90% of all non-work activity starts on smart phone. How does your company present itself to a smart phone user? How do you?

6. PPC (Pay-per-click)
Ever notice those annoying little ads that appear when you search for something in google? The ones above and to the right of your search results? You might not ever click on them, but your customers do. Especially if they are relevant to what they are looking for. Especially if the organic search results aren't. If you don't know how a PPC campaign runs, what parameters are available (wouldn't you like to talk to each person who visited your website without buying and offer them something special? Did you know you can? Did you know your competition already is?) and what your PPC strategy is, then you are simply not doing your job. Delegating without understanding isn't delegating. It's called being lazy. Learn about PPC and you'll better be able to make high level decisions about budget and strategy. Plus you'll start clicking on your competitor's ads just to piss them off.

7. Excel
What on earth is this doing here? I'm sure you all are already experts on excel. Just the other day you added a green background to three cells without even using the manual. The most underused application on the planet is excel. Did you know that excel can talk directly to Google analytics AND your internal database? Did you know that this allows your staff to create reports that automatically populate themselves with accurate and current information each time you open the file? Did you know that you can work collaboratively with excel using windows office live? Did you know that pressing control and down arrow at the same time moves to the bottom of a column? Given the amount of time you and your staff spend on excel, getting 5% more efficient can save thousands of hours each year, yet almost no one bothers to learn the more advanced features. Don't be one of the ignorant masses. If you do anything within excel more than 5 times in a row, there is a better way.


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
Fantastic article. I have for some time been comparing the "higher education bubble" with the housing bubble. Both were fueled by similar expectations for continuous growth and aggressive lending policies. As going to college came to be viewed a an inalienable right, lenders (with governmental blessings) stepped in to offer loans to all, with no regards or consideration for the underlying value of the degree being sought. Increased demand combined with cheap money led to spiraling college costs.

At some point, buying a $500,000 condo in California is as nonsensical as graduating $160,000 in debt for a liberal arts degree. In working with a few clients in the college lending space, I'm seeing a real backlash on the part of parents who no longer are willing (or even able) to underwrite $20,$30 or $40k/year tuition bills. Instead they are pushing quality community college classes for their children. I truly believe that many of our ivy crusted institutions are heading for a housing bubble type crash if they continue to decouple their tuition costs with the actual value of their degree.


Bjpower2 [Moderator] 19 hours ago in reply to Bill_Patton
Well said. I am in full agreement. For those who have real world skills, watching their portfolios for the "bubble-burst" of student debt and likely taxpayer bailout would be wise.
On the whole, the overall topic is almost too enormous for blog discussions. There is real value to gaining the ability for critical thought and systems thinking. With a good curriculum, a student learns to generalize the skills they learn from writing to applied statistics. While I have profound doubts about our current global higher educational institutions, a good programme will elevate a student's skills and abilities. The ROI on this is now in doubt -- for good reasons stated above. This is unlikely to be fixed by a myopic view on higher ed. It starts long before university.


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:

<a href="https://www.secondsite.com/?login=parameters"
'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

Facebook has an awesome collection of free social plugins available for web developers - as i started working with them i found very little in the way of "getting started" or "FAQ's" that were comprehensive enough to be useful. Most existing documentation assumed you were already part way there and left out steps. This is my try at a complete getting started tutorial.

1. Create a facebook (fb) profile for yourself (the developer) and then log into facebook using this profile.

2. Set up your fb application that will point to your website. THIS IS KEY! The result of this step will be the unique ID #'s that will allow everything else to happen. Visit this page http://developers.facebook.com/setup/ and follow the instructions.

3. Once you have created your application you are ready to visit:

This page/site will write out the basic code for you - even writing out complete HTML sample pages that hold the various options.

4. Copy/paste in the sample code - being careful to get exactly what you need.

The result?

http://www.logsitall.com/fb-test.asp shows the result of this process - through to a comments box/ auto login and like link.

to summarize:

First, set up a new application:

1. Go to: http://www.facebook.com/developers
2. Click on the + Set Up New Application button (at the top right of the page)
3. Type your Application Name (example: Mysite-Name Comments) > select Agree > click on Create Application
4. Go to the Connect tab (on the left tabs-list)
5. Enter your site url with an ending slash in Connect URL and click on Save Changes (for example: http://mysitedomainname.com/)
6. You will see your Application ID number (below your app API & Secret)
7. It will take between 2 to 20 minutes until it will be ready to use with.

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

Must be the worst tv show in history - made all the worst by the fact that thousands of men like me have to suffer through it while their girl friends are weeping on the sofa. Good thing it didn't conflict with the gold medal Olympic hockey final.


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

google offers a very cool way to display data in a dynamic fashion with little more effort that you'd spend building a standard html table - if you know how to do it...

getting started: visit and book mark these two pages

They will be your friend for the duration of the exercise. The first rule to remember when working with the tables:
1. Google will not tolerate a single error. period. Miss a comma, formatter, line, etc. and the whole thing simply won't render.

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

With this in mind - let's take a quick look at the structure.
add/define the columns: data.addColumn('date', 'Date');
define # rows: data.addRows(6);
add data/cells:
data.setValue(0, 0, new Date(2008, 1 ,1));
data.setValue(0, 1, 30000);

The number one thing that screwed me up was the data type - if you assign the type "number" and accidently put in a non-numeric value - then the table won't render. The second thing - the data format has to be in a google specific format as shown above: new Date(2008, 1 ,1). This date is actually Feb 1, 2008 - since the months start with zero. I had to write a vbscript function to create dates in this format (not knowing any other way to do it). Next tip - string values have to be enclosed in ' marks, numeric values can not be.

Last two problems i found - when rendering data that had been entered via text area - the table wouldn't render. I finally figured out that the text area (due to my wrap settings) was putting in vbLf (line breaks) - this was then rendering a line break in the html code that was trying to generate the table - and blowing up. Doing a Replace(raw-text,vbLf,"") did the trick. The last one was one that any decent javascript programmer would know for sure - i had to escape all ' chars - by rendering then as /' using a similar replace function.

The last problem didn't really have anything to do with the table itself - instead it was a css/style issue - where the background color that was assigned to a div was selectively hiding text within the div ONLY when the google table was present and rendered (and only in IE browsers). If the table javascript code was there, but the table didn't load (due to an error) the div/background color issue wouldn't happen. The text would appear and dissapear when specific mouse over patterns occured over the google table. very odd. on the production site i solved this issue by using an inline style within the div that normally had a background color <-div style="background:'';"-> IE browser had the background color supressed - allowing the text to be seen, firefox and others ignored this command and still showed the background color.

Update: assigning an explicit width to the div that holds the datatable prevented the table from 'spilling over onto' the content in the other column.

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 cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory.
Const cdoSendUsingPort = 2 'Send the message using the network (SMTP over the network).

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/sendusing") = cdoSendUsingPort
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "mail71.safesecureweb.com"
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 15
 .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "root@logsitall.com"
 .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "XXXX"
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False


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 cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory.
Const cdoSendUsingPort = 2 'Send the message using the network (SMTP over the network).

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/sendusing") = cdoSendUsingPort
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "XXXXX"
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 15
 .Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = "root@XXXXX.com"
 .Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = "password"
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25
 .Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False


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
'objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false

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

objHttp.setRequestHeader "Content-type", "application/x-www-form-urlencoded"
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
'objHttp.open "POST", "https://www.paypal.com/cgi-bin/webscr", false

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

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

Basically I needed a place to archive posts i make elsewhere in search of answers to technical problems, support emails i've sent in response to requests for help, and cool stuff that i might want to find later. I'm a numbers guy with quite a bit of experience developing technical websites with a community basis. Questions? Please feel free to post - anyone who has ever posted and received an answer from an un-named saviour (as i have many times) should welcome to chance to earn some karma points by doing the same in reverse.