SendGrid Attachments Are Empty or Corrupt Using API (VBA)

前端 未结 3 460
日久生厌
日久生厌 2021-01-21 13:44

This seems to be a constant issue with the SendGrid Web API and emailing attachments. I\'ve found many, many posts across the web all of whom are having this same issue... but n

3条回答
  •  爱一瞬间的悲伤
    2021-01-21 14:24

    This code has some additional code and logic to attach multiple attachments:

    Option Explicit
    
    Sub SendEmailUsingSendGrid()
        Dim HttpReqURL As String: HttpReqURL = "https://api.sendgrid.com/api/mail.send.json"
    
        Const adSaveCreateNotExist = 1
        Const adSaveCreateOverWrite = 2
        Const adTypeBinary = 1
        Const adTypeText = 2
        Const adModeReadWrite = 3
    
        Dim YOUR_SG_CREDS_USERNAME As String
        YOUR_SG_CREDS_USERNAME = "username"
    
        Dim YOUR_SG_CREDS_PASSWORD As String
        YOUR_SG_CREDS_PASSWORD = "password"
    
        Dim multiPartUploadBoundary As String
        multiPartUploadBoundary = "123456789abc"
    
        Dim eTo As String
        eTo = "to@example.com"
    
        Dim eToName As String
        eToName = "To Name"
    
        Dim eSubject As String
        eSubject = "My Subject"
    
        Dim eBody As String
        eBody = "This is a test!"
    
        Dim eFrom As String
        eFrom = "from@example.com"
    
        Dim outputStream As Object
        Set outputStream = CreateObject("adodb.stream")
        outputStream.Type = adTypeText
        outputStream.Mode = adModeReadWrite
        outputStream.charset = "windows-1252"
        outputStream.Open
    
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "api_user", YOUR_SG_CREDS_USERNAME
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "api_key", YOUR_SG_CREDS_PASSWORD
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "to", eTo
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "toname", eToName
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "subject", eSubject
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "text", eBody
        AddParameterAndValueToStream outputStream, multiPartUploadBoundary, "from", eFrom
    
        Dim filesToAttach As New Collection
        filesToAttach.Add "C:\temp\test.png"
        filesToAttach.Add "C:\temp\test2.jpg"
    
        AddMultipleFilesToStream outputStream, multiPartUploadBoundary, filesToAttach
    
        outputStream.WriteText "--" + multiPartUploadBoundary + "--" + vbCrLf
    
        Dim binaryStream As Object
        Set binaryStream = CreateObject("ADODB.Stream")
        binaryStream.Mode = 3 'read write
        binaryStream.Type = 1 'adTypeText 'Binary
        binaryStream.Open
    
        ' copy text to binary stream so xmlHttp.send works correctly
        outputStream.Position = 0
        outputStream.CopyTo binaryStream
        outputStream.Close
    
        binaryStream.Position = 0
    
        Dim xmlHttp As Object
        Set xmlHttp = CreateObject("MSXML2.XMLHTTP")
        xmlHttp.Open "POST", HttpReqURL, False
        xmlHttp.setRequestHeader "Content-Type", "multipart/form-data; boundary=" + multiPartUploadBoundary
        xmlHttp.setRequestHeader "Content-Length", Len(binaryStream.Size)
        xmlHttp.send binaryStream.Read(binaryStream.Size)
    
        binaryStream.Close
    End Sub
    
    Sub AddParameterAndValueToStream(stream As Variant, boundary As String, paramName As String, value As String)
        stream.WriteText "--" + boundary + vbCrLf
        stream.WriteText "Content-Disposition: form-data; name=""" + paramName + """" + vbCrLf
        stream.WriteText vbCrLf
        stream.WriteText value + vbCrLf
    End Sub
    
    Sub AddFileToStream(stream As Variant, boundary As String, name As String, filePath As String)
        Dim fileBytes As String
        fileBytes = ReadBinaryFile(filePath)
    
        stream.WriteText "--" + boundary + vbCrLf
        stream.WriteText "Content-Disposition: form-data; name=""files[" + name + "]""; filename=""" + name + """" + vbCrLf
        stream.WriteText "Content-Type: application/octet-stream" + vbCrLf
        stream.WriteText vbCrLf
        stream.WriteText fileBytes + vbCrLf
    End Sub
    
    Sub AddMultipleFilesToStream(stream As Variant, boundary As String, filePaths As Collection)
        Dim fileCount As Integer
        fileCount = filePaths.Count
    
        For n = 1 To fileCount
            Dim fileName As String
            Dim filePath As String
    
            filePath = filePaths(n)
            fileName = Right(filePath, Len(filePath) - InStrRev(filePath, "\"))
    
            AddFileToStream stream, boundary, fileName, filePath
        Next n
    End Sub
    
    Function ReadBinaryFile(strPath)
        Dim oFSO: Set oFSO = CreateObject("Scripting.FileSystemObject")
        Dim oFile: Set oFile = oFSO.GetFile(strPath)
    
        If IsNull(oFile) Then MsgBox ("File not found: " & strPath): Exit Function
    
        With oFile.OpenAsTextStream()
            ReadBinaryFile = .Read(oFile.Size)
            .Close
        End With
    End Function
    

提交回复
热议问题