Home > other >  create JSON using JSONCOVERTER
create JSON using JSONCOVERTER

Time:11-18

I am wondering to create a json from VBA Outlook to export email as ticket on Osticket System Everithing working well except when there's multiple attachments

I need to have this syntax

{
 "alert": "true",
 "autorespond": "true",
 "source": "API",
 "name": "Angy User",
 "email": "[email protected]",
 "subject": "Help",
 "topicId": "1",
 "message": "data:text/html,</body></html>Please Help</body></html>",
 "attachments": [
  {   "MyFile.png": "data:image/png;base64,JVBERi0........."  },
  {   "MyFile.png": "data:image/png;base64,JVBERi0........."  },
 ]
}

But using my code i get this

{
 "alert": "true",
 "autorespond": "true",
 "source": "API",
 "name": "Angy User",
 "email": "[email protected]",
 "subject": "Help",
 "topicId": "1",
 "message": "data:text/html,</body></html>Please Help</body></html>",
 "attachments": [
  {   "MyFile.png": "data:image/png;base64,JVBERi0.........",  
      "MyFile.png": "data:image/png;base64,JVBERi0........."  },
 ]
}

I use this to create the json

   Dim Body As New Dictionary

   
   Body.Add "alert", "true"
   Body.Add "autorespond", "true"
   Body.Add "source", "API"
   Body.Add "name", myMsg.SenderName
   Body.Add "email", FromAddress
   Body.Add "subject", myMsg.Subject
   Body.Add "topicId", CStr(rubriq)
   Body.Add "message", "data:text/html," & strData 'myMsg.HTMLBody
   Body.Add "attachments", Array(Attm1) 'attachments
   
   Dim json As String
   json = JsonConverter.ConvertToJson(Body, Whitespace:=" ")

Where the Attm1 is a dictionary filled in FOR loop

Attm1.Add oFile.FileName, "data:" & _
    oFile.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_TYPE) & _
    ";" & "base64," & n.nodeTypedValue

I used this function

https://github.com/VBA-tools/VBA-JSON

The loop code

      Dim attachments As New Collection

   
 
   If myMsg.attachments.Count > 0 Then
      
      Set fs = CreateObject("Scripting.FileSystemObject")
            
      Set nAtt = xmlTicket.createElement("attachments")
      nodeTicket.appendChild nAtt
      
      For i = 1 To myMsg.attachments.Count
         Set oFile = myMsg.attachments.Item(i)
         
         'I only add attachments up to a limit in size
         If oFile.Size <= MAX_ATTACHMENT Then
            sTmpFile = fs.GetTempName
            oFile.SaveAsFile sTmpFile
            
                     
            'Attachment data is always base64-coded
            n.dataType = "bin.base64"
                     
            'The ADODB.Stream tweak allows to read binary files
            Set data = CreateObject("ADODB.Stream")
            data.Type = 1 'Binary
            data.Open
            data.LoadFromFile sTmpFile
            'MSXML will base64-code it for us
            n.nodeTypedValue = data.Read
            
            'Using the bin.base64 structure means adding namespace'd attributes.
            'For some reason, osTicket will complain for each extra attribute, so
            'we get to clean up
            n.Attributes.removeNamedItem "dt:dt"
           

            
            'For some reason, getting the content-type is very unclear in Outlook
            Set a = xmlTicket.createAttribute("type")
            a.Value = oFile.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_TYPE)
            n.Attributes.setNamedItem a
  
  
            Dim Attm1 As New Dictionary
            Attm1.Add oFile.FileName, "data:" & oFile.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_TYPE) & ";" & "base64," & n.nodeTypedValue
         
            Kill sTmpFile
            
            
         End If
      Next
       
     
   End If

CodePudding user response:

Try something like this. It's easier to manage if you split out the various jobs into separate methods.

Const MAX_ATTACHMENT As Long = 500000 'or whatever

Sub MainSub()
   Dim Body As Object, dict As Object, i As Long, json As String
   Dim myMsg As Outlook.MailItem
   
   '...
   '...
   Body.Add "attachments", New Collection

   If myMsg.attachments.Count > 0 Then
      For i = 1 To myMsg.attachments.Count
         Set dict = AttachmentDict(myMsg.attachments.Item(i))
         If Not dict Is Nothing Then  'check conversion happened
            Body("attachments").Add dict
         End If
      Next
   End If
   
   json = JsonConverter.ConvertToJson(Body, Whitespace:=" ")
   
   '...
   '...
   
End Sub

'create a dictionary from an attachment if it meets the size limit
Function AttachmentDict(att As Outlook.Attachment)
    Dim dict As Object, fso As Object, sTmpFile As String
    If att.Size < MAX_ATTACHMENT Then
        Set dict = CreateObject("Scripting.Dictionary")
        Set fso = CreateObject("Scripting.FileSystemObject")
        sTmpFile = fso.GetSpecialFolder(2) & "\" & fso.GetTempName
        att.SaveAsFile sTmpFile
        dict.Add att.Filename, "data:" & _
          att.PropertyAccessor.GetProperty(PR_ATTACH_CONTENT_TYPE) & _
          ";" & "base64," & FileToBase64(sTmpFile)
        Set AttachmentDict = dict
    End If
End Function

Function FileToBase64(FilePath As String) As String
    Const adTypeBinary = 1          ' Binary file is encoded
    Dim objXML, objDocElem, objStream
    ' Open data stream from file
    Set objStream = CreateObject("ADODB.Stream")
    objStream.Type = adTypeBinary
    objStream.Open
    objStream.LoadFromFile FilePath
    Set objXML = CreateObject("MSXml2.DOMDocument")
    Set objDocElem = objXML.createElement("Base64Data")
    objDocElem.DataType = "bin.base64"
    objDocElem.nodeTypedValue = objStream.Read()
    FileToBase64 = objDocElem.Text
End Function
  • Related