Search code examples
google-apps-scripturlfetchfreshdesk

Create Freshdesk Ticket with attachment from Google App Script by UrlFetchApp


I try to use google apps script to create ticket with attachments via freshdesk API.

Freshdesk have google app script sample code here: https://github.com/freshdesk/fresh-samples/tree/master/google_script , but without attachment demo.

I tried the following code, but it seems always return error by /helpdesk/tickets.json api.

how to post a attachment in google app script with UrlFetchApp right?

function createFreshdeskTicketWithAttachments() {

 var API_KEY = PropertiesService.getScriptProperties().getProperty('FreshDeskApiKey')
  if (!API_KEY) throw new Error('FreshDeskApiKey not found in script properties.')

  var ENDPOINT = Utilities.formatString('https://%s.freshdesk.com', 'zixia')

  var headers = {
    'Authorization': 'Basic ' + Utilities.base64Encode(API_KEY + ':X')
    , 'Content-type': 'application/json'
    //'Content-type': 'multipart/form-data'
  };

  var response = UrlFetchApp.fetch("https://circleci.com/gh/AKAMobi/ucapp/tree/master.svg?style=svg")
  var fileBlob = response.getBlob()
  Logger.log("%s:%s"
             , response.getResponseCode()
             , fileBlob.getContentType()
            )

  var payload = {
    helpdesk_ticket: {
      description: 'TEST 4'
      , subject: "TEST 4"
      , email: "[email protected]"
      , priority: 1
      , status: 2
      , attachments: { '': [ { resource: fileBlob } ] }
    }
  } 

  //Adds the extensions that are needed to post a new ticket to the end of the url
  var url = ENDPOINT + '/helpdesk/tickets.json';

  var options = {
    'method': 'post',
    'headers': headers,
    'payload': JSON.stringify(payload),
//    'payload': payload,
    muteHttpExceptions: true
  };

  var response = UrlFetchApp.fetch(url, options);

  Logger.log('resp: %s, %s'
             , response.getResponseCode()
             , response.getContentText()
            )

}

Solution

  • UPDATE Jan 20th, 2016

    I wrote a library named GasFreshdesk for freshdesk v2 api in gas, which is very easy to use(with attachments support):

    var MyFreshdesk = new GasFreshdesk('https://domain.freshdesk.com', 'TOKEN')
    
    var ticket = new MyFreshdesk.Ticket({
      description:'A description'
      , subject: 'A subject'
      , email: '[email protected]'
      , attachments: [ 
        Utilities.newBlob('TEST DATA').setName('test-data.dat')
        , Utilities.newBlob('TEST DATA2').setName('test-data2.dat')
      ]
    })
    
    ticket.assign(9000658396)
    ticket.note({
      body: 'Hi tom, Still Angry'
      , private: true
      , attachments: [ 
        Utilities.newBlob('TEST DATA').setName('test-data.dat')
        , Utilities.newBlob('TEST DATA2').setName('test-data2.dat')
      ]
    })
    ticket.reply({
      body: 'Hi tom, Still Angry'
      , cc_emails: ['[email protected]']
      , attachments: [ 
        Utilities.newBlob('TEST DATA').setName('test-data.dat')
        , Utilities.newBlob('TEST DATA2').setName('test-data2.dat')
      ]
    })
    ticket.setPriority(2)
    ticket.setStatus(2)
    
    ticket.del()
    ticket.restore()
    
    Logger.log('ticket #' + ticket.getId() + ' was set!')
    

    GasFreshdesk Github: https://github.com/zixia/gas-freshdesk

    OLD POST:

    finnaly, google apps script could attach multi attachments to new ticket on freshdesk by UrlFetchApp.fetch, with a hand made 'multipart' param generator helper function by myself.

    1. put attachments in another array payload:

      var payload = [ ['helpdesk_ticket[description]', 'test jjjj'] , ['helpdesk_ticket[subject]', 'test jj'] , ['helpdesk_ticket[email]', '[email protected]'] , ['helpdesk_ticket[attachments][][resource]', fileBlob2] , ['helpdesk_ticket[attachments][][resource]', fileBlob1] ]

    2. use makeMultipartBody function to generate a requestBody:

      var multipartBody = makeMultipartBody(payload)

    full code here:

    function createTicket2() {
    
      var API_KEY = PropertiesService.getScriptProperties().getProperty('FreshDeskApiKey')
      if (!API_KEY) throw new Error('FreshDeskApiKey not found in script properties.')
    
      var ENDPOINT = Utilities.formatString('https://%s.freshdesk.com', 'zixia')
    
      var headers = {
        'Authorization': 'Basic ' + Utilities.base64Encode(API_KEY + ':X')
      }
    
        var response = UrlFetchApp.fetch("https://circleci.com/gh/AKAMobi/ucapp/tree/master.svg?style=svg")
      var fileBlob1 = response.getBlob()
    
      var fileBlob2 = UrlFetchApp
      .fetch("http://imgcache.qq.com/open_proj/proj_qcloud_v2/qcloud_2015/css/img/global/internet-plus.png")
      .getBlob()
    
      var payload = [
        ['helpdesk_ticket[description]', 'test jjjj']
        , ['helpdesk_ticket[subject]', 'test jj']
        , ['helpdesk_ticket[email]', '[email protected]']
        , ['helpdesk_ticket[attachments][][resource]', fileBlob2]
        , ['helpdesk_ticket[attachments][][resource]', fileBlob1]
      ]
    
      var boundary = '-----CUTHEREelH7faHNSXWNi72OTh08zH29D28Zhr3Rif3oupOaDrj'
    
      payload = makeMultipartBody(payload, boundary)
    
      //Logger.log('payload: %s', payload)
      //return
    
      var options = {
        'method': 'post'
        , contentType: "multipart/form-data; boundary=" + boundary
        , 'headers': headers
        , 'payload': payload
        , muteHttpExceptions: true
      }
    
      var url = ENDPOINT + '/helpdesk/tickets.json'
    //  url = 'http://211.99.222.55:3333'
      var response = UrlFetchApp.fetch(url, options)
    
      Logger.log('resp: %s, %s'
                 , response.getResponseCode()
                 , response.getContentText()
                )    
    }
    
    
    function makeMultipartBody(payload, boundary) {
    
      var body = Utilities.newBlob('').getBytes()
      Logger.log(payload)
    
      for (var i in payload) {
        var [k, v] = payload[i]
    
        Logger.log('############ %s = %s', k, v)
    
        if (v.toString() == 'Blob') {
    
          // attachment
          body = body.concat(
            Utilities.newBlob(
              '--' + boundary + '\r\n'
              + 'Content-Disposition: form-data; name="' + k + '"; filename="' + v.getName() + '"\r\n'
            + 'Content-Type: ' + v.getContentType() + '\r\n\r\n'
          ).getBytes())
    
          body = body
          .concat(v.getBytes())
          .concat(Utilities.newBlob('\r\n').getBytes())
    
        } else {
    
          // string
          body = body.concat(
            Utilities.newBlob(
              '--'+boundary+'\r\n'
              + 'Content-Disposition: form-data; name="' + k + '"\r\n\r\n'
              + v + '\r\n'
            ).getBytes()
          )
    
        }
    
      }
    
      body = body.concat(Utilities.newBlob("\r\n--" + boundary + "--\r\n").getBytes())
    
      return body
    
    }