In my package I created a Detail Page Button that executes some Javascript. The intention is be able to add this to the Contact layout using the Metadata API.

I looked in eclipse and this is the metadata generated for my button:

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
        <masterLabel>Use My Button</masterLabel>
        <url>var url = &apos;/apex/CustomVfAction?Id={!Contact.Id}&apos;; //string for the URL of the 
parent.location.href = url; //refresh the page</url>

And here is how I am attempting to add to the layout (following the instructions from https://andyinthecloud.com/2014/04/24/apex-metadata-api-and-spring14-keys-to-the-kingdom/)

MetadataService.MetadataPort service = new MetadataService.MetadataPort();
service.SessionHeader = new MetadataService.SessionHeader_element();
service.SessionHeader.sessionId = UserInfo.getSessionId();

// Read the Layout
            MetadataService.Layout layout =
                (MetadataService.Layout) service.readMetadata('Layout',
                    new String[] { 'Contact Layout' }).getRecords()[0];

            // Add the Custom Button to the Layout
                layout.customButtons = new List<String>();


However this is throwing an exception in Apex - it's not very helpful though. It simply says "Webservice returned a SOAP fault: UNKNOWN EXCEPTION".

Any ideas on what I'm doing wrong or how to troubleshoot this? I'm not very familiar with the MetaData API.


In your case, I think you are mentioning the Layout name in a wrong way, it will be 'Contact-Contact Layout'.

Here is the working code to create button and adding it to layout-

MetadataService.WebLink webLink = new MetadataService.WebLink();
webLink.fullName = 'Contact.googleButton';
webLink.availability = 'online';
webLink.displayType = 'button';
webLink.encodingKey = 'UTF-8';
webLink.hasMenubar = false;
webLink.hasScrollbars = true;
webLink.hasToolbar = false;
webLink.height = 600;
webLink.isResizable = true;
webLink.linkType = 'url';
webLink.masterLabel = 'google test meta';
webLink.openType = 'newWindow';
webLink.position = 'none';
webLink.protected_x = false;
webLink.showsLocation = false;
webLink.showsStatus = false;
webLink.url = 'http://www.google.com';
webLink.width = 600;
service.createMetadata(new List<MetadataService.Metadata> { webLink })[0];

// Add the Custom Button to the Layout
MetadataService.Layout layout1 = (MetadataService.Layout) service.readMetadata('Layout', new String[] { 'Contact-Contact Layout' }).getRecords()[0];
    layout1.customButtons = new List<String>();

// Update the Layout
service.updateMetadata(new MetadataService.Metadata[] { layout1 })[0];
  • In my case then, would the button be called "Contact. myCustomContactButton?" since I already have it created in the package? – user1813867 Aug 26 '16 at 14:51
  • @user1813867 You won't need the button code and need to write layout1.customButtons.add('myCustomContactButton'); I checked it by creating an action button from salesforce admin and added on layout page by running the code like I have just suggested. – Aditya Vijay Aug 29 '16 at 14:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.