Google Script загрузит файл для комментирования в Basecamp Classi c API - PullRequest
0 голосов
/ 16 февраля 2020

ОБНОВЛЕНИЕ !!! Я обновил код рабочей версией, чтобы помочь кому-либо еще

Подсказка: обновите и сохраните файл на диске 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;
}
...