I've bashed up this Go twitter client below, the client still needs some work in terms of displaying the results, I'd like to represent the JSON result http://pastie.org/7298856 as a Go struct, I don't need all the fields in the JSON result, any pointers?
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
type TwitterResult struct{
}
var twitterUrl = "http://search.twitter.com/search.json?q=%23KOT"
func retrieveTweets(c chan<- string) {
for {
resp, err := http.Get(twitterUrl)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
c <- string(body)
}
}
func displayTweets(c chan string) {
fmt.Println(<-c)
}
func main() {
c := make(chan string)
go retrieveTweets(c)
for {
displayTweets(c)
}
}
I found this https://groups.google.com/forum/?fromgroups=#!topic/golang-nuts/dNjIs-O64do which is enough to point me in the right direction. Update: my implementation of the code
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
)
type twitterResult struct {
Results []struct {
Text string `json:"text"`
Ids string `json:"id_str"`
Name string `json:"from_user_name"`
Username string `json:"from_user"`
UserId string `json:"from_user_id_str"`
}
}
var (
twitterUrl = "http://search.twitter.com/search.json?q=%23UCL"
pauseDuration = 5 * time.Second
)
func retrieveTweets(c chan<- *twitterResult) {
for {
resp, err := http.Get(twitterUrl)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
r := new(twitterResult) //or &twitterResult{} which returns *twitterResult
err = json.Unmarshal(body, &r)
if err != nil {
log.Fatal(err)
}
c <- r
time.Sleep(pauseDuration)
}
}
func displayTweets(c chan *twitterResult) {
tweets := <-c
for _, v := range tweets.Results {
fmt.Printf("%v:%v
", v.Username, v.Text)
}
}
func main() {
c := make(chan *twitterResult)
go retrieveTweets(c)
for {
displayTweets(c)
}
}
The code works very well, I only wonder if creating a channel that is a pointer to a struct is idiomatic Go.
The encoding/json
package offers a way to unpack JSON directly into structs. The following example parses JSON content (a map) and assigns the fields to their corresponding targets identified by the struct tags. E.g., the key "someId"
is mapped to the struct field with the tag json:"someId"
. You can fiddle with the code here.
package main
import "fmt"
import "encoding/json"
type Example struct {
Id int `json:"someId"`
Content string `json:"someContent"`
}
func main() {
var xmpl Example
input := `{"someId": 100, "someContent": "foo"}`
json.Unmarshal([]byte(input), &xmpl)
fmt.Println(xmpl)
}
You can find details on the syntax in the docs. Fields that are not mentioned in the struct are ignored by default.