Attachment Migration

The API examples all reference a local copy of a file to be uploaded via multipart form. Tried reviewing posts on attachments to see if it’s possible to reference a url or other methods to upload attachments, but wanted to ask what options are available. We migrate a lot of data to and from Freshservice for tickets, solutions, etc. and would be interested in all possibilities migrating data into the platform. There are cases when data is being moved from one Freshservice instance to another Freshservice instance. Freshdesk to Freshservice. Would we need to download all attachments locally and then re-upload them to the new instance? Options? Are there any examples for creating solutions with inline attachments?

Hello Rob I will share an example of how I make multiple attachments in pythom

def prepare_attachments(attachments, path, limit_size= 20000000, limit_total_size= 25000000):
    try:      
        url = None
        files = []
        error = []
        total_size = 0
        for attachment in attachments:                
            file_name = attachment['filename'] if 'filename' in attachment else attachment['name']     
            import_id = uuid.uuid4().int & (1 << 32)-1
            file_path = os.path.join(path, str(import_id) + file_name )    
            url = attachment['url']   
            with requests.get(url, headers=header, stream=True) as r:
                r.raise_for_status()
                with open(file_path, "wb") as f:
                    for chunk in r.iter_content(chunk_size=15000000):
                        f.write(chunk)
            if os.path.getsize(file_path) <= limit_size:
                total_size = total_size + os.path.getsize(file_path)
                if total_size <= limit_total_size:
                    # print("aquii")
                    files.append(
                        (
                            "attachments[]",
                            (
                                file_name,
                                open(file_path, "rb"),
                                None,
                            ),
                        )
                    )
                else: 
                    error.append(attachment)
                    if debug:
                        print("burst the 25mb")
            else:
                error.append(attachment)
                if debug:
                    print("burst the 20mb")

        return {"files": files, "error": error}
    except Exception as e:
        print("erro:", e)
        return None

when you need to make the form data with multiple files it looks something like:
“attachments” = “path1”
“attachments” = “path2”

this is the only way I know of importing via api, in js I know that there is a library that you can download the file in memory and use to send the file directly without necessarily storing it on the machine

Hello @rasimm ,
the API examples on attachments work if you build an app hosted by yourself or anyone that isn’t freshservice, but if you’re trying to build a custom-app with the freshworks cli, this method won’t work.
I found out another method discussed here that consists of sending the attachment as an arraybuffer without downloading it first.

@Michele @Marllon_Mainardes Appreciate the input and examples. Currently using Powershell for most of my client-side operations, here is the module if you are looking for a quick command-line interface for Freshservice:

Not sure what exactly Axios is doing in the library, but I see in my searches that the file needs to be physically there to do a conversion based on comments here:

powershell - How to download a file as a byte stream? - Stack Overflow

Just trying to avoid having to download each attachment, send payload with attachment, delete attachments, move to next ticket approach. We’re migrating tens of thousands of tickets with multiple attachments and having to cache locally is very inefficient. We can work on writing something in a custom app if we can somehow skip the middleware caching.

With javascript you can use unirest to be able to use buffer in memory for these operations

   var   unirest  =  require('unirest');
   update_ticket(args){
	var domain = args.iparams.domain;
	var api_key = args.iparams.api_key;

	var url = `${domain}/api/tickets/${args.id}`;		
	var headersOpt = {  
		"Authorization": "Basic "+base64.encode(`${api_key}:x`)
	};		
	unirest.put(url)
		.headers(headersOpt)
		.attach('attachments[]', args.url_attachment)
		.end(function (response) {
			console.log(response.body);
			if (response.status === 200) {	
				renderData(null,{"body": response.body, "status": response.status});
			}else{
				renderData(null,{"body": response.body, "status": response.status});
			}
		});
}

it is possible to do this with axios too, but I don’t have any ready examples with it to share

1 Like