Skip to content

itzngga/Roxy

Repository files navigation

GitHub Repo stars GitHub forks GitHub watchers GitHub code size in bytes

Roxy

Command Handler Abstraction for whatsmeow

Installation

go get github.com/itzngga/Roxy
  • You need ffmpeg binary for generate image/video thumbnail

Get Started

package main

import (
	_ "github.com/itzngga/Roxy/examples/cmd"
	"log"

	"github.com/itzngga/Roxy"
	"github.com/itzngga/Roxy/options"

	"os"
	"os/signal"
	"syscall"
)

func main() {
	app, err := roxy.NewRoxyBase(options.NewDefaultOptions())
	if err != nil {
		log.Fatal(err)
	}

	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	app.Shutdown()
}

Config

default

app, err := roxy.NewRoxyBase(options.NewDefaultOptions())
if err != nil {
    log.Fatal(err)
}

custom

const (
	SCAN_QR   LoginOptions = 0
	PAIR_CODE LoginOptions = 1
)

type Options struct {
	// HostNumber will use the first available device when null
	HostNumber string

	// StoreMode can be "postgres" or "sqlite"
	StoreMode string

	// LogLevel: "INFO", "ERROR", "WARN", "DEBUG"
	LogLevel string

	// This PostgresDsn Must add when StoreMode equal to "postgres"
	PostgresDsn *PostgresDSN

	// This SqliteFile Generate "ROXY.DB" when it null
	SqliteFile string

	// WithSqlDB wrap with sql.DB interface
	WithSqlDB *sql.DB

	WithCommandLog              bool
	CommandResponseCacheTimeout time.Duration
	SendMessageTimeout          time.Duration

	// OSInfo system name in client
	OSInfo string

	// LoginOptions constant of ScanQR or PairCode
	LoginOptions LoginOptions

	// HistorySync is used to synchronize message history
	HistorySync bool
	// AutoRejectCall allow to auto reject incoming calls
	AutoRejectCall bool

	// Bot General Settings

	// AllowFromPrivate allow messages from private
	AllowFromPrivate bool
	// AllowFromGroup allow message from groups
	AllowFromGroup bool
	// OnlyFromSelf allow only from self messages
	OnlyFromSelf bool
	// CommandSuggestion allow command suggestion
	CommandSuggestion bool
	// DebugMessage debug incoming message to console
	DebugMessage bool
}

PostgresSQL

from env

package main

import (
	roxy "github.com/itzngga/Roxy"
	_ "github.com/itzngga/Roxy/examples/cmd"
	"github.com/itzngga/Roxy/options"
	"github.com/joho/godotenv"

	"log"

	"os"
	"os/signal"
	"syscall"
)

func init() {
	err := godotenv.Load()
	if err != nil {
		panic(err)
	}
}

func main() {
	// Required ENV
	// PG_HOST : postgresql host
	// PG_PORT : postgresql port
	// PG_USERNAME : postgresql username
	// PG_PASSWORD : postgresql password
	// PG_DATABASE : postgresql database

	opt := options.NewDefaultOptions()
	opt.StoreMode = "postgres"
	opt.PostgresDsn = options.NewPostgresDSN().FromEnv()

	app, err := roxy.NewRoxyBase(opt)
	if err != nil {
		log.Fatal(err)
	}

	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	app.Shutdown()
}

default parser

package main

import (
	roxy "github.com/itzngga/Roxy"
	_ "github.com/itzngga/Roxy/examples/cmd"
	"github.com/itzngga/Roxy/options"

	"log"

	"os"
	"os/signal"
	"syscall"
)

func main() {
	pg := options.NewPostgresDSN()
	pg.SetHost("localhost")
	pg.SetPort("4321")
	pg.SetUsername("postgres")
	pg.SetPassword("root123")
	pg.SetDatabase("roxy")

	opt := options.NewDefaultOptions()
	opt.StoreMode = "postgres"
	opt.PostgresDsn = pg

	app, err := roxy.NewRoxyBase(opt)
	if err != nil {
		log.Fatal(err)
	}

	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	app.Shutdown()
}

Sqlite

package main

import (
	roxy "github.com/itzngga/Roxy"
	_ "github.com/itzngga/Roxy/examples/cmd"
	"github.com/itzngga/Roxy/options"

	"log"
	"os"
	"os/signal"
	"syscall"
)

func main() {
	opt := options.NewDefaultOptions()
	app, err := roxy.NewRoxyBase(opt)
	if err != nil {
		log.Fatal(err)
	}

	c := make(chan os.Signal)
	signal.Notify(c, os.Interrupt, syscall.SIGTERM)
	<-c
	app.Shutdown()
}

Add a Command

create a simple command with:

command/hello_world.go

package cmd

import (
	"fmt"
	waProto "github.com/go-whatsapp/whatsmeow/binary/proto"
	"github.com/itzngga/Roxy"
	"github.com/itzngga/Roxy/context"
	"time"
)

func init() {
	roxy.Commands.Add(speed)
}

var speed = &roxy.Command{
	Name:        "speed",
	Description: "Testing speed",
	RunFunc: func(ctx *context.Ctx) *waProto.Message {
		t := time.Now()
		ctx.SendReplyMessage("wait...")
		return ctx.GenerateReplyMessage(fmt.Sprintf("Duration: %f seconds", time.Now().Sub(t).Seconds()))
	},
}

Create Question State

example with media question state

package media

import (
	"github.com/itzngga/Leficious/src/cmd/constant"
	"github.com/itzngga/Roxy"
	"github.com/itzngga/Roxy/context"
	"github.com/itzngga/Roxy/util/cli"
	waProto "github.com/go-whatsapp/whatsmeow/binary/proto"
	"log"
)

func init() {
	roxy.Commands.Add(ocr)
}

var ocr = &roxy.Command{
	Name:        "ocr",
	Category:    "media",
	Description: "Scan text on images",
	context: func(ctx *context.Ctx) *waProto.Message {
		var captured *waProto.Message
		ctx.NewUserQuestion().
			CaptureMediaQuestion("Please send/reply a media message", &captured).
			Exec()

		result, err := ctx.Download(captured, false)
		if err != nil {
			log.Fatal(err)
		}
		res := cli.ExecPipeline("tesseract", result, "stdin", "stdout", "-l", "ind", "--oem", "1", "--psm", "3", "-c", "preserve_interword_spaces=1")

		return ctx.GenerateReplyMessage(string(res))
	},
}

Example

currently available example project in Lara

Documentation

DOC

License

GNU

Contribute

Pull Request are pleased to

About

Command Handler Abstraction for Whatsapp Bot

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages