Unable to retrieve facebook live comments in real-time - http

I want to retrieve facebook live comments in real time. I have read this documentation
This is my implementation:
func getLiveComments(liveId, token string) {
url := fmt.Sprintf("https://streaming-graph.facebook.com/%s/live_comments?access_token=%s&comment_rate=one_per_two_seconds&fields=from{name,id},message",
liveId, url.QueryEscape(token))
resp, err := http.Get(url)
if err != nil {
fmt.Printf("Get: %s\n", err)
return
}
defer resp.Body.Close()
reader := bufio.NewReader(resp.Body)
for {
// got stuck here
line, err := reader.ReadBytes('\n')
if err != nil {
break
}
log.Println(string(line))
}
}
But it got stuck at line, err := reader.ReadBytes('\n').
I can use the liveId and token to get comments from facebook Graph API

Related

Sending form-data in a POST request in golang

I'm trying to send form-data by making a post request. The api works fine (I've tested on postman), but I'm not sure why I'm having trouble to do it in golang. The form-data contains a task field and a file field. But if I do the following I get Bad Request. Any ideas why I might be getting this? Thanks in advance.
// Create new buffer and writer
buf := new(bytes.Buffer)
w := multipart.NewWriter(buf)
// read data from file
var fdata []byte
if fd, e := os.Open(pdf); e != nil {
log.Fatal(e)
} else {
fd.Read(fdata)
}
// create file field and write
part, err := w.CreateFormFile("file", pdf)
if err != nil {
log.Fatal(err)
}
part.Write(fdata)
// create the task field and write
part, err = w.CreateFormField("task")
if err != nil {
log.Fatal(err)
}
part.Write([]byte(os.Getenv("task")))
w.Close()
// Create a new request
req, err := http.NewRequest("POST", fmt.Sprintf("https://%v/v1/upload",os.Getenv("server")), buf)
// Set content type header
req.Header.Add("Content-Type", "multipart/form-data")
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
// other stuff

Go http request redirect

I am writing an API whichs has to redirect incoming requests to another service, the response must be forwarded to the original requester.
I figured a simple function like below should do the trick, but I was wrong.
I receive the data from my redirected response, however when I send it back to the initial request I receive this response without any data Could not get response. Error: socket hang up
If I try to execute the very same request using postman straight to the redirect URL it works perfectly fine.
func initialAssetsHandler(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println(err)
return
}
resp, err := http.Post(conf.redirectURL, "application/json", bytes.NewReader(body))
if err != nil {
log.Error(err)
}
defer resp.Body.Close()
buf := new(bytes.Buffer)
buf.ReadFrom(resp.Body)
log.Info(string(buf.Bytes()))
var data json.RawMessage
if err = json.NewDecoder(resp.Body).Decode(&data); err != nil {
fmt.Println(err)
return
}
helper.SendJsonRaw(w, 200, data)
}
Here is the SendJsonRaw function:
func SendJsonRaw(w http.ResponseWriter, status int, r json.RawMessage) error {
w.Header().Set(HeaderContentType, MimeApplicationJSON)
w.WriteHeader(status)
_, err := w.Write(r)
return err
}
The r.Body is read by the json decoder up to EOF, then when you pass it to the redirect request it looks empty to the http.Client and therefore it sends no body. You need to retain the content of the body.
For example you can do the following:
func initialAssetsHandler(w http.ResponseWriter, r *http.Request) {
body, err := ioutil.ReadAll(r.Body)
if err != nil {
fmt.Println(err)
return
}
var initialAssets TagAssets
if err := json.Unmarshal(&initialAssets, body); err != nil {
if !strings.Contains(err.Error(), "json: invalid use of ,string struct tag, trying to unmarshal") {
helper.SendJsonError(w, http.StatusBadRequest, err)
return
}
}
resp, err := http.Post(conf.redirectURL, "application/json", bytes.NewReader(body))
if err != nil {
log.Error(err)
}
defer resp.Body.Close()
log.Info(resp)
var data json.RawMessage
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
fmt.Println(err)
return
}
helper.SendJsonOk(w, data)
}

request.FormValue is empty in the 'net/http' in Go

I'm trying to create a simple http service with the endpoint to download file to the local system in Go. The link comes in ?uri tag, but when I want to get it I receive an empty string. I tried to parse the form of my request but it didn't help. Here is my code:
func main() {
http.HandleFunc("/download", DownloadHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
func DownloadHandler(writer http.ResponseWriter, request *http.Request) {
prsErr := request.ParseForm()
if prsErr != nil{
panic(prsErr)
}
uri := request.FormValue("?uri")
_, _ = writer.Write([]byte(uri))
err := DownloadFile("img.png", uri)
if err != nil {
panic(err)
}
}
func DownloadFile(filepath string, url string) error {
// Create the file
out, err := os.Create(filepath)
if err != nil {
return err
}
defer out.Close()
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
// Write the body to file
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}
I will appreciate any help! Thank you!
invalid at request.FormValue("?uri")
uri := request.FormValue("uri")

How to listen to firestore through RPC

I want to listen to real time changes in firestore and I am also only allowed to use Go. Since firestore SDK for Go doesn't have any option to listen for real time changes, I decided to use the firestore v1beta1 sdk.
I have written the following code to do that
func TestRPCHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
c, err := firestore.NewClient(context.Background())
databaseName := "projects/[project_name]/databases/(default)"
if err != nil {
panic(err)
}
stream, err := client.Listen(context.Background())
if err != nil {
panic(err)
}
request := &firestorepb.ListenRequest{
Database: databaseName,
TargetChange: &firestorepb.ListenRequest_AddTarget{
AddTarget: &firestorepb.Target{
TargetType: &firestorepb.Target_Documents{
Documents: &firestorepb.Target_DocumentsTarget{
Documents: []string{"projects/[project_name]/databases/(default)/[collection_name]"} ,
},
},
},
},
}
if err := stream.Send(request); err != nil {
panic(err)
}
if err := stream.CloseSend(); err != nil {
panic(err)
}
for {
resp, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
panic(err)
}
}
}
When I am doing this, the code does not detect any changes I bring about manually in the database. stream.Recv() just returns EOF and exits immediately. I even tried manually waiting by adding time.Sleep() but that does not help either.
You don't need the beta SDK or hacks to make this happen, I found the solution, it's pretty easy actually.
The https://firebase.google.com/docs/firestore/query-data/listen documentation does not contain an example for Go.
The source code of the firestore client API for Go has an unexported watchStream which we cannot directly use: https://github.com/googleapis/google-cloud-go/blob/master/firestore/watch.go#L130
Deep search of the repository shows that this is actually used on the DocumentSnapshotIterator and QuerySnapshotIterator at: https://github.com/googleapis/google-cloud-go/blob/master/firestore/docref.go#L644 and: https://github.com/googleapis/google-cloud-go/blob/master/firestore/query.go#L716.
The Collection contains a Snapshots method which returns the snapshot iterator that we want, after that all is easy, we just make an infivitive loop through its Next method.
Example:
cols, err := client.Collections(context.Background()).GetAll()
for _, col := range cols {
iter := col.Snapshots(context.Background())
defer iter.Stop()
for {
doc, err := iter.Next()
if err != nil {
if err == iterator.Done {
break
}
return err
}
for _, change := range doc.Changes {
// access the change.Doc returns the Document,
// which contains Data() and DataTo(&p) methods.
switch change.Kind {
case firestore.DocumentAdded:
// on added it returns the existing ones.
isNew := change.Doc.CreateTime.After(l.startTime)
// [...]
case firestore.DocumentModified:
// [...]
case firestore.DocumentRemoved:
// [...]
}
}
}
}
Yours, Gerasimos Maropoulos aka #kataras
Firebase's Get realtime updates with Cloud Firestore documentation currently indicates that Go is not yet supported.
// Not yet supported in Go client library

How to get a cookie from a HTTP Get request to a consecutive HTTP Post request

For testing I like to simulate signups. I get the signup page, fill in the form and post it. Apparently the session cookie that is provided by the server is not sent in the post request. If I access the server from a web browser all works fine. I can see that the response to Get contains the cookie. How can I add it to the PostForm?
func signup(name string, ret chan bool) {
var xsrf string
fmt.Println("Starting signup with", name)
response, err := http.Get("http://localhost:8080/signup")
if err != nil {
panic(err)
} else {
defer response.Body.Close()
buffer, _ := ioutil.ReadAll(response.Body)
xsrf = regXsrf.FindStringSubmatch(string(buffer))[1]
}
data := url.Values{}
data.Set("name", name)
data.Add("password", "111222")
data.Add("password2", "111222")
data.Add("groupcode", "AllesWirdGut")
data.Add("websocketstoken", xsrf)
response, err = http.PostForm("http://localhost:8080/signup", data)
if err != nil {
panic(err)
} else {
defer response.Body.Close()
}
}

Resources