2017-01-29 57 views
8
$firstEmail = "[email protected]"; 
$secondEmail = "[email protected]"; 

Function Set-MIMEBase64Encoded 
{ 
Param(
[string]$subject 
) 

#Creates a MIME formatted email. 
$text = "From: $firstEmail\r\n" + "To: $secondEmail\r\n" + "Subject: $subject\r\n\r\n" + "$subject"; 
$bytes = [System.Text.Encoding]::Unicode.GetBytes($text); 
#Converts to Base 64. 
$encodedText =[Convert]::ToBase64String($bytes); 

#Makes encoding URL safe. 
$urlSafe1 = $encodedText.replace('+', '-'); 
$urlSafe2 = $urlSafe1.replace('/', '_'); 
$urlSafe3 = $urlSafe2.replace('=', '*'); 

return $urlSafe3; 
} 

Function Mail-Output 
{ 
Param(
[String]$subject 
) 

#Acquires access token. 
$accessToken = Refresh-AccessToken; 
#Sends subject for MIMEB64 encoding 
$text = Set-MIMEBase64Encoded -subject $subject; 

#Requests sends email according to parameters. 
$messages = Invoke-WebRequest -Uri ("https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=$accessToken&raw=$text") -Method Post; 
Write-Output $messages 
} 

Mail-Output -subject "Hope this works!" 

Więc, co usiłuję zrobić tutaj jest wysłanie prawidłowo sformatowany MIME (RFC 2822 zgodny) e-mail zakodowane w URL bezpiecznej base64 przez Invoke-WebRequest w powershell. Ten przykład powinien zadziałać, ale wydaje się, że Gmail nie akceptuje wysyłania wiadomości e-mail w tym formacie. Każda pomoc w uruchomieniu interfejsu API Gmaila byłaby zgodna z założeniami.Using Gmail API do wysyłania wiadomości e-mail za pomocą Invoke-WebRequest w PowerShell

+0

próbowałeś za pomocą pscmdlets tutaj: https://github.com/squid808/gShell – Kiran

+0

zrobiłem, ale nie jest łatwo zintegrować z mojego projektu, ani nie muszę inne funkcje Google API przewidzianych tam . – DeepS1X

+0

Niestety, nikt nigdy nie ukończył odpowiedzi na to pytanie. – DeepS1X

Odpowiedz

1

Po pracy nad tym przez chwilę w końcu znalazłem brakujący element. Nie konwertowałem mojego zakodowanego ciągu Base64 (moja wiadomość e-mail) do json i nie włączałem go poprawnie do Invoke-RestMethod.

W końcu znalazłem brakujący element tutaj: https://github.com/thinkAmi/PowerShell_misc/blob/master/gmail_api/gmail_sender.ps1. Oto fragment, który wskazał mi właściwy kierunek.

$body = @{ "raw" = $raw; } | ConvertTo-Json 
$uri = "https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=$AccessToken" 
$result = Invoke-RestMethod $uri -Method POST -ErrorAction Stop -Body $body -ContentType "application/json" 

Kiedyś to udało mi się spleść razem rozwiązanie do przesyłania za pośrednictwem interfejsu API Gmaila przy użyciu Powershell.

Znalazłem bardzo pomocny kod na this SO question (kod można znaleźć here), który pomógł mi uzyskać prawidłowe tokeny dostępu OAuth.

Oto działające rozwiązanie. To musi być oczyszczone, ale mam nadzieję, że będzie to pomoc dla kogoś innego.

Function Encode-Base64Url([string]$MsgIn) 
{ 
    $InputBytes = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($MsgIn)) 

    # "Url-Safe" base64 encodeing 
    $InputBytes = $InputBytes.Replace('+', '-').Replace('/', '_').Replace("=", "") 
    return $InputBytes 
} 

Add-Type -Path "C:\path\to\AE.Net.Mail.dll" # We are using AE.Net.Mail to create our message. https://github.com/andyedinborough/aenetmail 
Add-Type -AssemblyName System.IO 
Add-Type -AssemblyName System.Text.Encoding 

$ToEmail = "[email protected]" 
$FromEmail = "[email protected]" 
# From https://gist.github.com/LindaLawton/55115de5e8b366be3969b24884f30a39 
# Setup: 
# 
# Step 1: create new project on https://console.developers.google.com. 
# Step 2: Create oauth credentials type native or other. 
#   Save the client id and secret. 
# Step 3: Enable the api you are intersted in accessing. 
#   Look up what scopes you need for accssing this api, 
# Step 4: Using the client id, and client secret from the 
# 
# 
# Inital Authenticate: Authentication must be done the first time via a webpage create the link you will need. More then one scope can be added simply by seporating them with a comama 
#  Place it in a webbrowser. 
# 
# https://accounts.google.com/o/oauth2/auth?client_id={CLIENT ID}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope={SCOPES}&response_type=code 
# Change Scopes to https://www.googleapis.com/auth/gmail.send 
#      https://www.googleapis.com/auth/gmail.readonly 
#      https://mail.google.com/ 
# 
# Copy the authencation code and run the following script. 
#  note: AuthorizationCode can only be used once you will need to save the refresh token returned to you. 

$ClientID = "Your Client ID" 
$secret = "Your Client Secret" 
$RedirectURI = "urn:ietf:wg:oauth:2.0:oob" 
$AuthorizationCode = 'Your Authorization Code' 

$tokenParams = @{ 
     client_id=$ClientID; 
     client_secret=$secret; 
     code=$AuthorizationCode; 
     grant_type='authorization_code'; 
     redirect_uri=$RedirectURI 
    } 

$token = Invoke-WebRequest -Uri "https://accounts.google.com/o/oauth2/token" -Method POST -Body $tokenParams | ConvertFrom-Json 

# Use refresh token to get new access token 
# The access token is used to access the api by sending the access_token parm with every request. 
# Access tokens are only valid for an hour, after that you will need to request a new one using your refresh_token 
$refreshToken = $token.refresh_token 

$RefreshTokenParams = @{ 
     client_id=$ClientID; 
     client_secret=$secret; 
     refresh_token=$refreshToken; 
     grant_type='refresh_token'; 
    } 

$RefreshedToken = Invoke-WebRequest -Uri "https://accounts.google.com/o/oauth2/token" -Method POST -Body $refreshTokenParams | ConvertFrom-Json 

$AccessToken = $RefreshedToken.access_token 

# Compose and send an email using the access token 
$From = New-Object MailAddress($FromEmail) 
$To = New-Object MailAddress($ToEmail) 

$Msg = New-Object AE.Net.Mail.MailMessage 
$Msg.To.Add($To) 
$Msg.ReplyTo.Add($From) # Important so email doesn't bounce 
$Msg.From = $From 
$Msg.Subject = "Sent through the Gmail API using Powershell" 
$Msg.Body = "Hello, world from Gmail API using Powershell!" 

$MsgSW = New-Object System.IO.StringWriter 
$Msg.Save($MsgSW) 

$EncodedEmail = Encode-Base64Url $MsgSW 

# Found this gem here: https://github.com/thinkAmi/PowerShell_misc/blob/master/gmail_api/gmail_sender.ps1 
$Content = @{ "raw" = $EncodedEmail; } | ConvertTo-Json 

$Result = Invoke-RestMethod -Uri "https://www.googleapis.com/gmail/v1/users/me/messages/send?access_token=$AccessToken" -Method POST -ErrorAction Stop -Body $Content -ContentType "Application/Json" 

if($Result) 
{ 
    Write-Host $Result 
} 
else 
{ 
    Write-Host "Error sending email" 
} 
4

Jakiekolwiek powody, by nie używać Send-MailMessage? Jeśli nie, możesz spróbować tego przykładu:

$From = "[email protected]" 
$To = "[email protected]" 
$Cc = "[email protected]" 
$Attachment = "C:\temp\Some random file.txt" 
$Subject = "Email Subject" 
$Body = "Insert body text here" 
$SMTPServer = "smtp.gmail.com" 
$SMTPPort = "587" 
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject ` 
    -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl ` 
    -Credential (Get-Credential) -Attachments $Attachment 
+0

Powodem jest to, że nie mogę używać SMTP w naszej organizacji (wszystkie porty, z wyjątkiem 80 i 443, są blokowane przez zaporę), a ponieważ mam już usunięte e-maile i ich pobieranie do pracy z API, pomyślałem, że rozsądnie jest spróbować przedłużyć do wysyłania wiadomości e-mail przez port 80/443, zamiast spierać się z pracownikami ochrony, dlaczego musimy otworzyć inny port w zaporze sieciowej. – DeepS1X

+0

Niestety wygląda na to, że uderzyłem tu trochę o ceglaną ścianę, ponieważ nie jestem w stanie zrozumieć, co robię poprawnie z REST API, który dostarczyli. – DeepS1X

+0

Brak pomysłów na temat działania oryginalnego kodu? – DeepS1X