通过 UrlFetchApp 创建带有来自 Google 应用程序脚本附件的 Freshdesk 票证
Create Freshdesk Ticket with attachment from Google App Script by UrlFetchApp
我尝试使用 google 应用程序脚本通过 freshdesk API 创建带有附件的工单。
Freshdesk 在此处有 google 应用程序脚本示例代码:https://github.com/freshdesk/fresh-samples/tree/master/google_script,但没有附件演示。
我尝试了以下代码,但似乎总是 return 错误 /helpdesk/tickets.json api.
如何使用 UrlFetchApp 在 google 应用程序脚本中 post 附件?
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: "test@test.com"
, 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()
)
}
使用 nc 进行调试后:
nc -l 211.99.222.55 3333
我发现 payload 数组应该这样写:
var payload = {
'helpdesk_ticket[description]': 'test jjjj'
, 'helpdesk_ticket[subject]': 'test jj'
, 'helpdesk_ticket[email]': 'test@test.com'
, 'helpdesk_ticket[attachments][][resource]': fileBlob1
, 'helpdesk_ticket[attachments][][resource]': fileBlob2
}
但是 fileBlob2 不会 post 到服务器,因为数组的键是重复的。我试图将 'helpdesk_ticket[attachments][][resource]' 更改为 'helpdesk_ticket[attachments][1][resource]' 但它没有用。
所以这是一个可行的版本,它只支持单个附件:
function createTicket() {
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]': 'test@test.com'
, 'helpdesk_ticket[attachments][][resource]': fileBlob1
, 'helpdesk_ticket[attachments][][resource]': fileBlob2
}
//
// for (var i=0; i<attachments.length; i++) {
// payload['helpdesk_ticket[attachments][][resource]'] = attachments[i]
// }
//
// for (var k in payload) {
// Logger.log('%s = %s', k, payload[k])
// }
var options = {
'method': 'post'
, '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()
)
}
2016 年 1 月 20 日更新
我在gas中为freshdesk v2 api写了一个名为GasFreshdesk的库,非常好用(支持附件):
var MyFreshdesk = new GasFreshdesk('https://domain.freshdesk.com', 'TOKEN')
var ticket = new MyFreshdesk.Ticket({
description:'A description'
, subject: 'A subject'
, email: 'you@example.com'
, 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: ['you@example.com']
, 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
旧 POST:
最后,google 应用程序脚本可以通过 UrlFetchApp.fetch 将多个附件附加到 freshdesk 上的新工单,使用我自己手工制作的 'multipart' 参数生成器辅助函数。
将附件放在另一个数组有效负载中:
var 负载 = [
['helpdesk_ticket[description]', 'test jjjj']
, ['helpdesk_ticket[subject]', 'test jj']
, ['helpdesk_ticket[email]', 'test@test.com']
, ['helpdesk_ticket[attachments][][resource]', fileBlob2]
, ['helpdesk_ticket[attachments][][resource]', fileBlob1]
]
使用makeMultipartBody函数生成一个requestBody:
var multipartBody = makeMultipartBody(有效载荷)
完整代码在这里:
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]', 'test@test.com']
, ['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
}
我尝试使用 google 应用程序脚本通过 freshdesk API 创建带有附件的工单。
Freshdesk 在此处有 google 应用程序脚本示例代码:https://github.com/freshdesk/fresh-samples/tree/master/google_script,但没有附件演示。
我尝试了以下代码,但似乎总是 return 错误 /helpdesk/tickets.json api.
如何使用 UrlFetchApp 在 google 应用程序脚本中 post 附件?
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: "test@test.com"
, 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()
)
}
使用 nc 进行调试后:
nc -l 211.99.222.55 3333
我发现 payload 数组应该这样写:
var payload = {
'helpdesk_ticket[description]': 'test jjjj'
, 'helpdesk_ticket[subject]': 'test jj'
, 'helpdesk_ticket[email]': 'test@test.com'
, 'helpdesk_ticket[attachments][][resource]': fileBlob1
, 'helpdesk_ticket[attachments][][resource]': fileBlob2
}
但是 fileBlob2 不会 post 到服务器,因为数组的键是重复的。我试图将 'helpdesk_ticket[attachments][][resource]' 更改为 'helpdesk_ticket[attachments][1][resource]' 但它没有用。
所以这是一个可行的版本,它只支持单个附件:
function createTicket() {
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]': 'test@test.com'
, 'helpdesk_ticket[attachments][][resource]': fileBlob1
, 'helpdesk_ticket[attachments][][resource]': fileBlob2
}
//
// for (var i=0; i<attachments.length; i++) {
// payload['helpdesk_ticket[attachments][][resource]'] = attachments[i]
// }
//
// for (var k in payload) {
// Logger.log('%s = %s', k, payload[k])
// }
var options = {
'method': 'post'
, '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()
)
}
2016 年 1 月 20 日更新
我在gas中为freshdesk v2 api写了一个名为GasFreshdesk的库,非常好用(支持附件):
var MyFreshdesk = new GasFreshdesk('https://domain.freshdesk.com', 'TOKEN')
var ticket = new MyFreshdesk.Ticket({
description:'A description'
, subject: 'A subject'
, email: 'you@example.com'
, 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: ['you@example.com']
, 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
旧 POST:
最后,google 应用程序脚本可以通过 UrlFetchApp.fetch 将多个附件附加到 freshdesk 上的新工单,使用我自己手工制作的 'multipart' 参数生成器辅助函数。
将附件放在另一个数组有效负载中:
var 负载 = [ ['helpdesk_ticket[description]', 'test jjjj'] , ['helpdesk_ticket[subject]', 'test jj'] , ['helpdesk_ticket[email]', 'test@test.com'] , ['helpdesk_ticket[attachments][][resource]', fileBlob2] , ['helpdesk_ticket[attachments][][resource]', fileBlob1] ]
使用makeMultipartBody函数生成一个requestBody:
var multipartBody = makeMultipartBody(有效载荷)
完整代码在这里:
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]', 'test@test.com']
, ['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
}