github.com/yaegashi/msgraph.go@v0.1.4/cmd/msgraph-me/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "flag" 6 "fmt" 7 "io" 8 "io/ioutil" 9 "log" 10 "net/http" 11 "os" 12 "time" 13 14 "github.com/yaegashi/msgraph.go/jsonx" 15 "github.com/yaegashi/msgraph.go/msauth" 16 msgraph "github.com/yaegashi/msgraph.go/v1.0" 17 "github.com/yaegashi/wtz.go" 18 "golang.org/x/oauth2" 19 ) 20 21 const ( 22 defaultTenantID = "common" 23 defaultClientID = "45c7f99c-0a94-42ff-a6d8-a8d657229e8c" 24 defaultTokenCachePath = "token_cache.json" 25 ) 26 27 var defaultScopes = []string{"offline_access", "User.Read", "Calendars.Read", "Files.Read"} 28 29 func dump(o interface{}) { 30 enc := jsonx.NewEncoder(os.Stdout) 31 enc.SetIndent("", " ") 32 enc.Encode(o) 33 } 34 35 func main() { 36 var tenantID, clientID, tokenCachePath string 37 flag.StringVar(&tenantID, "tenant-id", defaultTenantID, "Tenant ID") 38 flag.StringVar(&clientID, "client-id", defaultClientID, "Client ID") 39 flag.StringVar(&tokenCachePath, "token-cache-path", defaultTokenCachePath, "Token cache path") 40 flag.Parse() 41 42 ctx := context.Background() 43 m := msauth.NewManager() 44 m.LoadFile(tokenCachePath) 45 ts, err := m.DeviceAuthorizationGrant(ctx, tenantID, clientID, defaultScopes, nil) 46 if err != nil { 47 log.Fatal(err) 48 } 49 m.SaveFile(tokenCachePath) 50 51 httpClient := oauth2.NewClient(ctx, ts) 52 graphClient := msgraph.NewClient(httpClient) 53 54 { 55 log.Printf("Get current logged in user information") 56 req := graphClient.Me().Request() 57 log.Printf("GET %s", req.URL()) 58 user, err := req.Get(ctx) 59 if err == nil { 60 dump(user) 61 } else { 62 log.Println(err) 63 } 64 } 65 66 { 67 log.Println("Get current logged in user's first 10 events") 68 req := graphClient.Me().Events().Request() 69 req.Top(10) 70 tzname, err := wtz.LocationToName(time.Local) 71 if err != nil { 72 log.Println(err) 73 tzname = "Tokyo Standard Time" 74 } 75 req.Header().Add("Prefer", fmt.Sprintf(`outlook.timezone="%s"`, tzname)) 76 log.Printf("GET %s", req.URL()) 77 events, err := req.GetN(ctx, 1) 78 if err == nil { 79 dump(events) 80 } else { 81 log.Println(err) 82 } 83 } 84 85 var items []msgraph.DriveItem 86 { 87 log.Printf("Get files in the root folder of user's drive") 88 req := graphClient.Me().Drive().Root().Children().Request() 89 // This filter is not supported by OneDrive for Business or SharePoint Online 90 // https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/filtering-results?#filterable-properties 91 // req.Filter("file ne null") 92 log.Printf("GET %s", req.URL()) 93 items, err = req.Get(ctx) 94 if err != nil { 95 log.Println(err) 96 } 97 } 98 99 for _, item := range items { 100 timestamp := item.LastModifiedDateTime.Format(time.RFC3339) 101 itemType := "FILE" 102 if item.File == nil { 103 itemType = "DIR " 104 } 105 log.Printf(" %s %s %10d %s", itemType, timestamp, *item.Size, *item.Name) 106 } 107 108 fmt.Print("Press ENTER to download files or Ctrl-C to abort: ") 109 fmt.Scanln() 110 111 for _, item := range items { 112 if item.File == nil { 113 continue 114 } 115 err := func() error { 116 log.Printf("Download %q (%d bytes)", *item.Name, *item.Size) 117 if url, ok := item.GetAdditionalData("@microsoft.graph.downloadUrl"); ok { 118 res, err := http.Get(url.(string)) 119 if err != nil { 120 return err 121 } 122 defer res.Body.Close() 123 if res.StatusCode != http.StatusOK { 124 b, _ := ioutil.ReadAll(res.Body) 125 return fmt.Errorf("%s: %s", res.Status, string(b)) 126 } 127 f, err := os.Create(*item.Name) 128 if err != nil { 129 return err 130 } 131 defer f.Close() 132 _, err = io.Copy(f, res.Body) 133 if err != nil { 134 return err 135 } 136 } else { 137 return fmt.Errorf("unknown download URL") 138 } 139 return nil 140 }() 141 if err != nil { 142 log.Println(err) 143 } 144 } 145 }