beginner
beginner

Reputation: 15

Unable to send email to multiple recipients in powershell using sendgrid API

I am testing send mail feature in PowerShell using sendgrid API key. The problem is when I give one email in the To list, test email comes successfully but when I add multiple email ids it gives "Cannot convert value to type System.String" error. Can anyone please help :(

function Send-EmailWithSendGrid {
     Param
    (
        [Parameter(Mandatory=$true)]
        [string] $From,

        [Parameter(Mandatory=$true)]
        [String] $To,

        [Parameter(Mandatory=$true)]
        [string] $ApiKey,

        [Parameter(Mandatory=$true)]
        [string] $Subject,

        [Parameter(Mandatory=$true)]
        [string] $Body

    )

    $headers = @{}
    $headers.Add("Authorization","Bearer $apiKey")
    $headers.Add("Content-Type", "application/json")

    $jsonRequest = [ordered]@{
                            personalizations= @(@{to = @(@{email =  "$To"}) 
                                subject = "$SubJect" })
                                from = @{email = "$From"}
                                content = @( @{ type = "text/html"
                                            value = "$Body" }
                                )} | ConvertTo-Json -Depth 10
    Invoke-RestMethod   -Uri "https://api.sendgrid.com/v3/mail/send" -Method Post -Headers $headers -Body $jsonRequest 

}

$MailParams = @{ 
              From = "[email protected]"
                To =  "[email protected]" , "[email protected]"
            APIKEY = "putapikeyhere"
           Subject = "TEST MAIL"
              Body = $HTMLmessage
            }

Send-EmailWithSendGrid @MailParams

I have tried multiple combinations like below but couldn't able to solve this problem.

To = "[email protected]" , "[email protected]"

or

To = "[email protected] , [email protected]"

or

To = " ; "

Error:

Send-EmailWithSendGrid : Cannot process argument transformation on parameter 'To'. Cannot convert value to type System.String.
At line:82 char:24
+ Send-EmailWithSendGrid @MailParams
+                        ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Send-EmailWithSendGrid], ParameterBindingArgumentTransformationException
    + FullyQualifiedErrorId : ParameterArgumentTransformationError,Send-EmailWithSendGrid

Upvotes: 0

Views: 1138

Answers (2)

Djongov
Djongov

Reputation: 325

After searching a lot for this and i finally had to build it myself. The challenge is that SendGrid want the To Array to be in the format

{
  "personalizations": [
    {
      "to": [
        {
          "email": "[email protected]"
        },
        {
          "email": "[email protected]"
        },
        {
          "email": "[email protected]"
        }
      ],
      "subject": "YOUR SUBJECT LINE GOES HERE"
    }
  ]
}

So what I've found challenging is that in Powershell, key value pairs (aka. hashtables) do not easily allow the key to be the same name over and over again. After some fighting i made it work. Here is it:

function Send-EmailWithSendGrid {
    #"text/plain" or "text/html"
    $body_type = "text/html"
    #Body
    $Body = "<h1>Hello, test email from Powershell using SendGrid</h1><p>Paragraph</p>"
    #From
    $From = "[email protected]"
    #Subject
    $Subject = "Test Email"
    #Api Key
    $ApiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    #Array with recipients
    $recipients = "[email protected]", "[email protected]"
    #To needs to be an array which consists of hashtable with multiple "email" keys and the different reciepients as values
    $to_hashtable = [Collections.ArrayList]::new()
    #loop through the recipients array and add it to the $to_hashtable array
    foreach ($recipient in $recipients) {
        $null = $to_hashtable.Add( @{email=$recipient} )
    }    
    #Prepare the headers using a hashtable
    $headers = @{}
    $headers.Add("Authorization","Bearer $apiKey")
    $headers.Add("Content-Type", "application/json")
    #build the JSON body of the http request
    $jsonRequest = [ordered]@{
                            personalizations= @(@{to = @($to_hashtable) 
                                subject = "$SubJect" })
                                from = @{email = "$From"}
                                content = @( @{ type = $body_type
                                            value = "$Body" }
                                )} | ConvertTo-Json -Depth 10 
    #$jsonRequest
    #send the actual HTTP request to the SendGrid API
    Invoke-RestMethod -Uri "https://api.sendgrid.com/v3/mail/send" -Method Post -Headers $headers -Body $jsonRequest
 
}

#Call the function
Send-EmailWithSendGrid

Upvotes: 0

Tejinder Singh Uppal
Tejinder Singh Uppal

Reputation: 11

Not sure if this has already been answered, but I was able to resolve this by using the parameter type as Array and using the FOREACH loop inside the function. (See below).

function Send-EmailWithSendGrid {
     Param
    (
        [Parameter(Mandatory=$true)]
        [string] $From,

        [Parameter(Mandatory=$true)]
        [String[]] $To,

        [Parameter(Mandatory=$true)]
        [string] $ApiKey,

        [Parameter(Mandatory=$true)]
        [string] $Subject,

        [Parameter(Mandatory=$true)]
        [string] $Body

    )

    $headers = @{}
    $headers.Add("Authorization","Bearer $apiKey")
    $headers.Add("Content-Type", "application/json")
    foreach($t in $To){
        $jsonRequest = [ordered]@{
                                personalizations= @(@{to = @(@{email =  "$t"}) 
                                    subject = "$SubJect" })
                                    from = @{email = "$From"}
                                    content = @( @{ type = "text/html"
                                                value = "$Body" }
                                    )} | ConvertTo-Json -Depth 10
        Invoke-RestMethod   -Uri "https://api.sendgrid.com/v3/mail/send" -Method Post -Headers $headers -Body $jsonRequest 
    }
}

$From = "[email protected]"
$To =  @("[email protected]" , "[email protected]")
$APIKEY = "putapikeyhere"
$Subject = "TEST MAIL"
$Body = $HTMLmessage

Send-EmailWithSendGrid -from $From -to $To -ApiKey $APIKEY -Body $Body -Subject $Subject

Upvotes: 1

Related Questions