Search code examples
ibm-connections

IBM Connections API - How to attach files to wiki pages?


In the IBM Connections user interface, it's possible to attach files directly to wiki pages.
I want to attach files to wiki pages programatically, but can't find a documented way to do so.

I've been looking at the Connections 4.5 API documentation here:
http://www-10.lotus.com/ldd/appdevwiki.nsf/xpDocViewer.xsp?lookupName=IBM+Connections+4.5+API+Documentation#action=openDocument&content=catcontent&ct=prodDoc

Looking specifically at the APIs for Files and Wikis, there seems to be nothing about wiki-page attachments. While I'm mainly looking to upload attachments, I can't even see a documented API to retrieve attachments, despite the user-interface having a link to a feed (on each wiki page) that does that.

Is there any (possibly undocumented) API to attach files to a wiki page?


Solution

  • Here is some sample code to show how to do it in a supported way.

    First, you need two URLs.

    private static String apiUrlWikiNonce = "https://sdkdev.swg.usma.ibm.com:444/wikis/basic/api/nonce";
    private static String apiUrlWikiAttachment = "https://sdkdev.swg.usma.ibm.com:444/wikis/form/api/wiki/{WIKI_LABEL_OR_WIKI_UUID}/page/{PAGE_LABEL_OR_PAGE_UUID}/feed";
    

    Get the Nonce

       /**
         * gets the nonce value only valid return type is text, anything else throws
         * an error
         * 
         * @param httpClient
         * @param user
         * @param password
         * @return
         */
        public static String getNonce(CloseableHttpClient httpClient, String user,
                String password) {
            String result = "";
            HttpGet httpGet = new HttpGet(apiUrlWikiNonce);
    
            String combo = user + ":" + password;
            String hash = org.apache.commons.codec.binary.Base64
                    .encodeBase64String(combo.getBytes());
            System.out.println(user + " is logging in with " + hash);
            String auth = "Basic " + hash;
            httpGet.setHeader("Authorization", auth.replace("=", ""));
    
            HttpClientContext context = HttpClientContext.create();
    
            CloseableHttpResponse response = null;
            try {
    
                response = httpClient.execute(httpGet, context);
    
                System.out.println(response.getStatusLine());
                HttpEntity entity = response.getEntity();
    
                InputStream is = entity.getContent();
                StringWriter writer = new StringWriter();
    
                IOUtils.copy(is, writer);
                String responseString = writer.toString();
                // System.out.println(responseString);
    
                result = responseString;
    
                EntityUtils.consume(entity);
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            return result;
        }
    

    Now that you have the nonce such as... b1911872-36f1-4767-956d-214759886406

    Then upload a file with X-Update-Nonce

    /**
         * uploads a file to a given wiki page.
         * 
         * @param httpClient
         * @param user
         * @param password
         * @param wikiLabel
         * @param wikiPage
         * @param file
         * @param nonce
         * @return uuid <empty or uuid of file>
         */
        public static String uploadFileToWiki(CloseableHttpClient httpClient, String user,
                String password, String wikiLabel, String wikiPage, File file, String nonce){
            String uuid = "";
    
            String apiUrl = apiUrlWikiAttachment.replace("{WIKI_LABEL_OR_WIKI_UUID}", wikiLabel);
            apiUrl = apiUrl.replace("{PAGE_LABEL_OR_PAGE_UUID}", wikiPage);
    
            //Mandatory Parameter
            apiUrl += "?category=attachment";
    
    
            System.out.println("API Url : " + apiUrl);
    
            HttpPost post = new HttpPost(apiUrl);
            post.addHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:32.0) Gecko/20100101 Firefox/32.0");
            post.addHeader("Content-Type", "image/png");
    
            String combo = user + ":" + password;
            String hash = org.apache.commons.codec.binary.Base64
                    .encodeBase64String(combo.getBytes());
            System.out.println(user + " is logging in with " + hash);
            String auth = "Basic " + hash;
            post.setHeader("Authorization", auth.replace("=", ""));
    
            HttpClientContext context = HttpClientContext.create();
    
            CloseableHttpResponse response = null;
            try {
                EntityBuilder builder = EntityBuilder.create();
                builder.setFile(file);
                HttpEntity postentity = builder.build();
    
                post.setHeader("Slug","NominalWorkItem-v1.png");
                post.setHeader("title","Test Title");
                post.setHeader("label","Test Test");
    
                post.setEntity(postentity);
    
                response = httpClient.execute(post, context);
    
                System.out.println(response.getStatusLine());
                HttpEntity entity = response.getEntity();
    
                InputStream is = entity.getContent();
                StringWriter writer = new StringWriter();
    
                IOUtils.copy(is, writer);
                String responseString = writer.toString();
                System.out.println(responseString);
    
                uuid = responseString;
    
                EntityUtils.consume(entity);
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
    
            return uuid;
        }
    

    The file is updated, and you get the response code 201 when created, and the XML

    > <?xml version="1.0" encoding="UTF-8"?><entry
    > xmlns:thr="http://purl.org/syndication/thread/1.0"
    > xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"
    > xmlns:snx="http://www.ibm.com/xmlns/prod/sn" xmlns:td="urn:ibm.com/td"
    > xmlns="http://www.w3.org/2005/Atom"><id>urn:lsid:ibm.com:td:7780e11c-7240-41b3-8f0c-00a10ea69c93</id><td:uuid>7780e11c-7240-41b3-8f0c-00a10ea69c93</td:uuid><td:label>NominalWorkItem-v1.png</td:label><link
    > href="https://sdkdev.swg.usma.ibm.com:444/wikis/form/api/wiki/744ccaeb-e9af-434c-9fa6-78831fb94846/page/3b017473-2dbe-4920-85a2-bf908a8e1475/attachment/7780e11c-7240-41b3-8f0c-00a10ea69c93/entry"
    > rel="self"></link><link
    > href="https://sdkdev.swg.usma.ibm.com:444/wikis/form/anonymous/api/wiki/744ccaeb-e9af-434c-9fa6-78831fb94846/page/3b017473-2dbe-4920-85a2-bf908a8e1475/attachment/7780e11c-7240-41b3-8f0c-00a10ea69c93/media/NominalWorkItem-v1.png"
    > rel="alternate"></link><link
    > href="https://sdkdev.swg.usma.ibm.com:444/wikis/form/api/wiki/744ccaeb-e9af-434c-9fa6-78831fb94846/page/3b017473-2dbe-4920-85a2-bf908a8e1475/attachment/7780e11c-7240-41b3-8f0c-00a10ea69c93/entry"
    > rel="edit"></link><link
    > href="https://sdkdev.swg.usma.ibm.com:444/wikis/form/api/wiki/744ccaeb-e9af-434c-9fa6-78831fb94846/page/3b017473-2dbe-4920-85a2-bf908a8e1475/attachment/7780e11c-7240-41b3-8f0c-00a10ea69c93/media"
    > rel="edit-media"></link><link
    > href="https://sdkdev.swg.usma.ibm.com:444/wikis/form/anonymous/api/wiki/744ccaeb-e9af-434c-9fa6-78831fb94846/page/3b017473-2dbe-4920-85a2-bf908a8e1475/attachment/7780e11c-7240-41b3-8f0c-00a10ea69c93/media/NominalWorkItem-v1.png"
    > rel="enclosure" type="image/png" title="NominalWorkItem-v1.png"
    > length="107763"></link><category term="attachment"
    > scheme="tag:ibm.com,2006:td/type"
    > label="attachment"></category><summary
    > type="text"></summary><td:documentUuid>3b017473-2dbe-4920-85a2-bf908a8e1475</td:documentUuid><td:libraryId>744ccaeb-e9af-434c-9fa6-78831fb94846</td:libraryId><author><name>Frank
    > Adams</name><snx:userid>6B54D23A-0A70-C7A4-8525-7CA50082A393</snx:userid><email>[email protected]</email><snx:userState>active</snx:userState></author><td:modifier><name>Frank
    > Adams</name><snx:userid>6B54D23A-0A70-C7A4-8525-7CA50082A393</snx:userid><email>[email protected]</email><snx:userState>active</snx:userState></td:modifier><title
    > type="text">NominalWorkItem-v1.png</title><published>2014-09-29T20:29:16.210Z</published><updated>2014-09-29T20:29:16.210Z</updated><td:created>2014-09-29T20:29:16.210Z</td:created><td:modified>2014-09-29T20:29:16.210Z</td:modified><td:lastAccessed></td:lastAccessed><content
    > type="image/png"
    > src="https://sdkdev.swg.usma.ibm.com:444/wikis/form/api/wiki/744ccaeb-e9af-434c-9fa6-78831fb94846/page/3b017473-2dbe-4920-85a2-bf908a8e1475/attachment/7780e11c-7240-41b3-8f0c-00a10ea69c93/media"></content></entry>