TclLang Twitter feed

2019-08-08 @TclLang is a Twitter feed dedicated to Tcl. From the c.l.t. announcement:

Announcing @TclLang - a Twitter feed dedicated to Tcl. This is intended to be a low volume channel for announcements of software releases, articles, conferences and anything else of interest to the Tcl community.

The feed will include any announcements etc. of general interest from c.l.t, the wiki, Tclers' chat and the core mailing list. You can also DM or tweet @TclLang for other items you think might be of interest to the community at large, such as Tcl-related job openings, blogs etc.

Admins AM, APN.

SEH: Who's the admin for the @TclTk account?

Tweeting from Tcl

The easiest way to create a tweet from Tcl is to use a single access token. To use this method you need both the consumer key and secret and the access token and secret. These can be obtained from the twitter web site at [L1 ].

This code uses the oauth package.

package require oauth
package require http
package require tls

::http::register https 443 [list ::tls::socket -tls1 1]

# Modify the values below to match your own twitter tokens
# Consumer secret
oauth secret MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98CP644uQOE
# Consumer key
set key GDdmIQH6jhtmLUypg82g
# Access Token (oauth_token)
set token 819797-Jxq8aYUDRmykzVKrgoLhXSq67TEa5ruc4GJC2rWimw
# Access Token Secret (oauth_token_secret)
set secret J6zix3FfA9LofH0awS24M3HcBYXO5nI1iYe8EfBA
# --

proc tweet {str} {
    global key token secret

    set url

    dict set req oauth_consumer_key $key
    dict set req oauth_token $token
    dict set req status $str
    set oauth [oauth auth POST $url $req $secret]
    set tok [http::geturl $url -headers [list Authorization $oauth] \
      -query [http::formatQuery status $str]]
    puts [http::code $tok]
    http::cleanup $tok

tweet "Hello, World!"

If your application needs to be able to access different accounts, you have to go through the full OAuth authentication process, which involves the user going to a web page, logging in with their account, and entering a PIN into the application.

package require oauth
package require http
package require tls

::http::register https 443 [list ::tls::socket -tls1 1]

array set consumer {
    key     GDdmIQH6jhtmLUypg82g
    secret  MCD8BKwGdgPHvAuvgvz4EQpqDAtx89grbuNMRd7Eh98CP644uQOE

set requesturl
set accessurl
set authurl

proc geturl {url secret args} {
    set cmd [list http::geturl $url]
    if {[llength $args] & 1} {
        set method POST
        set args [dict merge [lassign $args query] $query]
        lappend cmd -query [http::formatQuery {*}$query]
    } else {
        set method GET
    set hdrs [list Authorization [oauth auth $method $url $args $secret]]
    set tok [{*}$cmd -headers $hdrs]
    set data [http::data $tok]
    puts $data
    http::cleanup $tok
    return $data

proc gettoken {url args} {
    if {[llength $args] & 1} {
        set args [lassign $args secret]
    } else {
        set secret ""
    set rc [dict create]
    foreach n [split [geturl $url $secret {*}$args] &] {
        lassign [split $n =] name val
        dict set rc $name $val
    return $rc

# Setup the oauth package with the consumer secret
oauth secret $consumer(secret)

# Acquire a request token
set dict [gettoken $requesturl \
  oauth_callback oob oauth_consumer_key $consumer(key)]
set token [dict get $dict oauth_token]
set secret [dict get $dict oauth_token_secret]

# Send the user to authorization
puts $authurl?oauth_token=$token
puts -nonewline "Please enter PIN: "
flush stdout
gets stdin pin

# Exchange a request token for an access token
set dict [gettoken $accessurl $secret \
  oauth_consumer_key $consumer(key) oauth_token $token oauth_verifier $pin]
puts $dict
set token [dict get $dict oauth_token]
set secret [dict get $dict oauth_token_secret]

# Make a resource request on a user's behalf
set query [list status "Testing the twitter oauth process"]
set data [geturl $secret $query \
  oauth_consumer_key $consumer(key) oauth_token $token]

puts $data

Setok - 2015-01-02 20:57:15

Twitter requires SSL for API requests as of January 2014, ie. the code with merely HTTP, not HTTPS, will not work.

aspect 2015-01-03: added tls and TLS1 (required post-POODLE) support to the above snippets in the obvious way.

vh 2018-07-01: the url from the first example ( ) now gives this error:

"{"errors":[{"message":"The Twitter REST API v1 is no longer active. Please migrate to API v1.1.","code":64}]} "