ОБНОВЛЕНИЕ !!! Я обновил код рабочей версией, чтобы помочь кому-либо еще
Подсказка: обновите и сохраните файл на диске Google, чтобы убедиться, что файл действителен и не поврежден
при попытке добавить файл к комментарию как вложение, в комментарии есть вложение, но на миниатюре написано «извините, но это изображение кажется поврежденным». мой процесс
- выберите файл (ы), используя html input type = "file" и отправьте форму в google.script.run.withSuccessHandler (updateStatusServerAfter) .updateStatusServer (formData)
- добавление файлов с помощью URL-адреса выгрузки, это работает, поскольку я получаю возвращенный идентификатор
- обновите комментарий, указав идентификатор файла, полученный при загрузке
HTML
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
</head>
<body>
<input id="image-file" type="file" onchange="SavePhoto(this)" multiple>
<br><br>
</body>
<script>
function SavePhoto(inp)
{
var d={fileCount:0}
let files= inp.files;
const r = Promise.all([...files.files].map((file, i) => {
const fr = new FileReader();
return new Promise((r) => {
fr.onload = (e) => {
const data = e.target.result.split(",");
return r({fileName: files.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]});
}
fr.readAsDataURL(file);
});
}))
.then((obj) => {
d.fileCount=obj.length;
console.log('calling updateStatusServer d:'+JSON.stringify(d));
d.files=obj
d.startTS=new Date().toISOString();
google.script.run.withSuccessHandler(updateStatusServerAfter).updateStatusServer(d)
});
}
function updateStatusServerAfter(dataReturned) {
console.log('updateStatusServerAfter dataReturned: ' + dataReturned);
console.log('updateStatusServerAfter typeof dataReturned: ' + typeof dataReturned);
}
</script>
</html>
Код для добавления файла в базовый лагерь
function CallBasecampAPI(urlIn,opt) {
if (!username || !password || !url) {
throw ('username, password and url must be initialized before calling the wrapper script functions')
}
if (url.slice(-1) !='/') url+='/';
var furl=url + urlIn;
var response;
var headers = {
'Authorization': 'Basic ' + Utilities.base64Encode(username + ':' + password),
'Content-Type': 'application/xml',
'Accept': 'application/xml',
'validateHttpsCertificates': false,
'muteHttpExceptions': false,
}
if (opt==undefined) opt={}
opt.headers=headers
var response;
response = UrlFetchApp.fetch(furl, opt)
AllHeaders=response.getAllHeaders()
ResponseCode=response.getResponseCode()
var responseX=response.getContentText();
return responseX;
}
function updateStatusServer(theForm) {
//works - must refresh a couple of times to see changes
//console.log('updateStatusServer theForm:'+JSON.stringify(theForm));
//HtmlContentsWrite('updateStatusServer.JSON',JSON.stringify(theForm))
var stTime=new Date()
var files= theForm.files;
var tsx=new Date().toISOString()
var a=''
var fa=[]
for (var i=0; i< files.length; i++) {
var obj=files[i];
var name=obj.fileName
var MimeType=obj.mimeType
console.log('updateStatusServer:'+name+' '+MimeType);
var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
var content=blob.getBytes()
var opt = {
'contentType': 'application/octet-stream',
'method': 'POST',
"payload": content,
// 'body': content,
'muteHttpExceptions': true
};
var myurl = 'upload';
console.log('processing url '+myurl);
var response = CallBasecampAPI(myurl,opt);
var parsedresponse = XmlService.parse(response);
var fileId=parsedresponse.getRootElement().getChild('id').getText();
console.log('file response:'+response);
var x='<attachment><name>'+name+'</name><file><file>'+fileId+'</file><content-type>'+MimeType+'</content-type><original-filename>'+name+'</original-filename></file></attachment>'
a+=x;
fa.push(name);
elapsedTime(stTime,'add file '+name)
}
elapsedTime(stTime,'after add all files')
//update comment
var nl={ts:tsx,fileCount:theForm.fileCount};
nl.files=fa.join(',');
var commentH=GetStatusComment(usId); //this gets the comment you want to append to
elapsedTime(stTime,'after GetStatusComment')
var commentNode=commentH.commentItem;
var commentId=commentH.commentId;
var statusCommentXML=commentH.statusCommentXML;
var att= commentNode.getChild('attachments');
var body= commentNode.getChild('body').getText()
var nlx=JSON.stringify(nl)
console.log('body new line:'+nlx);
var nb='<div>'+nlx+'</div>';
body='<![CDATA['+body+nb+']]>'
var attX=XmlService.getRawFormat().format(att);
console.log('attachments before:'+attX);
if (attX=='<attachments type="array" />') {
var attOut='<attachments>'+a+'</attachments>'
} else {
var attOut=attX.replace('</attachments>',a+'</attachments>')
}
console.log('attachments after:'+attOut);
var xml='<comment><id type="integer">'+commentId+'</id><body>'+body+'</body>'+attOut+'</comment>'
//PUT /comments/#{id}.xml
var opt = {
'contentType': 'application/xml',
'method': 'PUT',
'payload': xml,
'muteHttpExceptions': true
};
var myurl = 'comments/' + commentId + '.xml'
console.log('processing url '+myurl+' xml:\n'+xml);
var response = CallBasecampAPI(myurl,opt);
console.log(myurl+' response:'+response);
var m="."
if (files.length>0) {
m=" and "+files.length+' files loaded.';
}
elapsedTime(stTime,'end')
return 'Status Updated'+m;
}