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  }