|
@@ -5,6 +5,7 @@ import (
|
|
|
"encoding/json"
|
|
"encoding/json"
|
|
|
"fmt"
|
|
"fmt"
|
|
|
"os"
|
|
"os"
|
|
|
|
|
+ "strings"
|
|
|
|
|
|
|
|
"gogs.dmsc.dev/arp/arp_cli/client"
|
|
"gogs.dmsc.dev/arp/arp_cli/client"
|
|
|
"gogs.dmsc.dev/arp/arp_cli/config"
|
|
"gogs.dmsc.dev/arp/arp_cli/config"
|
|
@@ -19,7 +20,7 @@ func MessageCommand() *cli.Command {
|
|
|
return &cli.Command{
|
|
return &cli.Command{
|
|
|
Name: "message",
|
|
Name: "message",
|
|
|
Usage: "Manage messages",
|
|
Usage: "Manage messages",
|
|
|
- Description: `Manage ARP messages. Messages are sent in channels between users/agents.
|
|
|
|
|
|
|
+ Description: `Manage ARP messages. Messages are sent between users/agents.
|
|
|
|
|
|
|
|
Use this command to create, list, update, and delete messages. You can also watch for real-time message updates.`,
|
|
Use this command to create, list, update, and delete messages. You can also watch for real-time message updates.`,
|
|
|
Commands: []*cli.Command{
|
|
Commands: []*cli.Command{
|
|
@@ -59,15 +60,10 @@ Use this command to create, list, update, and delete messages. You can also watc
|
|
|
Usage: "Create a new message",
|
|
Usage: "Create a new message",
|
|
|
Action: messageCreate,
|
|
Action: messageCreate,
|
|
|
Flags: []cli.Flag{
|
|
Flags: []cli.Flag{
|
|
|
- &cli.StringFlag{
|
|
|
|
|
- Name: "conversation",
|
|
|
|
|
- Aliases: []string{"c"},
|
|
|
|
|
- Usage: "Conversation/Channel ID",
|
|
|
|
|
- },
|
|
|
|
|
- &cli.StringFlag{
|
|
|
|
|
- Name: "sender",
|
|
|
|
|
- Aliases: []string{"s"},
|
|
|
|
|
- Usage: "Sender user ID",
|
|
|
|
|
|
|
+ &cli.StringSliceFlag{
|
|
|
|
|
+ Name: "receivers",
|
|
|
|
|
+ Aliases: []string{"r"},
|
|
|
|
|
+ Usage: "Receiver user IDs (comma-separated or multiple flags)",
|
|
|
},
|
|
},
|
|
|
&cli.StringFlag{
|
|
&cli.StringFlag{
|
|
|
Name: "content",
|
|
Name: "content",
|
|
@@ -92,6 +88,11 @@ Use this command to create, list, update, and delete messages. You can also watc
|
|
|
Aliases: []string{"c"},
|
|
Aliases: []string{"c"},
|
|
|
Usage: "Message content",
|
|
Usage: "Message content",
|
|
|
},
|
|
},
|
|
|
|
|
+ &cli.StringSliceFlag{
|
|
|
|
|
+ Name: "receivers",
|
|
|
|
|
+ Aliases: []string{"r"},
|
|
|
|
|
+ Usage: "Receiver user IDs (comma-separated or multiple flags)",
|
|
|
|
|
+ },
|
|
|
},
|
|
},
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
@@ -122,14 +123,14 @@ Use this command to create, list, update, and delete messages. You can also watc
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
type Message struct {
|
|
type Message struct {
|
|
|
- ID string `json:"id"`
|
|
|
|
|
- ConversationID string `json:"conversationId"`
|
|
|
|
|
- SenderID string `json:"senderId"`
|
|
|
|
|
- Sender *User `json:"sender"`
|
|
|
|
|
- Content string `json:"content"`
|
|
|
|
|
- SentAt string `json:"sentAt"`
|
|
|
|
|
- CreatedAt string `json:"createdAt"`
|
|
|
|
|
- UpdatedAt string `json:"updatedAt"`
|
|
|
|
|
|
|
+ ID string `json:"id"`
|
|
|
|
|
+ SenderID string `json:"senderId"`
|
|
|
|
|
+ Sender *User `json:"sender"`
|
|
|
|
|
+ Content string `json:"content"`
|
|
|
|
|
+ SentAt string `json:"sentAt"`
|
|
|
|
|
+ Receivers []string `json:"receivers"`
|
|
|
|
|
+ CreatedAt string `json:"createdAt"`
|
|
|
|
|
+ UpdatedAt string `json:"updatedAt"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func messageList(ctx context.Context, cmd *cli.Command) error {
|
|
func messageList(ctx context.Context, cmd *cli.Command) error {
|
|
@@ -144,7 +145,7 @@ func messageList(ctx context.Context, cmd *cli.Command) error {
|
|
|
c := client.New(cfg.ServerURL)
|
|
c := client.New(cfg.ServerURL)
|
|
|
c.SetToken(cfg.Token)
|
|
c.SetToken(cfg.Token)
|
|
|
|
|
|
|
|
- query := "query Messages { messages { id conversationId sender { id email } content sentAt createdAt } }"
|
|
|
|
|
|
|
+ query := "query Messages { messages { id sender { id email } content sentAt receivers createdAt } }"
|
|
|
|
|
|
|
|
resp, err := c.Query(query, nil)
|
|
resp, err := c.Query(query, nil)
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -170,8 +171,7 @@ func messageList(ctx context.Context, cmd *cli.Command) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
table := tablewriter.NewWriter(os.Stdout)
|
|
table := tablewriter.NewWriter(os.Stdout)
|
|
|
- table.Header([]string{"ID", "Conversation", "Sender", "Content", "Sent At"})
|
|
|
|
|
-
|
|
|
|
|
|
|
+ table.Header([]string{"ID", "Sender", "Content", "Receivers", "Sent At"})
|
|
|
|
|
|
|
|
for _, m := range result.Messages {
|
|
for _, m := range result.Messages {
|
|
|
sender := ""
|
|
sender := ""
|
|
@@ -182,7 +182,8 @@ func messageList(ctx context.Context, cmd *cli.Command) error {
|
|
|
if len(content) > 50 {
|
|
if len(content) > 50 {
|
|
|
content = content[:47] + "..."
|
|
content = content[:47] + "..."
|
|
|
}
|
|
}
|
|
|
- table.Append([]string{m.ID, m.ConversationID, sender, content, m.SentAt})
|
|
|
|
|
|
|
+ receivers := strings.Join(m.Receivers, ", ")
|
|
|
|
|
+ table.Append([]string{m.ID, sender, content, receivers, m.SentAt})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
table.Render()
|
|
table.Render()
|
|
@@ -202,7 +203,7 @@ func messageGet(ctx context.Context, cmd *cli.Command) error {
|
|
|
c.SetToken(cfg.Token)
|
|
c.SetToken(cfg.Token)
|
|
|
|
|
|
|
|
id := cmd.String("id")
|
|
id := cmd.String("id")
|
|
|
- query := "query Message($id: ID!) { message(id: $id) { id conversationId sender { id email } content sentAt createdAt updatedAt } }"
|
|
|
|
|
|
|
+ query := "query Message($id: ID!) { message(id: $id) { id sender { id email } content sentAt receivers createdAt updatedAt } }"
|
|
|
|
|
|
|
|
resp, err := c.Query(query, map[string]interface{}{"id": id})
|
|
resp, err := c.Query(query, map[string]interface{}{"id": id})
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -228,13 +229,13 @@ func messageGet(ctx context.Context, cmd *cli.Command) error {
|
|
|
|
|
|
|
|
m := result.Message
|
|
m := result.Message
|
|
|
fmt.Printf("ID: %s\n", m.ID)
|
|
fmt.Printf("ID: %s\n", m.ID)
|
|
|
- fmt.Printf("Conversation ID: %s\n", m.ConversationID)
|
|
|
|
|
if m.Sender != nil {
|
|
if m.Sender != nil {
|
|
|
fmt.Printf("Sender: %s (%s)\n", m.Sender.Email, m.SenderID)
|
|
fmt.Printf("Sender: %s (%s)\n", m.Sender.Email, m.SenderID)
|
|
|
} else {
|
|
} else {
|
|
|
fmt.Printf("Sender ID: %s\n", m.SenderID)
|
|
fmt.Printf("Sender ID: %s\n", m.SenderID)
|
|
|
}
|
|
}
|
|
|
fmt.Printf("Content: %s\n", m.Content)
|
|
fmt.Printf("Content: %s\n", m.Content)
|
|
|
|
|
+ fmt.Printf("Receivers: %s\n", strings.Join(m.Receivers, ", "))
|
|
|
fmt.Printf("Sent At: %s\n", m.SentAt)
|
|
fmt.Printf("Sent At: %s\n", m.SentAt)
|
|
|
fmt.Printf("Created At: %s\n", m.CreatedAt)
|
|
fmt.Printf("Created At: %s\n", m.CreatedAt)
|
|
|
fmt.Printf("Updated At: %s\n", m.UpdatedAt)
|
|
fmt.Printf("Updated At: %s\n", m.UpdatedAt)
|
|
@@ -251,21 +252,18 @@ func messageCreate(ctx context.Context, cmd *cli.Command) error {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- conversationID := cmd.String("conversation")
|
|
|
|
|
- senderID := cmd.String("sender")
|
|
|
|
|
|
|
+ receivers := cmd.StringSlice("receivers")
|
|
|
content := cmd.String("content")
|
|
content := cmd.String("content")
|
|
|
|
|
|
|
|
- if conversationID == "" {
|
|
|
|
|
- prompt := &survey.Input{Message: "Conversation ID:"}
|
|
|
|
|
- if err := survey.AskOne(prompt, &conversationID, survey.WithValidator(survey.Required)); err != nil {
|
|
|
|
|
|
|
+ if len(receivers) == 0 {
|
|
|
|
|
+ var receiverInput string
|
|
|
|
|
+ prompt := &survey.Input{Message: "Receiver user IDs (comma-separated):"}
|
|
|
|
|
+ if err := survey.AskOne(prompt, &receiverInput, survey.WithValidator(survey.Required)); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if senderID == "" {
|
|
|
|
|
- prompt := &survey.Input{Message: "Sender user ID:"}
|
|
|
|
|
- if err := survey.AskOne(prompt, &senderID, survey.WithValidator(survey.Required)); err != nil {
|
|
|
|
|
- return err
|
|
|
|
|
|
|
+ receivers = strings.Split(receiverInput, ",")
|
|
|
|
|
+ for i, r := range receivers {
|
|
|
|
|
+ receivers[i] = strings.TrimSpace(r)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -279,12 +277,11 @@ func messageCreate(ctx context.Context, cmd *cli.Command) error {
|
|
|
c := client.New(cfg.ServerURL)
|
|
c := client.New(cfg.ServerURL)
|
|
|
c.SetToken(cfg.Token)
|
|
c.SetToken(cfg.Token)
|
|
|
|
|
|
|
|
- mutation := `mutation CreateMessage($input: NewMessage!) { createMessage(input: $input) { id conversationId sender { id email } content sentAt createdAt } }`
|
|
|
|
|
|
|
+ mutation := `mutation CreateMessage($input: NewMessage!) { createMessage(input: $input) { id sender { id email } content sentAt receivers createdAt } }`
|
|
|
|
|
|
|
|
input := map[string]interface{}{
|
|
input := map[string]interface{}{
|
|
|
- "conversationId": conversationID,
|
|
|
|
|
- "senderId": senderID,
|
|
|
|
|
- "content": content,
|
|
|
|
|
|
|
+ "content": content,
|
|
|
|
|
+ "receivers": receivers,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
resp, err := c.Mutation(mutation, map[string]interface{}{"input": input})
|
|
resp, err := c.Mutation(mutation, map[string]interface{}{"input": input})
|
|
@@ -320,10 +317,11 @@ func messageUpdate(ctx context.Context, cmd *cli.Command) error {
|
|
|
|
|
|
|
|
id := cmd.String("id")
|
|
id := cmd.String("id")
|
|
|
content := cmd.String("content")
|
|
content := cmd.String("content")
|
|
|
|
|
+ receivers := cmd.StringSlice("receivers")
|
|
|
|
|
|
|
|
- if content == "" {
|
|
|
|
|
- prompt := &survey.Multiline{Message: "New message content:"}
|
|
|
|
|
- if err := survey.AskOne(prompt, &content, survey.WithValidator(survey.Required)); err != nil {
|
|
|
|
|
|
|
+ if content == "" && len(receivers) == 0 {
|
|
|
|
|
+ prompt := &survey.Multiline{Message: "Message content:"}
|
|
|
|
|
+ if err := survey.AskOne(prompt, &content); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -331,11 +329,15 @@ func messageUpdate(ctx context.Context, cmd *cli.Command) error {
|
|
|
c := client.New(cfg.ServerURL)
|
|
c := client.New(cfg.ServerURL)
|
|
|
c.SetToken(cfg.Token)
|
|
c.SetToken(cfg.Token)
|
|
|
|
|
|
|
|
- input := map[string]interface{}{
|
|
|
|
|
- "content": content,
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ mutation := `mutation UpdateMessage($id: ID!, $input: UpdateMessage!) { updateMessage(id: $id, input: $input) { id sender { id email } content sentAt receivers createdAt updatedAt } }`
|
|
|
|
|
|
|
|
- mutation := `mutation UpdateMessage($id: ID!, $input: UpdateMessageInput!) { updateMessage(id: $id, input: $input) { id content updatedAt } }`
|
|
|
|
|
|
|
+ input := map[string]interface{}{}
|
|
|
|
|
+ if content != "" {
|
|
|
|
|
+ input["content"] = content
|
|
|
|
|
+ }
|
|
|
|
|
+ if len(receivers) > 0 {
|
|
|
|
|
+ input["receivers"] = receivers
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
resp, err := c.Mutation(mutation, map[string]interface{}{"id": id, "input": input})
|
|
resp, err := c.Mutation(mutation, map[string]interface{}{"id": id, "input": input})
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -350,7 +352,7 @@ func messageUpdate(ctx context.Context, cmd *cli.Command) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if result.UpdateMessage == nil {
|
|
if result.UpdateMessage == nil {
|
|
|
- return fmt.Errorf("message not found")
|
|
|
|
|
|
|
+ return fmt.Errorf("failed to update message")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("Message updated successfully!\n")
|
|
fmt.Printf("Message updated successfully!\n")
|
|
@@ -369,19 +371,15 @@ func messageDelete(ctx context.Context, cmd *cli.Command) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
id := cmd.String("id")
|
|
id := cmd.String("id")
|
|
|
- skipConfirm := cmd.Bool("yes")
|
|
|
|
|
|
|
|
|
|
- if !skipConfirm {
|
|
|
|
|
|
|
+ if !cmd.Bool("yes") {
|
|
|
confirm := false
|
|
confirm := false
|
|
|
- prompt := &survey.Confirm{
|
|
|
|
|
- Message: fmt.Sprintf("Are you sure you want to delete message %s?", id),
|
|
|
|
|
- Default: false,
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ prompt := &survey.Confirm{Message: fmt.Sprintf("Are you sure you want to delete message %s?", id)}
|
|
|
if err := survey.AskOne(prompt, &confirm); err != nil {
|
|
if err := survey.AskOne(prompt, &confirm); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
if !confirm {
|
|
if !confirm {
|
|
|
- fmt.Println("Deletion cancelled.")
|
|
|
|
|
|
|
+ fmt.Println("Cancelled.")
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -389,7 +387,7 @@ func messageDelete(ctx context.Context, cmd *cli.Command) error {
|
|
|
c := client.New(cfg.ServerURL)
|
|
c := client.New(cfg.ServerURL)
|
|
|
c.SetToken(cfg.Token)
|
|
c.SetToken(cfg.Token)
|
|
|
|
|
|
|
|
- mutation := `mutation DeleteMessage($id: ID!) { deleteMessage(id: $id) }`
|
|
|
|
|
|
|
+ mutation := `mutation DeleteMessage($id: ID!) { deleteMessage(id: $id) { id } }`
|
|
|
|
|
|
|
|
resp, err := c.Mutation(mutation, map[string]interface{}{"id": id})
|
|
resp, err := c.Mutation(mutation, map[string]interface{}{"id": id})
|
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -397,18 +395,18 @@ func messageDelete(ctx context.Context, cmd *cli.Command) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
var result struct {
|
|
var result struct {
|
|
|
- DeleteMessage bool `json:"deleteMessage"`
|
|
|
|
|
|
|
+ DeleteMessage *Message `json:"deleteMessage"`
|
|
|
}
|
|
}
|
|
|
if err := json.Unmarshal(resp.Data, &result); err != nil {
|
|
if err := json.Unmarshal(resp.Data, &result); err != nil {
|
|
|
return err
|
|
return err
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if result.DeleteMessage {
|
|
|
|
|
- fmt.Printf("Message %s deleted successfully.\n", id)
|
|
|
|
|
- } else {
|
|
|
|
|
- fmt.Printf("Failed to delete message %s.\n", id)
|
|
|
|
|
|
|
+ if result.DeleteMessage == nil {
|
|
|
|
|
+ return fmt.Errorf("failed to delete message")
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ fmt.Printf("Message %s deleted successfully!\n", result.DeleteMessage.ID)
|
|
|
|
|
+
|
|
|
return nil
|
|
return nil
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -422,25 +420,44 @@ func messageWatch(ctx context.Context, cmd *cli.Command) error {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
wsClient := client.NewWebSocketClient(cfg.ServerURL, cfg.Token)
|
|
wsClient := client.NewWebSocketClient(cfg.ServerURL, cfg.Token)
|
|
|
-
|
|
|
|
|
if err := wsClient.Connect(); err != nil {
|
|
if err := wsClient.Connect(); err != nil {
|
|
|
return fmt.Errorf("failed to connect: %w", err)
|
|
return fmt.Errorf("failed to connect: %w", err)
|
|
|
}
|
|
}
|
|
|
defer wsClient.Close()
|
|
defer wsClient.Close()
|
|
|
|
|
|
|
|
- fmt.Println("Watching for new messages...")
|
|
|
|
|
- fmt.Println("Press Ctrl+C to stop.")
|
|
|
|
|
-
|
|
|
|
|
- subscription := "subscription { messageAdded { id conversationId sender { id email } content sentAt } }"
|
|
|
|
|
|
|
+ subscription := `subscription MessageAdded { messageAdded { id sender { id email } content sentAt receivers createdAt } }`
|
|
|
|
|
|
|
|
if err := wsClient.Subscribe("1", subscription, nil); err != nil {
|
|
if err := wsClient.Subscribe("1", subscription, nil); err != nil {
|
|
|
return fmt.Errorf("failed to subscribe: %w", err)
|
|
return fmt.Errorf("failed to subscribe: %w", err)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ fmt.Println("Watching for new messages... (press Ctrl+C to stop)")
|
|
|
|
|
+
|
|
|
for {
|
|
for {
|
|
|
select {
|
|
select {
|
|
|
case msg := <-wsClient.Messages():
|
|
case msg := <-wsClient.Messages():
|
|
|
- fmt.Printf("New message: %s\n", string(msg))
|
|
|
|
|
|
|
+ var result struct {
|
|
|
|
|
+ MessageAdded *Message `json:"messageAdded"`
|
|
|
|
|
+ }
|
|
|
|
|
+ if err := json.Unmarshal(msg, &result); err != nil {
|
|
|
|
|
+ fmt.Fprintf(os.Stderr, "Error parsing message: %v\n", err)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if result.MessageAdded != nil {
|
|
|
|
|
+ m := result.MessageAdded
|
|
|
|
|
+ sender := "Unknown"
|
|
|
|
|
+ if m.Sender != nil {
|
|
|
|
|
+ sender = m.Sender.Email
|
|
|
|
|
+ }
|
|
|
|
|
+ fmt.Printf("\n--- New Message ---\n")
|
|
|
|
|
+ fmt.Printf("ID: %s\n", m.ID)
|
|
|
|
|
+ fmt.Printf("From: %s\n", sender)
|
|
|
|
|
+ fmt.Printf("Content: %s\n", m.Content)
|
|
|
|
|
+ fmt.Printf("Receivers: %s\n", strings.Join(m.Receivers, ", "))
|
|
|
|
|
+ fmt.Printf("Sent At: %s\n", m.SentAt)
|
|
|
|
|
+ fmt.Println("--------------------")
|
|
|
|
|
+ }
|
|
|
case err := <-wsClient.Errors():
|
|
case err := <-wsClient.Errors():
|
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
|
|
|
case <-wsClient.Done():
|
|
case <-wsClient.Done():
|