Giter VIP home page Giter VIP logo

Comments (8)

vaibhavgeek avatar vaibhavgeek commented on June 2, 2024 2

Hi, as @Rhymen already suggested. Here is what I did to call send message inside the handler.

Put this as the first line of code.
var wac, _ = whatsapp.NewConn(5 * time.Second)
Code for sending message in handler. (This is very dangerous code though, please manipulate it a little bit before using)

func (*waHandler) HandleTextMessage(message whatsapp.TextMessage) {
	msg := whatsapp.TextMessage{
		Info: whatsapp.MessageInfo{
			RemoteJid: message.Info.RemoteJid,
		},
		Text: "Message sent by github.com/Rhymen/go-whatsapp",
	}

	err = wac.Send(msg)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error sending message: %v", err)
	}
	fmt.Printf("%v %v\n\t%v\n", message.Info.Timestamp, message.Info.RemoteJid, message.Text)
}

Do not forget to remove wac *whatsapp.Conn parameter from the login function, as the variable is globally declared now.

An echo example that replies only for new queries would be really cool. Look forward to it.
Regards,

from go-whatsapp.

Rhymen avatar Rhymen commented on June 2, 2024 1

I implemented the writePump, messages can now be send without worrying about concurrenry.

from go-whatsapp.

Rhymen avatar Rhymen commented on June 2, 2024

Hey lutpiero,

I think that I can see a two mistakes in your code. Please try to format it correctly next time as it is very hard to read like this.

  1. You transform the message to lower case, but compare with an upper case "Hello". The condition is always false.

  2. I can't really see it in the short snippet here, but is wac really in the correct scope? If you want to use it in the listener, you have to create the connection globally.

I will add an echo example in the next couple of days, so if you can't get it to work you can check mine.

from go-whatsapp.

lutpiero avatar lutpiero commented on June 2, 2024

I've created an echo example, this example will echo the message if it contain @echo keyword.
But the problem is I often got error

panic: concurrent write to websocket connection

The code is like this:

package main

import (
	"encoding/gob"
	"fmt"
	"os"
	"strings"
	"time"

	"github.com/Baozisoftware/qrcode-terminal-go"
	"github.com/Rhymen/go-whatsapp"
)

type waHandler struct {
	wac *whatsapp.Conn
}

//HandleError needs to be implemented to be a valid WhatsApp handler
func (wh *waHandler) HandleError(err error) {
	fmt.Fprintf(os.Stderr, "error occoured: %v", err)
}

//Optional to be implemented. Implement HandleXXXMessage for the types you need.
func (wh *waHandler) HandleTextMessage(message whatsapp.TextMessage) {
	var err error
	if strings.Contains(strings.ToLower(message.Text), "@echo") && !message.Info.FromMe {
		msg := whatsapp.TextMessage{
			Info: whatsapp.MessageInfo{
				RemoteJid: message.Info.RemoteJid,
			},
			Text: message.Text,
		}

		err = wh.wac.Send(msg)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error sending message: %v", err)
		}		
	}
	fmt.Printf("%v %v\n\t%v\n", message.Info.Timestamp, message.Info.RemoteJid, message.Text)

}

//Example for media handling. Video, Audio, Document are also possible in the same way
func (wh *waHandler) HandleImageMessage(message whatsapp.ImageMessage) {
	data, err := message.Download()
	if err != nil {
		return
	}
	filename := fmt.Sprintf("%v/%v.%v", os.TempDir(), message.Info.Id, strings.Split(message.Type, "/")[1])
	file, err := os.Create(filename)
	defer file.Close()
	if err != nil {
		return
	}
	_, err = file.Write(data)
	if err != nil {
		return
	}
	fmt.Printf("%v %v\n\timage reveived, saved at:%v\n", message.Info.Timestamp, message.Info.RemoteJid, filename)
}

func main() {
	//create new WhatsApp connection
	wac, err := whatsapp.NewConn(5 * time.Second)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error creating connection: %v\n", err)
		return
	}

	//Add handler
	wac.AddHandler(&waHandler{wac})

	err = login(wac)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error logging in: %v\n", err)
		return
	}

	<-time.After(500 * time.Minute)
}

func login(wac *whatsapp.Conn) error {
	//load saved session
	session, err := readSession()
	if err == nil {
		//restore session
		session, err = wac.RestoreSession(session)
		if err != nil {
			return fmt.Errorf("restoring failed: %v\n", err)
		}
	} else {
		//no saved session -> regular login
		qr := make(chan string)
		go func() {
			terminal := qrcodeTerminal.New()
			terminal.Get(<-qr).Print()
		}()
		session, err = wac.Login(qr)
		if err != nil {
			return fmt.Errorf("error during login: %v\n", err)
		}
	}

	//save session
	err = writeSession(session)
	if err != nil {
		return fmt.Errorf("error saving session: %v\n", err)
	}
	return nil
}

func readSession() (whatsapp.Session, error) {
	session := whatsapp.Session{}
	file, err := os.Open(os.TempDir() + "/whatsappSession.gob")
	if err != nil {
		return session, err
	}
	defer file.Close()
	decoder := gob.NewDecoder(file)
	err = decoder.Decode(&session)
	if err != nil {
		return session, err
	}
	return session, nil
}

func writeSession(session whatsapp.Session) error {
	file, err := os.Create(os.TempDir() + "/whatsappSession.gob")
	if err != nil {
		return err
	}
	defer file.Close()
	encoder := gob.NewEncoder(file)
	err = encoder.Encode(session)
	if err != nil {
		return err
	}
	return nil
}

from go-whatsapp.

SchulteMK avatar SchulteMK commented on June 2, 2024

This happens propably due to the flood of messages received after connecting to whatsapp. We are currently creating a goroutine for every incoming message to not block the message queue. Maybe we should consider to remove this. For an easy and simple workaround you can try to add the handler a few seconds after logging into whatsapp.

I think we have to implement a queue for message sending so that no two messages get sent at the same time.

from go-whatsapp.

Rhymen avatar Rhymen commented on June 2, 2024

I think we have to implement a queue for message sending so that no two messages get sent at the same time.

This. It's not allowed to read / write from mutiple goroutines from / to the socket. We have to implement a "send pump", much like the read pump we already got. Look at the comments above the readPump and writePump in this example.

from go-whatsapp.

Rhymen avatar Rhymen commented on June 2, 2024

I added a slightly modified version of the echo example that @lutpiero provided to the examples folder.

from go-whatsapp.

lutpiero avatar lutpiero commented on June 2, 2024

Great I've tested the echo no more
panic: concurrent write to websocket connection

I'm closing the issue, thanks @Rhymen

from go-whatsapp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.