- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这似乎是 SendGrid Web API 和电子邮件附件的一个常见问题。我在网络上发现了很多帖子,他们都遇到了同样的问题……但似乎没有一个能得到解决方案。 SendGrid 自己的 jar 头回应是使用他们的库之一......但问题仍然是当您使用没有库的语言时如何附加文件。
我已经尝试就此问题联系 SendGrid 支持人员……甚至提出支付支持费用以获得答案,但他们认为我要求的是“代码审查”,但我没有。问题很简单:将附件上传到 SendGrid Web API 需要什么。
我以前只是在建议的 API 格式中提供文件位置,如下所示:Previous Example of Posting to SendGrid Using VBA这对我自己和其他几个人来说似乎工作了一段时间......但最近有些事情发生了变化。提供简单的文件路径似乎不再有效。那我现在需要做什么?我应该对文件进行编码吗?如果是这样,我应该使用 base64 什么编码?我和其他许多人将不胜感激!
这是我的 base64 尝试,但它与我之前的文件路径尝试有同样的问题,即附件显示在电子邮件中......但它无法打开。
Private Sub SendEmail()
Dim rs As DAO.Recordset
Dim SQL As String
Dim byteData() As Byte
Dim xmlhttp As Object
Dim eTo As String
Dim eFrom As String
Dim eBody As String
Dim eSubject As String
Dim eToName As String
Dim HttpReq As String
Dim ePass As String
Dim eUser As String
Dim strXML As String
Dim strAttachments As String
Dim strBase64 As String
eSubject = Me.txtSubject
eBody = Me.txtMessage
eFrom = SenderEmail
eUser = SendGridUser
ePass = SendGridPass
' If Groups List/ Else Contacts List
If Me.chkGroups <> 0 Then
SQL = "SELECT * FROM qryContactsInSelectedGroups WHERE ContactType = 'Email'"
Else
SQL = "SELECT * FROM qrySelectedContacts WHERE ContactType = 'Email'"
End If
Set rs = CurrentDb.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
Do Until rs.EOF = True
eTo = rs.Fields("ContactValue").Value
eToName = rs.Fields("FirstName").Value & " " & rs.Fields("LastName").Value
' Set the Server URL to the form input
HttpReq = "https://api.sendgrid.com/api/mail.send.xml?" _
& "api_user=" & eUser _
& "&api_key=" & ePass _
& "&to=" & eTo _
& "&toname=" & eToName _
& "&subject=" & eSubject _
& "&text=" & eBody _
& "&from=" & eFrom _
& GetAttachments()
' files[file1.jpg]=file1.jpg&files[file2.pdf]=file2.pdf
Set xmlhttp = CreateObject("MSXML2.XMLHTTP")
' adoStream.Position = 0
xmlhttp.Open "POST", HttpReq, False
xmlhttp.send
byteData = xmlhttp.responseBody
Set xmlhttp = Nothing
strXML = StrConv(byteData, vbUnicode)
Call EmailResponse(strXML, rs.Fields("ContactID").Value)
Debug.Print strXML
rs.MoveNext
Loop
End If
Set rs = Nothing
End Sub
Private Function GetAttachments() As String
Dim rs As DAO.Recordset
Dim SQL As String
Dim currentAttachment As String
Dim strAttachments As String
Dim Encoded64 As String
SQL = "SELECT * FROM tblMessageAttachments WHERE [MessageID] = " & MessageID
Set rs = CurrentDb.OpenRecordset(SQL, dbOpenDynaset, dbSeeChanges)
If Not (rs.EOF And rs.BOF) Then
rs.MoveFirst
Do Until rs.EOF = True
' Set Current Attachment
currentAttachment = rs.Fields("AttachmentLocation").Value & rs.Fields("AttachmentName").Value
Encoded64 = EncodeFile(currentAttachment)
strAttachments = strAttachments & "&files" & Chr(91) & rs.Fields("AttachmentName").Value & Chr(93) & "=" & Encoded64 'currentAttachment
'strAttachments = strAttachments & Encoded64
' Debug.Print strAttachments
rs.MoveNext
Loop
Debug.Print strAttachments
GetAttachments = strAttachments
End If
End Function
Private Function EncodeFile(text As String) As String
Dim arrData() As Byte
arrData = StrConv(text, vbFromUnicode)
Dim objXML As MSXML2.DOMDocument
Dim objNode As MSXML2.IXMLDOMElement
Set objXML = New MSXML2.DOMDocument
Set objNode = objXML.createElement("b64")
objNode.DataType = "bin.base64"
objNode.nodeTypedValue = arrData
EncodeFile = Replace(objNode.text, vbLf, "")
Set objNode = Nothing
Set objXML = Nothing
End Function
最佳答案
这段代码有一些额外的代码和逻辑来附加多个附件:
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
关于ms-access - 使用 API (VBA) 的 SendGrid 附件为空或损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35423101/
SendGrid的automated security通过 CNAME 记录自动化 SPF 和 DKIM。它甚至允许直接使用域注册商拥有我们自己的 SPF 和 DKIM 记录。 他们如何在不串通现有
通过 SendGrid 发送事务性 API。我的模板(从 Mailchimp 移植过来)有条件(例如 *|IF:SHOWTHISSECTION|* 在 Mailchimp 语法中)。这包括或排除基于变
SendGrid 是否支持双重选择加入列表作为一项功能,还是我们必须自己实现? https://sendgrid.api-docs.io/v3.0/contacts-api-recipients/ad
我已完成 Exim 的 SendGrid 集成说明 (http://docs.sendgrid.com/documentation/get-started/integrate/examples/exi
我正在尝试更新我的 SendGrid 联系人,但无法弄清楚为什么我尝试更新我的联系人的自定义字段不起作用。我的保留字段(名字、姓氏、电子邮件)更新,但我的自定义字段没有。任何想法为什么? 此处的文档:
我一直在尝试使用 API 检索 SendGrid 事务模板列表。我使用正确的 API key 并得到一个空数组,而我的 SendGrid 帐户中存在大约 5 个事务模板。这是响应: { "temp
是否可以配置发送网格帐户,我可以指定多个 Post Event URL 事件通知。或者是否可以添加多个事件通知应用程序? 最佳答案 目前无法将 Events Webhook POST 事件发送到多个
我正在尝试将以下脚本添加到 sendgrid 模板 { "@context": "http://schema.org", "@type": "EmailMessage", "potent
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 3个月前关闭。 Improve th
SendGrid 中的版本控制允许 API 客户端仅通过记录的模板 ID 发出模板请求 here ,但是,一次只能“激活”一个模板版本。显然,用于我们的生产应用程序的模板需要始终设置为事件状态,但是如
我正在使用 Svelte 和 SendGrid 制作一个联系表单。这是一个基本的 app.svelte: import sgMail from '@sendgrid/mail'; s
有人可以帮助我了解 SendGrid 实际上添加到应用程序架构中的内容吗?它的作用真的像替代传送引擎 (SMTP) 和发送后分析一样有限吗?我希望它能为交易电子邮件做更多的事情,但我看到/读到的所有内
正如 Sendgrid 的文档明确指出的,他们的 Web GUI 事件页面只能搜索过去 7 天的内容。 如何搜索更早以前的事件? Web API documentation is here ,但我找不
正如 Sendgrid 的文档明确指出的,他们的 Web GUI 事件页面只能搜索过去 7 天的内容。 如何搜索更早以前的事件? Web API documentation is here ,但我找不
我可以从 web app 获取 API key 。但是,根据 SendGrid 文档,我只被允许访问整个 key 的一小部分。 如果您看到下面的 API key 示例: SG.ngeVfQFYQlKU
我正在使用 sendgrid API 向多个收件人发送电子邮件! addTo(array('first@mail.com','second@mail.com'..)) ->setFrom('m
我使用以下方式发送电子邮件:https://github.com/sendgrid/sendgrid-nodejs/tree/master/packages/mail 我一直无法找到如何添加 Unsu
我正在通过 SendGrid 从 Azure Webjob (C#) 发送电子邮件。我没有看到任何在邮件 header 中添加返回路径的选项。可能吗? 最佳答案 默认情况下,SendGrid 控制返回
任何人都可以帮我解决这个问题。我想在 Excel 中跟踪用户事件,关于他们的打开、点击状态。我可以在 UI 门户中看到它们。是否有导出为 CSV 的选项? 提前致谢。 百色 最佳答案 查看 Keen
我正在使用 sendgrid 发送电子邮件。但是当我尝试按如下方式创建电子邮件对象时 let email = new sendgrid.Email(); email.addTo("rhushikesh
我是一名优秀的程序员,十分优秀!