[dzach] 2008-6-25: How can one post a message to a google Blogger blog programmatically using TCL? Given the popularity of Google's Blogger platform, it might be a good idea to provide some basic functionality here. Google's '''Account Authentication API''' documentation can be found at: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html#ClientLogin and a guide for the API here: http://code.google.com/apis/blogger/developers_guide_protocol.html#CreatingPublicEntries Here is the code I've tried so far (corrected with the help of [Pat Thoyts] in the Tcler's Chat): namespace eval ::gpost { proc init {} { # packages http and tls are needed if {[catch { package require tls package req http } err] } { return $err } variable var variable login array set var { loginurl https://www.google.com/accounts/ClientLogin posturl http://www.blogger.com/feeds//posts/default timer_http 30000 } array unset login array set login { accountType GOOGLE Email Passwd service blogger source } ::http::register https 443 ::tls::socket set query [eval ::http::formatQuery [array get login]] # by specifying the -query option http::geturl sends a POST instead of a GET request, with a Content-type: application/x-www-form-urlencoded header # sent the POST request set token [::http::geturl $var(loginurl) -timeout $var(timer_http) -query $query] # to see what the reply was, uncomment the next line #parray $token upvar $token state # store login ids for later use foreach line [split [http::data $token] \n] { array set login [split $line =] } set login(httpcode) [lindex $state(http) 1] ::http::cleanup $token return $login(httpcode) } proc post args { # prepare ATOM XML variable var variable login array set data $args if {![info exists data(-body)] || $data(-body) eq ""} { return [set login(httpcode) 500] } append atom "" if {[info exists data(-title)] && ($data(-title) ne "")} { append atom "$data(-title)" } append atom "" append atom $data(-body) append atom "" if {[info exists data(-pubtime)] && ($data(-pubtime) ne "")} { append atom "$var(-pubtime)" } if {[info exists data(-categories)] && ($data(-categories) ne "")} { foreach cat $data(-categories) { append atom "" } } if {![info exists data(-draft)] || $data(-draft)} { append atom "yes" } if {[info exists data(-author)] && ($data(-author) ne "")} { append atom "$data(author)" if {[info exists data(-email)] && ($data(-email) ne "")} { append atom "$data(-email) " } append atom "" } append atom "" # the encoding should be utf-8 set atom [encoding convertto utf-8 $atom] # now that the post is in an ATOM XML structure, send it to google set token [::http::geturl $var(posturl) -timeout $var(timer_http) -query $atom -type application/atom+xml -headers [list Authorization "GoogleLogin auth=$login(Auth)"]] # to see what the server reply was, uncomment the next line parray $token # store http return code to be returned upvar $token state set login(httpcode) [lindex $state(http) 1] # free memory used ::http::cleanup $token return $login(httpcode) } }; # end namespace ::gpost A reply like: HTTP/1.0 200 OK Server: GFE/1.3 Content-Type: text/plain SID=DQAAAGgA...7Zg8CTN LSID=DQAAAGsA...lk8BBbG Auth=DQAAAGgA...dk3fA5N should be returned by the server upon login, where '''Auth=DQAAAGgA...dk3fA5N''' is the ''Auth'' (authorization) key to use in all subsequent requests. The key is stored in array value ::gpost::login(Auth), and a code 200 is returned if the login was successful. For a minimal post, the ''post'' command must include a ''-body'' option, so to send a post, type: ::gpost::post -body "This is a test" A code 201 is returned if the post was successful. ---- !!!!!! %|[Category Internet]|% !!!!!!