package main import ( "context" "fmt" "log" "os" "strings" "os/exec" "path/filepath" "encoding/base64" "golang.org/x/oauth2/google" "google.golang.org/api/gmail/v1" "google.golang.org/api/option" ) const CREDENTIALS_DIR = "creds" const TOKEN_FILE = "token.json" const CREDENTIALS_FILE = "credentials.json" const USER = "me" const EMAILADDR = "downloader.kasernen@gmail.com" func getEmail(service *gmail.Service, msgID string) *gmail.Message { r, err := service.Users.Messages.Get(USER, msgID).Format("FULL").Do() if err != nil { log.Fatalf("Error when getting mail content: %v", err) } if r == nil { log.Fatalf("Response when getting mail was nil") } return r } func getEmailPlaintext (mail *gmail.Message) (fromAddr string, bodyStr string) { part := mail.Payload.Parts[0].Body.Data body, err := base64.StdEncoding.DecodeString(part) if err != nil { log.Fatalf("Error in message body decoding: %v", err) } for _, header := range mail.Payload.Headers { if header.Name == "From" { _, addrPart, _ := strings.Cut(header.Value, "<") fromAddr, _, _ = strings.Cut(addrPart, ">") } } return fromAddr, string(body) } func main() { ctx := context.Background() creds_file := filepath.Join(CREDENTIALS_DIR, CREDENTIALS_FILE) creds_b, err := os.ReadFile(creds_file) if err != nil { log.Fatalf("Unable to read client secret file: %v", err) } config, err := google.ConfigFromJSON(creds_b, gmail.GmailModifyScope) if err != nil { log.Fatalf("Unable to parse client secret file to config: %v", err) } client := getClient(config) service, err := gmail.NewService(ctx, option.WithHTTPClient(client)) if err != nil { log.Fatalf("Unable to retrieve Gmail client: %v", err) } user := "me" r, err := service.Users.Messages.List(user).LabelIds("INBOX").Do() if err != nil { log.Fatalf("Unable to retrieve messages: %v", err) } if len(r.Messages) == 0 { fmt.Println("No messages found") return } fmt.Println("Messages:") for _, msg := range r.Messages { fmt.Printf("- %s\n", msg.Id) mail := getEmail(service, msg.Id) fromAddr, msgBody := getEmailPlaintext(mail) fmt.Printf("From: %s\n", fromAddr) fmt.Printf("Link: %s", msgBody) cmd := exec.Command("yt-dlp", msgBody) err = cmd.Run() if err != nil { log.Fatalf("Video download failed: %v", err) } var modifications gmail.ModifyMessageRequest modifications.AddLabelIds = []string{"Label_6181251506395195727"} modifications.RemoveLabelIds = []string{"INBOX"} _, err = service.Users.Messages.Modify(USER, msg.Id, &modifications).Do() if err != nil { log.Fatalf("Unable to move email request from inbox: %v", err) } var message gmail.Message messageStr := fmt.Sprintf( "From: %s\r\n" + "To: %s\r\n" + "Subject: Request received\r\n\r\n" + "Message body", EMAILADDR, fromAddr) message.Raw = base64.URLEncoding.EncodeToString([]byte(messageStr)) _, err = service.Users.Messages.Send(USER, &message).Do() if err != nil { log.Fatalf("Unable to send email: %v", err) } fmt.Printf("Download completed, confirmation sent to: %s\n", fromAddr) fmt.Println() } }