Open hajsf opened 2 years ago
Trying to make login screen as WhatsApp, where the QR is pushed to the client for scanning, so I wrote the below server code:
package main import ( "context" "fmt" "net/http" "os" "os/signal" "syscall" _ "github.com/mattn/go-sqlite3" "github.com/skip2/go-qrcode" "google.golang.org/protobuf/proto" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/store" "go.mau.fi/whatsmeow/store/sqlstore" "go.mau.fi/whatsmeow/types/events" waLog "go.mau.fi/whatsmeow/util/log" ) func eventHandler(evt interface{}) { switch v := evt.(type) { case *events.Message: fmt.Println("Received a message!", v.Message.GetConversation()) } } func main() { passer := &DataPasser{logs: make(chan string)} http.HandleFunc("/", passer.handleHello) go http.ListenAndServe(":9999", nil) store.DeviceProps.Os = proto.String("WhatsApp GO") dbLog := waLog.Stdout("Database", "DEBUG", true) // Make sure you add appropriate DB connector imports, e.g. github.com/mattn/go-sqlite3 for SQLite container, err := sqlstore.New("sqlite3", "file:datastore.db?_foreign_keys=on", dbLog) if err != nil { panic(err) } // If you want multiple sessions, remember their JIDs and use .GetDevice(jid) or .GetAllDevices() instead. deviceStore, err := container.GetFirstDevice() if err != nil { panic(err) } clientLog := waLog.Stdout("Client", "DEBUG", true) client := whatsmeow.NewClient(deviceStore, clientLog) client.AddEventHandler(eventHandler) if client.Store.ID == nil { // No ID stored, new login qrChan, _ := client.GetQRChannel(context.Background()) err = client.Connect() if err != nil { panic(err) } for evt := range qrChan { switch evt.Event { case "success": { passer.logs <- "success" fmt.Println("Login event: success") } case "timeout": { passer.logs <- "timeout" fmt.Println("Login event: timeout") } case "code": { passer.logs <- "new code" fmt.Println("new code recieved") img, err := qrcode.Encode(evt.Code, qrcode.Medium, 200) // evt.Code if err != nil { fmt.Println("error when write qrImage", err.Error()) } passer.logs <- string(img) } } } } else { // Already logged in, just connect passer.logs <- "Already logged" fmt.Println("Already logged") err = client.Connect() if err != nil { panic(err) } } // Listen to Ctrl+C (you can also do something else that prevents the program from exiting) c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt, syscall.SIGTERM) <-c client.Disconnect() }
With the below api:
package main import ( "bytes" "fmt" "log" "net/http" "strconv" "sync" ) var ( mux sync.Mutex ) type Result struct { ResultType, Result string } type DataPasser struct { logs chan string } func (p *DataPasser) handleHello(w http.ResponseWriter, r *http.Request) { setupCORS(&w, r) w.Header().Set("Content-Type", "text/event-stream") flusher, ok := w.(http.Flusher) if !ok { http.Error(w, "Internal error", 500) return } flusher.Flush() done := r.Context().Done() defer fmt.Println("EXIT") for { select { case <-done: // the client disconnected return case m := <-p.logs: fmt.Println(m) if m == "new code" || m == "We are logging in" || m == "Already logged" || m == "timeout" || m == "success" { if _, err := fmt.Fprintf(w, "data: %s\n\n", m); err != nil { // Write to connection failed. Subsequent writes will probably fail. return } flusher.Flush() } else { mux.Lock() buffer := bytes.NewBuffer([]byte(m)) /* img, _, err := image.Decode(buffer) if err != nil { fmt.Println("err: ", err) } if err := jpeg.Encode(buffer, img, nil); err != nil { log.Println("unable to encode image.") } */ w.Header().Set("Content-Type", "image/jpeg") w.Header().Set("Content-Length", strconv.Itoa(len(buffer.Bytes()))) if _, err := w.Write(buffer.Bytes()); err != nil { log.Println("unable to write image.") } mux.Unlock() flusher.Flush() } } } } func setupCORS(w *http.ResponseWriter, req *http.Request) { (*w).Header().Set("Cache-Control", "no-cache") (*w).Header().Set("Connection", "keep-alive") (*w).Header().Set("Access-Control-Allow-Origin", "*") (*w).Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") (*w).Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") }
But stuck to read it in the client, I tried something as below, but got lost:
<html> <head></head> <body> note: <span id="content"></span><br> <img id="photo" style="display: block;-webkit-user-select: none;"> </body> <script> /* (function(){ document.getElementById("content").innerHTML='<object type="text/html" data="http://localhost:9999/" ></object>'; })(); */ const myRequest = new Request('http://127.0.0.1:9999/', { method: 'GET', headers: new Headers(), type: "arraybuffer", mode: 'cors', cache: 'default', }); var source = new EventSource("http://127.0.0.1:9999/"); source.onmessage = function (event) { console.log(event) var counter = event.data; // JSON.parse(event.data); document.getElementById("content").innerHTML = counter; } fetch(myRequest).then(response => { console.log(response) console.log(response.headers) const contentType = response.headers.get("content-type"); if (contentType && contentType.indexOf("application/json") !== -1) { return response.json().then(data => { var obj = JSON.parse(str); console.log(obj) // Process your data as a JavaScript object }); } if (contentType && contentType.indexOf("image/jpeg") !== -1) { console.log("Image received") return response.blob().then(data => { var reader = new FileReader(); reader.readAsDataURL(blob); reader.onloadend = function() { var imageUrl = reader.result; var img = document.querySelector("#photo"); img.src = imageUrl; } }); } else if (contentType && contentType.indexOf("text/event-stream") !== -1) { return response.text().then(text => { console.log(text) var source = new EventSource("http://localhost:9999/"); source.onmessage = function (event) { var response = event.data // JSON.parse(event.data); document.getElementById("content").innerHTML = counter; } // Process your text as a String }); } else if (contentType && contentType.indexOf("text/html") !== -1) { return response.text().then(text => { console.log(text) var source = new EventSource("http://localhost:9999/"); source.onmessage = function (event) { var response = event.data // JSON.parse(event.data); document.getElementById("content").innerHTML = counter; } // Process your text as a String }); } }); </script> </html>
If I run and see the displayed page, I see:
Any help?
Trying to make login screen as WhatsApp, where the QR is pushed to the client for scanning, so I wrote the below server code:
With the below api:
But stuck to read it in the client, I tried something as below, but got lost:
If I run and see the displayed page, I see:
Any help?