Tcl
Tcl
Xero Get Attachment (Download a Xero Attachment)
Demonstrates how to get the content of an attachment in Xero.Note: This example requires Chilkat v9.5.0.64 or greater.
Chilkat Tcl Downloads
load ./chilkat.dll
set success 0
# Note: Requires Chilkat v9.5.0.64 or greater.
# This requires the Chilkat API to have been previously unlocked.
# See Global Unlock Sample for sample code.
set rest [new_CkRest]
# Before sending REST API calls, the REST object needs to be
# initialized for OAuth1.
# See Xero 2-Legged OAuth1 Setup for sample code.
# Assuming the REST object's OAuth1 authenticator is setup, and the initial
# connection was made, we may now send REST HTTP requests..
# --------------------------------------------------------------
# First get a list of attachments for a given document (in this case a Receipt).
set endPoint "Receipts"
set receiptID "c4f40e59-c390-0001-caff-ce731c707d00"
set sbPath [new_CkStringBuilder]
CkStringBuilder_Append $sbPath "/api.xro/2.0/{Endpoint}/{Guid}/Attachments/"
set numReplaced [CkStringBuilder_Replace $sbPath "{Endpoint}" $endPoint]
set numReplaced [CkStringBuilder_Replace $sbPath "{Guid}" $receiptID]
set responseXml [CkRest_fullRequestNoBody $rest "GET" [CkStringBuilder_getAsString $sbPath]]
if {[CkRest_get_LastMethodSuccess $rest] != 1} then {
puts [CkRest_lastErrorText $rest]
delete_CkRest $rest
delete_CkStringBuilder $sbPath
exit
}
# A 200 response is expected for actual success.
if {[CkRest_get_ResponseStatusCode $rest] != 200} then {
puts "$responseXml"
delete_CkRest $rest
delete_CkStringBuilder $sbPath
exit
}
# Examine the response.
puts "$responseXml"
# A sample response looks like this:
# <Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
# <Id>b235646f-34ac-4b15-90ce-d63267f7cd33</Id>
# <Status>OK</Status>
# <ProviderName>ChilkatPrivate</ProviderName>
# <DateTimeUTC>2016-11-11T14:32:17.0908971Z</DateTimeUTC>
# <Attachments>
# <Attachment>
# <AttachmentID>0edcddc8-325f-40c7-b950-8c71f14afc7c</AttachmentID>
# <FileName>penguins.jpg</FileName>
# <Url>http://api.xero.com/api.xro/2.0/Receipts/c4f40e59-c390-0001-caff-ce731c707d00/Attachments/penguins.jpg</Url>
# <MimeType>image/jpg</MimeType>
# <ContentLength>777835</ContentLength>
# </Attachment>
# <Attachment>
# <AttachmentID>0adffdc8-325f-65c7-b950-4391f14af908</AttachmentID>
# <FileName>starfish.jpg</FileName>
# <Url>http://api.xero.com/api.xro/2.0/Receipts/c4f40e59-c390-0001-caff-ce731c707d00/Attachments/starfish.jpg</Url>
# <MimeType>image/jpg</MimeType>
# <ContentLength>24537</ContentLength>
# </Attachment>
# </Attachments>
# </Response>
set xml [new_CkXml]
CkXml_LoadXml $xml $responseXml
# Iterate over the attachments and download each.
set numRecords [CkXml_NumChildrenAt $xml "Attachments"]
puts "Number of Attachments = $numRecords"
set sbSaveFilePath [new_CkStringBuilder]
set sbAttachmentPath [new_CkStringBuilder]
set attachmentData [new_CkBinData]
set i 0
while {$i < $numRecords} {
CkXml_put_I $xml $i
set attachmentID [CkXml_getChildContent $xml "Attachments|Attachment[i]|AttachmentID"]
set filename [CkXml_getChildContent $xml "Attachments|Attachment[i]|FileName"]
puts "AttachmentID: $attachmentID"
puts "Filename: $filename"
puts "----"
# Download this attachment.
# First build the path for this particular attachment by appending the FileName to the path used to get the list of attachments.
CkStringBuilder_Clear $sbAttachmentPath
CkStringBuilder_AppendSb $sbAttachmentPath $sbPath
CkStringBuilder_Append $sbAttachmentPath $filename
# Send the GET request in one call, and then get the response in the next two.
set success [CkRest_SendReqNoBody $rest "GET" [CkStringBuilder_getAsString $sbAttachmentPath]]
if {$success != 1} then {
puts [CkRest_lastErrorText $rest]
delete_CkRest $rest
delete_CkStringBuilder $sbPath
delete_CkXml $xml
delete_CkStringBuilder $sbSaveFilePath
delete_CkStringBuilder $sbAttachmentPath
delete_CkBinData $attachmentData
exit
}
# Get the response header. If it's not a 200 success status code, then the response body does NOT contain
# the attachment data.
set statusCode [CkRest_ReadResponseHeader $rest]
if {$statusCode == -1} then {
# We didn't get any response..
puts [CkRest_lastErrorText $rest]
delete_CkRest $rest
delete_CkStringBuilder $sbPath
delete_CkXml $xml
delete_CkStringBuilder $sbSaveFilePath
delete_CkStringBuilder $sbAttachmentPath
delete_CkBinData $attachmentData
exit
}
if {$statusCode != 200} then {
puts "Response Status: $statusCode"
set responseBody [CkRest_readRespBodyString $rest]
if {[CkRest_get_LastMethodSuccess $rest] != 1} then {
puts "Failed to read the response body."
} else {
puts "$responseBody"
}
puts "Failed."
delete_CkRest $rest
delete_CkStringBuilder $sbPath
delete_CkXml $xml
delete_CkStringBuilder $sbSaveFilePath
delete_CkStringBuilder $sbAttachmentPath
delete_CkBinData $attachmentData
exit
}
# OK, the response header indicates the attachment content is forthcoming...
# There are a few ways to get the response body. If it is a very large attachment, it can be streamed directly
# to a file. We'll assume it's not, so we'll get the response into a BinData object, and then save it to a file.
CkBinData_Clear $attachmentData
set success [CkRest_ReadRespBd $rest $attachmentData]
if {$success != 1} then {
puts [CkRest_lastErrorText $rest]
delete_CkRest $rest
delete_CkStringBuilder $sbPath
delete_CkXml $xml
delete_CkStringBuilder $sbSaveFilePath
delete_CkStringBuilder $sbAttachmentPath
delete_CkBinData $attachmentData
exit
}
# Save the data to the file.
CkStringBuilder_SetString $sbSaveFilePath "qa_output/"
CkStringBuilder_Append $sbSaveFilePath $filename
set success [CkBinData_WriteFile $attachmentData [CkStringBuilder_getAsString $sbSaveFilePath]]
if {$success != 1} then {
puts "Failed to save to output file."
} else {
puts "Saved to [CkStringBuilder_getAsString $sbSaveFilePath]"
}
set i [expr $i + 1]
}
delete_CkRest $rest
delete_CkStringBuilder $sbPath
delete_CkXml $xml
delete_CkStringBuilder $sbSaveFilePath
delete_CkStringBuilder $sbAttachmentPath
delete_CkBinData $attachmentData