@@ -43,6 +43,8 @@ commands:
4343 whoami Show the current Graph account
4444 mail List mail with optional filters
4545 mail-get Fetch one mail message by id
46+ mail-move Move one or more mail messages to another folder
47+ mail-archive Move one or more mail messages to Archive
4648 agenda List calendar events in a time range
4749 event-get Fetch one calendar event by id
4850 files List or search OneDrive files
@@ -108,6 +110,10 @@ func run(args []string) error {
108110 return cmdMail (s , g , rest )
109111 case "mail-get" :
110112 return cmdMailGet (s , g , rest )
113+ case "mail-move" :
114+ return cmdMailMove (s , g , rest )
115+ case "mail-archive" :
116+ return cmdMailArchive (s , g , rest )
111117 case "agenda" :
112118 return cmdAgenda (s , g , rest )
113119 case "event-get" :
@@ -433,6 +439,59 @@ func cmdMailGet(s *store.Store, g globalFlags, args []string) error {
433439 return emit (g , "mail-get" , data )
434440}
435441
442+ func cmdMailMove (s * store.Store , g globalFlags , args []string ) error {
443+ fs := flag .NewFlagSet ("mail-move" , flag .ContinueOnError )
444+ destination := fs .String ("destination" , "" , "destination folder id or well-known folder name" )
445+ destinationAlias := fs .String ("dest-folder" , "" , "alias for --destination" )
446+ if err := fs .Parse (args ); err != nil {
447+ return err
448+ }
449+ if * destination == "" {
450+ * destination = * destinationAlias
451+ }
452+ if * destination == "" || fs .NArg () == 0 {
453+ return fmt .Errorf ("usage: msx mail-move --destination <folder-id|well-known-name> <message-id> [message-id ...]" )
454+ }
455+ return runMailMove (s , g , * destination , fs .Args (), "mail-move" )
456+ }
457+
458+ func cmdMailArchive (s * store.Store , g globalFlags , args []string ) error {
459+ fs := flag .NewFlagSet ("mail-archive" , flag .ContinueOnError )
460+ if err := fs .Parse (args ); err != nil {
461+ return err
462+ }
463+ if fs .NArg () == 0 {
464+ return fmt .Errorf ("usage: msx mail-archive <message-id> [message-id ...]" )
465+ }
466+ return runMailMove (s , g , "archive" , fs .Args (), "mail-archive" )
467+ }
468+
469+ func runMailMove (s * store.Store , g globalFlags , destination string , ids []string , command string ) error {
470+ client := newGraphClient (s , g .profile )
471+ results := make ([]map [string ]any , 0 , len (ids ))
472+ for _ , id := range ids {
473+ id = strings .TrimSpace (id )
474+ if id == "" {
475+ continue
476+ }
477+ body , err := json .Marshal (map [string ]any {"destinationId" : destination })
478+ if err != nil {
479+ return err
480+ }
481+ data , err := client .RequestWithBody ("POST" , "/me/messages/" + url .PathEscape (id )+ "/move" , nil , body )
482+ if err != nil {
483+ return fmt .Errorf ("move %s: %w" , id , err )
484+ }
485+ results = append (results , data )
486+ }
487+ return emit (g , command , map [string ]any {
488+ "ok" : true ,
489+ "destination" : destination ,
490+ "count" : len (results ),
491+ "value" : results ,
492+ })
493+ }
494+
436495func cmdAgenda (s * store.Store , g globalFlags , args []string ) error {
437496 fs := flag .NewFlagSet ("agenda" , flag .ContinueOnError )
438497 top := fs .Int ("top" , 20 , "maximum number of events" )
0 commit comments