status-go/cmd/status-cli/serve.go

109 lines
2.9 KiB
Go
Raw Normal View History

package main
import (
"context"
"encoding/json"
"log"
"os"
"os/signal"
"syscall"
"github.com/status-im/status-go/protocol/common"
"github.com/status-im/status-go/protocol/protobuf"
msignal "github.com/status-im/status-go/signal"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
)
func serve(cCtx *cli.Context, useExistingAccount bool) error {
rawLogger, err := zap.NewDevelopment()
if err != nil {
log.Fatalf("Error initializing logger: %v", err)
}
logger = rawLogger.Sugar()
logger.Info("Running serve command, flags passed:")
for _, flag := range ServeFlags {
logger.Infof("-%s %v", flag.Names()[0], cCtx.Value(flag.Names()[0]))
}
name := cCtx.String(NameFlag)
port := cCtx.Int(PortFlag)
apiModules := cCtx.String(APIModulesFlag)
telemetryUrl := cCtx.String(TelemetryServerURLFlag)
interactive := cCtx.Bool(InteractiveFlag)
dest := cCtx.String(AddFlag)
keyUID := cCtx.String(KeyUIDFlag)
cli, err := start(name, port, apiModules, telemetryUrl, useExistingAccount, keyUID)
if err != nil {
return err
}
defer cli.stop()
// Using the mobile signal handler to listen for received messages
// because if we call messenger.RetrieveAll() from different routines we will miss messages in one of them
// and the retrieve messages loop is started when starting a node, so we needed a different appproach,
// alternatively we could have implemented another notification mechanism in the messenger, but this signal is already in place
msignal.SetMobileSignalHandler(msignal.MobileSignalHandler(func(s []byte) {
var ev MobileSignalEvent
if err := json.Unmarshal(s, &ev); err != nil {
logger.Error("unmarshaling signal event", zap.Error(err), zap.String("event", string(s)))
return
}
if ev.Type == msignal.EventNewMessages {
for _, message := range ev.Event.Messages {
logger.Infof("message received: %v (ID=%v)", message.Text, message.ID)
// if request contact, accept it
if message.ContentType == protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_SENT {
if err := cli.sendContactRequestAcceptance(cCtx.Context, message.ID); err != nil {
logger.Errorf("accepting contact request: %v", err)
return
}
}
}
}
}))
// Send contact request
if dest != "" {
err := cli.sendContactRequest(cCtx.Context, dest)
if err != nil {
return err
}
}
// nightly testrunner looks for this log to consider node as started
logger.Info("retrieve messages...")
if interactive {
ctx, cancel := context.WithCancel(cCtx.Context)
go func() {
waitForSigExit()
cancel()
}()
interactiveSendMessageLoop(ctx, cli)
} else {
waitForSigExit()
}
logger.Info("Exiting")
return nil
}
type MobileSignalEvent struct {
Type string `json:"type"`
Event struct {
Messages []*common.Message `json:"messages"`
} `json:"event"`
}
func waitForSigExit() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
}