2017-01-29 21 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!" 

Итак, что я пытаюсь сделать здесь послать правильно отформатированный MIME (RFC 2822 совместимый) электронной почты закодировано в URL безопасного base64 через Invoke-WebRequest в Powershell. Этот образец должен работать, но проблема заключается в том, что Gmail фактически не принимает отправки электронной почты в этом формате. Любая помощь в получении API Gmail для фактической работы будет означать, что это было бы неплохо.Использование Gmail API для отправки по электронной почте с помощью Invoke-WebRequest в Powershell

+0

вы пытались с помощью pscmdlets здесь: https://github.com/squid808/gShell – Kiran

+0

я сделал, но это не так легко интегрировать в свой проект, и я не нужен другое API функциональных возможностей Google при условии , – DeepS1X

+0

Никто, на самом деле, никогда не отвечал на этот вопрос, к сожалению. – DeepS1X

ответ

1

После того как я некоторое время работал над этим, я наконец нашел недостающую деталь. Я не преобразовывал свою кодировку Base64 (мое почтовое сообщение) в json, и я не включил ее в Invoke-RestMethod правильно.

Я, наконец, нашел недостающую деталь здесь: https://github.com/thinkAmi/PowerShell_misc/blob/master/gmail_api/gmail_sender.ps1. Вот фрагмент, который указал мне в правильном направлении.

$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" 

После того, как я был, что я был в состоянии сколотить решение для отправки через API Gmail с помощью Powershell.

Я нашел очень полезный код на this SO question (код можно найти here), который помог мне получить правильные токены доступа OAuth.

Это рабочее решение. Его нужно очистить, но, надеюсь, это поможет кому-то другому.

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

Любые причины не использовать Send-MailMessage?. Если нет, вы можете попробовать этот пример:

$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

Причина в том, что я не могу использовать SMTP в нашей организации (все порты, кроме 80 и 443, блокируются брандмауэром), и поскольку я уже получил удаление и извлечение электронной почты для работы с API, я счел разумным попытаться расширить он отправляет электронные письма по порту 80/443 вместо того, чтобы спорить с сотрудниками службы безопасности о том, почему нам нужно открыть еще один порт в брандмауэре. – DeepS1X

+0

К сожалению, похоже, что я ударил здесь немного кирпичной стены, так как я не могу понять, что я делаю неправильно с помощью REST API, который они предоставили. – DeepS1X

+0

Нет идей о том, как сделать исходную функцию кода? – DeepS1X