Browse Source

Merge branch 'main' into main

Signed-off-by: TheProcedural <contact@theprocedural.com>
pull/305/head
TheProcedural 9 months ago
committed by GitHub
parent
commit
b02c56c531
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 3
      .gitignore
  2. 28
      src/cmd/root.go
  3. 2
      src/config/settings.go
  4. 18
      src/infrastructure/whatsapp/init.go
  5. 29
      src/infrastructure/whatsapp/webhook.go
  6. 16
      src/views/components/GroupList.js

3
.gitignore

@ -8,4 +8,5 @@ main.exe
*.jpe
src/pkged.go
storages
.env
.env
bin

28
src/cmd/root.go

@ -3,6 +3,7 @@ package cmd
import (
"context"
"embed"
"fmt"
"os"
"strings"
"time"
@ -68,45 +69,46 @@ func init() {
// initEnvConfig loads configuration from environment variables
func initEnvConfig() {
fmt.Println(viper.AllSettings())
// Application settings
if envPort := viper.GetString("APP_PORT"); envPort != "" {
if envPort := viper.GetString("app_port"); envPort != "" {
config.AppPort = envPort
}
if envDebug := viper.GetBool("APP_DEBUG"); envDebug {
if envDebug := viper.GetBool("app_debug"); envDebug {
config.AppDebug = envDebug
}
if envOs := viper.GetString("APP_OS"); envOs != "" {
if envOs := viper.GetString("app_os"); envOs != "" {
config.AppOs = envOs
}
if envBasicAuth := viper.GetString("APP_BASIC_AUTH"); envBasicAuth != "" {
if envBasicAuth := viper.GetString("app_basic_auth"); envBasicAuth != "" {
credential := strings.Split(envBasicAuth, ",")
config.AppBasicAuthCredential = credential
}
if envChatFlushInterval := viper.GetInt("APP_CHAT_FLUSH_INTERVAL"); envChatFlushInterval > 0 {
if envChatFlushInterval := viper.GetInt("app_chat_flush_interval"); envChatFlushInterval > 0 {
config.AppChatFlushIntervalDays = envChatFlushInterval
}
// Database settings
if envDBURI := viper.GetString("DB_URI"); envDBURI != "" {
if envDBURI := viper.GetString("db_uri"); envDBURI != "" {
config.DBURI = envDBURI
}
// WhatsApp settings
if envAutoReply := viper.GetString("WHATSAPP_AUTO_REPLY"); envAutoReply != "" {
if envAutoReply := viper.GetString("whatsapp_auto_reply"); envAutoReply != "" {
config.WhatsappAutoReplyMessage = envAutoReply
}
if envWebhook := viper.GetString("WHATSAPP_WEBHOOK"); envWebhook != "" {
if envWebhook := viper.GetString("whatsapp_webhook"); envWebhook != "" {
webhook := strings.Split(envWebhook, ",")
config.WhatsappWebhook = webhook
}
if envWebhookSecret := viper.GetString("WHATSAPP_WEBHOOK_SECRET"); envWebhookSecret != "" {
if envWebhookSecret := viper.GetString("whatsapp_webhook_secret"); envWebhookSecret != "" {
config.WhatsappWebhookSecret = envWebhookSecret
}
if envAccountValidation := viper.GetBool("WHATSAPP_ACCOUNT_VALIDATION"); envAccountValidation {
config.WhatsappAccountValidation = envAccountValidation
if viper.IsSet("whatsapp_account_validation") {
config.WhatsappAccountValidation = viper.GetBool("whatsapp_account_validation")
}
if envChatStorage := viper.GetBool("WHATSAPP_CHAT_STORAGE"); !envChatStorage {
config.WhatsappChatStorage = envChatStorage
if viper.IsSet("whatsapp_chat_storage") {
config.WhatsappChatStorage = viper.GetBool("whatsapp_chat_storage")
}
if envCallWebhookOnMessageToSelf := viper.GetBool("CALL_WEBHOOK_ON_MESSAGE_TO_SELF"); envCallWebhookOnMessageToSelf {
config.WhatsappCallWebhookOnMessageToSelf = envCallWebhookOnMessageToSelf

2
src/config/settings.go

@ -5,7 +5,7 @@ import (
)
var (
AppVersion = "v6.1.0"
AppVersion = "v6.1.1"
AppPort = "3000"
AppDebug = false
AppOs = "AldinoKemal"

18
src/infrastructure/whatsapp/init.go

@ -247,14 +247,21 @@ func handleAutoReply(evt *events.Message) {
}
func handleWebhookForward(ctx context.Context, evt *events.Message) {
if protocolMessage := evt.Message.GetProtocolMessage(); protocolMessage != nil {
protocolType := protocolMessage.GetType().String()
if protocolType == "EPHEMERAL_SYNC_RESPONSE" {
log.Debugf("Skipping webhook for EPHEMERAL_SYNC_RESPONSE message")
return
}
}
shouldCallWebhook := len(config.WhatsappWebhook) > 0 &&
!strings.Contains(evt.Info.SourceString(), "broadcast")
// Check if message is from myself and whether we should call webhook for self messages
if isFromMySelf(evt.Info.SourceString()) && !config.WhatsappCallWebhookOnMessageToSelf {
shouldCallWebhook = false
}
if shouldCallWebhook {
go func(evt *events.Message) {
if err := forwardToWebhook(ctx, evt); err != nil {
@ -265,9 +272,10 @@ func handleWebhookForward(ctx context.Context, evt *events.Message) {
}
func handleReceipt(_ context.Context, evt *events.Receipt) {
if evt.Type == types.ReceiptTypeRead || evt.Type == types.ReceiptTypeReadSelf {
switch evt.Type {
case types.ReceiptTypeRead, types.ReceiptTypeReadSelf:
log.Infof("%v was read by %s at %s", evt.MessageIDs, evt.SourceString(), evt.Timestamp)
} else if evt.Type == types.ReceiptTypeDelivered {
case types.ReceiptTypeDelivered:
log.Infof("%s was delivered to %s at %s", evt.MessageIDs[0], evt.SourceString(), evt.Timestamp)
}
}

29
src/infrastructure/whatsapp/webhook.go

@ -5,12 +5,13 @@ import (
"context"
"encoding/json"
"fmt"
"go.mau.fi/whatsmeow/types"
"net/http"
"regexp"
"strings"
"time"
"go.mau.fi/whatsmeow/types"
"github.com/aldinokemal/go-whatsapp-web-multidevice/config"
pkgError "github.com/aldinokemal/go-whatsapp-web-multidevice/pkg/error"
"github.com/sirupsen/logrus"
@ -109,6 +110,32 @@ func createPayload(ctx context.Context, evt *events.Message) (map[string]interfa
body["timestamp"] = timestamp
}
// Handle protocol messages (revoke, etc.)
if protocolMessage := evt.Message.GetProtocolMessage(); protocolMessage != nil {
protocolType := protocolMessage.GetType().String()
switch protocolType {
case "REVOKE":
body["action"] = "message_revoked"
if key := protocolMessage.GetKey(); key != nil {
body["revoked_message_id"] = key.GetID()
body["revoked_from_me"] = key.GetFromMe()
if key.GetRemoteJID() != "" {
body["revoked_chat"] = key.GetRemoteJID()
}
}
case "MESSAGE_EDIT":
body["action"] = "message_edited"
if editedMessage := protocolMessage.GetEditedMessage(); editedMessage != nil {
if editedText := editedMessage.GetExtendedTextMessage(); editedText != nil {
body["edited_text"] = editedText.GetText()
} else if editedConv := editedMessage.GetConversation(); editedConv != "" {
body["edited_text"] = editedConv
}
}
}
}
if audioMedia := evt.Message.GetAudioMessage(); audioMedia != nil {
path, err := ExtractMedia(ctx, config.PathMedia, audioMedia)
if err != nil {

16
src/views/components/GroupList.js

@ -80,9 +80,17 @@ export default {
if (!value) return ''
return moment(value).format('LLL');
},
isAdmin(ownerJID) {
const owner = ownerJID.split('@')[0];
return owner === this.currentUserId;
isAdmin(group) {
// Check if current user is the owner
const owner = group.OwnerJID.split('@')[0];
if (owner === this.currentUserId) {
return true;
}
// Check if current user is an admin in participants
const currentUserJID = `${this.currentUserId}@s.whatsapp.net`;
const participant = group.Participants.find(p => p.JID === currentUserJID);
return participant && participant.IsAdmin;
},
async handleSeeRequestedMember(group_id) {
this.selectedGroupId = group_id;
@ -180,7 +188,7 @@ export default {
<td>{{ formatDate(g.GroupCreated) }}</td>
<td>
<div style="display: flex; gap: 8px; align-items: center;">
<button v-if="isAdmin(g.OwnerJID)" class="ui green tiny button" @click="handleSeeRequestedMember(g.JID)">Requested Members</button>
<button v-if="isAdmin(g)" class="ui green tiny button" @click="handleSeeRequestedMember(g.JID)">Requested Members</button>
<button class="ui red tiny button" @click="handleLeaveGroup(g.JID)">Leave</button>
</div>
</td>

Loading…
Cancel
Save