Compare commits

...

9 Commits

Author SHA1 Message Date
normen
e5ef667909 show help and set no receiver on contact root 2020-11-24 22:29:50 +01:00
normen
c39479f12b fix notifications for own messages 2020-11-24 22:28:24 +01:00
normen
f1109f6465 add /colorlist command 2020-11-24 21:05:12 +01:00
normen
127883701d fix version snafu in 0.9.1 release 2020-11-24 20:52:07 +01:00
normen
5cacc3c5ea bump version 2020-11-24 20:46:17 +01:00
normen
65957ff732 use color_negative for all error messages 2020-11-24 20:38:04 +01:00
normen
7a096dbc94 allow configuring command for image to text conversion 2020-11-24 20:25:21 +01:00
normen
a7977959b5 help info update 2020-11-24 19:19:51 +01:00
normen
ea92d56426 allow sending image, video and audio messages
files have to be right format to be recognized by WhatsApp
2020-11-24 19:16:37 +01:00
3 changed files with 125 additions and 28 deletions

View File

@@ -25,6 +25,7 @@ type General struct {
DownloadPath string
PreviewPath string
CmdPrefix string
ShowCommand string
EnableNotifications bool
NotificationTimeout int64
}
@@ -70,6 +71,7 @@ var Config = IniFile{
DownloadPath: GetHomeDir() + "Downloads",
PreviewPath: GetHomeDir() + "Downloads",
CmdPrefix: "/",
ShowCommand: "jp2a --color",
EnableNotifications: false,
NotificationTimeout: 60,
},

30
main.go
View File

@@ -4,6 +4,7 @@ import (
"bufio"
"fmt"
"io"
"os"
"os/exec"
"strings"
@@ -15,7 +16,7 @@ import (
"gitlab.com/tslocum/cbind"
)
var VERSION string = "v0.8.10"
var VERSION string = "v0.9.3"
var sndTxt string = ""
var currentReceiver string = ""
@@ -143,6 +144,7 @@ func MakeTree() *tview.TreeView {
treeView.SetChangedFunc(func(node *tview.TreeNode) {
reference := node.GetReference()
if reference == nil {
SetDisplayedContact("")
return // Selecting the root node does nothing.
}
children := node.GetChildren()
@@ -356,9 +358,9 @@ func PrintHelp() {
fmt.Fprintln(textView, "")
fmt.Fprintln(textView, "[-::-]Message panel focused:[-::-]")
fmt.Fprintln(textView, "[::b] Up/Down[::-] = select message")
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageDownload, "[::-] = download attachment -> ", config.Config.General.DownloadPath)
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageOpen, "[::-] = download & open attachment -> ", config.Config.General.PreviewPath)
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageShow, "[::-] = download & show image using jp2a -> ", config.Config.General.PreviewPath)
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageDownload, "[::-] = download attachment to", config.Config.General.DownloadPath)
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageOpen, "[::-] = download & open attachment in", config.Config.General.PreviewPath)
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageShow, "[::-] = download & show image using"+config.Config.General.ShowCommand, config.Config.General.PreviewPath+string(os.PathSeparator)+"filename.file")
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageUrl, "[::-] = find URL in message and open it")
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageRevoke, "[::-] = revoke message")
fmt.Fprintln(textView, "[::b]", config.Config.Keymap.MessageInfo, "[::-] = info about message")
@@ -367,7 +369,8 @@ func PrintHelp() {
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"backlog [::-]or[::b]", config.Config.Keymap.CommandBacklog, "[::-] = load next 10 older messages for current chat")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"connect [::-]or[::b]", config.Config.Keymap.CommandConnect, "[::-] = (re)connect in case the connection dropped")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"leave[::-] = leave group")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"upload[::-] /path/to/file = upload file to current chat")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"upload[::-] /path/to/file = upload any file as document to current chat")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"sendimage[::-] /path/to/file = send image as image message to current chat (also sendvideo/audio")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"disconnect[::-] = close the connection")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"logout[::-] = remove login data from computer (stays connected until app closes)")
fmt.Fprintln(textView, "[::b] "+cmdPrefix+"help [::-]or[::b]", config.Config.Keymap.CommandHelp, "[::-] = show this help")
@@ -458,7 +461,7 @@ func PrintError(err error) {
if err == nil {
return
}
fmt.Fprintln(textView, "[red]", err.Error(), "[-]")
fmt.Fprintln(textView, "["+config.Config.Colors.Negative+"]", err.Error(), "[-]")
}
// prints an error to the TextView
@@ -466,13 +469,21 @@ func PrintErrorMsg(text string, err error) {
if err == nil {
return
}
fmt.Fprintln(textView, "[red]", text, err.Error(), "[-]")
fmt.Fprintln(textView, "["+config.Config.Colors.Negative+"]", text, err.Error(), "[-]")
}
// prints an image attachment to the TextView (by message id)
func PrintImage(path string) {
var err error
cmd := exec.Command("jp2a", "--color", path)
cmdParts := strings.Split(config.Config.General.ShowCommand, " ")
cmdParts = append(cmdParts, path)
var cmd *exec.Cmd
size := len(cmdParts)
if size > 1 {
cmd = exec.Command(cmdParts[0], cmdParts[1:]...)
} else if size > 0 {
cmd = exec.Command(cmdParts[0])
}
var stdout io.ReadCloser
if stdout, err = cmd.StdoutPipe(); err == nil {
if err = cmd.Start(); err == nil {
@@ -538,6 +549,9 @@ func (u UiHandler) NewScreen(screen string, ids []string) {
textView.Clear()
textView.SetText(screen)
curRegions = ids
if screen == "" {
PrintHelp()
}
})
}

View File

@@ -12,6 +12,7 @@ import (
"time"
"github.com/gabriel-vasile/mimetype"
"github.com/gdamore/tcell/v2"
"github.com/gen2brain/beeep"
"github.com/rivo/tview"
"mvdan.cc/xurls/v2"
@@ -115,7 +116,7 @@ func (sm *SessionManager) StartManager() error {
sm.uiHandler.NewScreen(screen, ids)
}
// notify if contact is in focus and we didn't send a message recently
if config.Config.General.EnableNotifications {
if config.Config.General.EnableNotifications && !msg.Info.FromMe {
if int64(msg.Info.Timestamp) > time.Now().Unix()-30 {
if int64(msg.Info.Timestamp) > sm.lastSent.Unix()+config.Config.General.NotificationTimeout {
err := beeep.Notify(sm.GetIdShort(msg.Info.RemoteJid), msg.Text, "")
@@ -126,7 +127,7 @@ func (sm *SessionManager) StartManager() error {
}
}
} else {
if config.Config.General.EnableNotifications {
if config.Config.General.EnableNotifications && !msg.Info.FromMe {
// notify if message is younger than 30 sec and not in focus
if int64(msg.Info.Timestamp) > time.Now().Unix()-30 {
err := beeep.Notify(sm.GetIdShort(msg.Info.RemoteJid), msg.Text, "")
@@ -252,9 +253,8 @@ func (sm *SessionManager) execCommand(command Command) {
cmd := command.Name
switch cmd {
default:
sm.uiHandler.PrintText("[red]Unknown command: [-]" + cmd)
sm.uiHandler.PrintText("[" + config.Config.Colors.Negative + "]Unknown command: [-]" + cmd)
case "backlog":
//command
if sm.currentReceiver == "" {
return
}
@@ -265,8 +265,6 @@ func (sm *SessionManager) execCommand(command Command) {
go sm.getConnection().LoadChatMessages(sm.currentReceiver, count, firstMsg.Info.Id, firstMsg.Info.FromMe, false, sm)
}
}
//FullChatHistory(currentReceiver, 20, 100000, handler)
//messages.GetConnection().LoadFullChatHistory(currentReceiver, 20, 100000, handler)
case "login":
sm.uiHandler.PrintError(sm.login())
case "connect":
@@ -281,19 +279,19 @@ func (sm *SessionManager) execCommand(command Command) {
text := strings.Join(textParams, " ")
sm.sendText(command.Params[0], text)
} else {
sm.uiHandler.PrintText("[red]Usage:[-] send [user-id[] [message text[]")
sm.printCommandUsage("send", "[user-id[] [message text[]")
}
case "select":
if checkParam(command.Params, 1) {
sm.setCurrentReceiver(command.Params[0])
} else {
sm.uiHandler.PrintText("[red]Usage:[-] select [user-id[]")
sm.printCommandUsage("select", "[user-id[]")
}
case "info":
if checkParam(command.Params, 1) {
sm.uiHandler.PrintText(sm.db.GetMessageInfo(command.Params[0]))
} else {
sm.uiHandler.PrintText("[red]Usage:[-] info [message-id[]")
sm.printCommandUsage("info", "[message-id[]")
}
case "download":
if checkParam(command.Params, 1) {
@@ -303,7 +301,7 @@ func (sm *SessionManager) execCommand(command Command) {
sm.uiHandler.PrintText("[::d] -> " + path + "[::-]")
}
} else {
sm.uiHandler.PrintText("[red]Usage:[-] download [message-id[]")
sm.printCommandUsage("download", "[message-id[]")
}
case "open":
if checkParam(command.Params, 1) {
@@ -313,7 +311,7 @@ func (sm *SessionManager) execCommand(command Command) {
sm.uiHandler.PrintError(err)
}
} else {
sm.uiHandler.PrintText("[red]Usage:[-] open [message-id[]")
sm.printCommandUsage("open", "[message-id[]")
}
case "show":
if checkParam(command.Params, 1) {
@@ -323,7 +321,7 @@ func (sm *SessionManager) execCommand(command Command) {
sm.uiHandler.PrintError(err)
}
} else {
sm.uiHandler.PrintText("[red]Usage:[-] show [message-id[]")
sm.printCommandUsage("show", "[message-id[]")
}
case "url":
if checkParam(command.Params, 1) {
@@ -335,7 +333,7 @@ func (sm *SessionManager) execCommand(command Command) {
}
}
} else {
sm.uiHandler.PrintText("[red]Usage:[-] url [message-id[]")
sm.printCommandUsage("url", "[message-id[]")
}
case "upload":
if sm.currentReceiver == "" {
@@ -355,14 +353,86 @@ func (sm *SessionManager) execCommand(command Command) {
}
wac := sm.getConnection()
sm.lastSent = time.Now()
_, err := wac.Send(msg)
if err != nil {
sm.uiHandler.PrintError(err)
}
_, err = wac.Send(msg)
}
}
} else {
sm.uiHandler.PrintText("[red]Usage:[-] upload [/path/to/file[]")
sm.printCommandUsage("upload", "/path/to/file")
}
sm.uiHandler.PrintError(err)
case "sendimage":
if sm.currentReceiver == "" {
return
}
var err error
if checkParam(command.Params, 1) {
path := strings.Join(command.Params, " ")
if mime, err := mimetype.DetectFile(path); err == nil {
if file, err := os.Open(path); err == nil {
msg := whatsapp.ImageMessage{
Info: whatsapp.MessageInfo{
RemoteJid: sm.currentReceiver,
},
Type: mime.String(),
Content: file,
}
wac := sm.getConnection()
sm.lastSent = time.Now()
_, err = wac.Send(msg)
}
}
} else {
sm.printCommandUsage("sendimage", "/path/to/file")
}
sm.uiHandler.PrintError(err)
case "sendvideo":
if sm.currentReceiver == "" {
return
}
var err error
if checkParam(command.Params, 1) {
path := strings.Join(command.Params, " ")
if mime, err := mimetype.DetectFile(path); err == nil {
if file, err := os.Open(path); err == nil {
msg := whatsapp.VideoMessage{
Info: whatsapp.MessageInfo{
RemoteJid: sm.currentReceiver,
},
Type: mime.String(),
Content: file,
}
wac := sm.getConnection()
sm.lastSent = time.Now()
_, err = wac.Send(msg)
}
}
} else {
sm.printCommandUsage("sendvideo", "/path/to/file")
}
sm.uiHandler.PrintError(err)
case "sendaudio":
if sm.currentReceiver == "" {
return
}
var err error
if checkParam(command.Params, 1) {
path := strings.Join(command.Params, " ")
if mime, err := mimetype.DetectFile(path); err == nil {
if file, err := os.Open(path); err == nil {
msg := whatsapp.AudioMessage{
Info: whatsapp.MessageInfo{
RemoteJid: sm.currentReceiver,
},
Type: mime.String(),
Content: file,
}
wac := sm.getConnection()
sm.lastSent = time.Now()
_, err = wac.Send(msg)
}
}
} else {
sm.printCommandUsage("sendaudio", "/path/to/file")
}
sm.uiHandler.PrintError(err)
case "revoke":
@@ -392,7 +462,7 @@ func (sm *SessionManager) execCommand(command Command) {
}
sm.uiHandler.PrintError(err)
} else {
sm.uiHandler.PrintText("[red]Usage:[-] revoke [message-id[]")
sm.printCommandUsage("revoke", "[message-id[]")
}
case "leave":
groupId := sm.currentReceiver
@@ -406,9 +476,20 @@ func (sm *SessionManager) execCommand(command Command) {
sm.uiHandler.PrintText("left group " + groupId)
}
sm.uiHandler.PrintError(err)
case "colorlist":
out := ""
for idx, _ := range tcell.ColorNames {
out = out + "[" + idx + "]" + idx + "[-]\n"
}
sm.uiHandler.PrintText(out)
}
}
// helper for built-in command help
func (sm *SessionManager) printCommandUsage(command string, usage string) {
sm.uiHandler.PrintText("[" + config.Config.Colors.Negative + "]Usage:[-] " + command + " " + usage)
}
// check if parameters for command are okay
func checkParam(arr []string, length int) bool {
if arr == nil || len(arr) < length {
@@ -600,7 +681,7 @@ func (sm *SessionManager) sendText(wid string, text string) {
// HandleError implements the error handler interface for go-whatsapp
func (sm *SessionManager) HandleError(err error) {
sm.uiHandler.PrintText("[red]go-whatsapp reported an error:[-]")
sm.uiHandler.PrintText("[" + config.Config.Colors.Negative + "]go-whatsapp reported an error:[-]")
sm.uiHandler.PrintError(err)
statusMsg := StatusMsg{false, err}
sm.StatusChannel <- statusMsg