0

I'm developing an app for the app exchange that requires a callout to an external system. I have a named credential set up to handle the users login information to the external server. While developing the application, when I make a callout to the external server everything works fine. I issue starts after I upload the package to the app exchange. When customers download and install the application they are getting a callout error. I'm not sure what to test for next? I've verified that their login information is correct. I'll attach some screenshots of the error as well as the code I'm using.

Callout Class

/**
* @author       Allen Watson
* @version  1.0
* @since        1.0 
* 
* Used to handle communication with slybroadcast Servers
*/
public with sharing class callout {

public String Username;
public String Password;

public callout(){
    Username = '{!$Credential.UserName}';
    Password = '{!$Credential.Password}';
}


/**
 * Sends a voice message request to slybroadcast
 * 
 * @param   phone - The phone number that is to receive the voice message.
 * @param   audioRecord - The voice message that is to be sent.
 * @param   cdate - The date and time the voice message should be sent.
 * @param   callerID - The phone number that you want to send the voice message from.
 * @param   mobileOnly - Do you want to send the voice message to mobile phones only?
 * @return  Boolean - return value relays success or failure to the parent.
 * @since   1.0
 */
public Boolean sendRequest(String phone, String audioRecord, String cdate, String callerID, String mobileOnly)
{
    // remove username and password as it is handled by named credential
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();
    req.setMethod('POST'); // Method Type
    req.setEndpoint('callout:SlyUserCred/vmb.php'); // Server Url
    req.setBody('c_uid='+Username+  
                '&c_password='+Password+ '&c_phone=' + EncodingUtil.urlEncode(phone, 'UTF-8') +
                '&c_record_audio=' + EncodingUtil.urlEncode(audioRecord, 'UTF-8') + '&c_callerID=' + 
                EncodingUtil.urlEncode(callerID,'UTF-8') + '&c_date=' + EncodingUtil.urlEncode(cdate, 'UTF-8') +
                '&c_audio='+ EncodingUtil.urlEncode('wav', 'UTF-8') + '&mobile_only=' + EncodingUtil.urlEncode(mobileOnly, 'UTF-8')); // Request Parameters
    try 
    {
        //processing the response from slybroadcast.
        res = http.send(req);
        system.debug(res.getBody());
        if(res.getBody() != null)
        {
            system.debug(res.getBody());
            return true;
        }
        return true;

    } 
    catch(Exception e) 
    {
        System.debug('error: '+ e);
        return false;
    }
}

/**
 * Use to ask the slybroadcast severs for a list of stored audio file names.
 * 
 * @return  List<String> - returns a list of all the audiofile accociated with a slybroadcast account.
 * @since   1.0
 */
public List<String> getAudioFiles()
{
    // remove username and password as it is handled by named credential
    List<String> rtnString = new List<String>();

    //Creates HttpRequest and builds the request.
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();
    req.setMethod('POST'); // Method Type
    req.setEndpoint('callout:SlyUserCred/vmb.aflist.php'); // Server Url
    req.setBody('c_uid='+Username+   
                '&c_password='+Password+
               '&c_method=' + EncodingUtil.urlEncode('get_audio_list', 'UTF-8'));

    try 
    {
        //Processing the response from slybroadcast
        res = http.send(req);
        system.debug(res.getBody());
        if(res.getBody() != null)
        {
            //Splitting up the audioRecords into a list
            String unsplitString = res.getBody();
            List<String> firstSplitString = unsplitString.split('\n');
            List<String> secondSplitString = new List<String>();
            for(String s : firstSplitString)
            {
                secondSplitString = s.split('\\|');
                String temp = secondSplitString[1];
                secondSplitString[1] = temp.remove('\"');
                rtnString.add(secondSplitString[1]);
            }
            return rtnString;
        }
        return rtnString;
    } 
    catch(Exception e) 
    {
        rtnString.add('error: '+ e);
        return rtnString;
    }
}
//used to verify that the slybroadcast account that the user entered is a valid one.
public Boolean validateAccount()
{
    // remove username and password as it is handled by named credential
    Boolean isValid = false;
    HttpRequest req = new HttpRequest();
    HttpResponse res = new HttpResponse();
    Http http = new Http();
    req.setMethod('POST'); // Method Type
    req.setEndpoint('callout:SlyUserCred/vmb.php'); // Server Url
    req.setBody('c_uid='+Username+   
                '&c_password='+Password+
                '&c_option=user_verify'); // Request Parameters
    system.debug('CAL116: '+req.getBody());
    try 
    {
        res = http.send(req);
        system.debug('Res: '+res.getBody());
        if(res.getBody() == 'OK')
        {
            isValid = true;
        }else
        {
            //throw new CalloutException(res.getBody());
        }

    } 
    catch(Exception e) 
    {
        throw e;
    }
    return isValid;
} 
}

VisualForce Page Controller

public with sharing class WelcomeController {
public callout Broadcaster;

public WelcomeController(){
    Broadcaster = new callout();
    //System.debug('Got Here');
}

public PageReference ValidateSlybroadcastAccount(){
    PageReference ValidationResult = Page.SlybroadcastAcctValidVFP;
    Boolean isValid = Broadcaster.validateAccount();
    if(!isValid) ValidationResult = Page.SlybroadcastAcctInvalidVFP;
    System.debug('Is Slybroadcast Account Valid: '+isValid);
    return ValidationResult;
}

public PageReference ReturnToWelcome(){
    return Page.SlybroadcastWelcomeVFP;
}
}

Visualforce Page

<apex:page controller="WelcomeController">
<apex:pageBlock title="Welcome to Slybroadcast." tabStyle="Message__c">
    <apex:form >
        <apex:pageBlockSection title="Account Validation" collapsible="true">
            <apex:commandLink action="/0XU/e?retURL=%2Fudd%2FExternalDataUserAuth%2FlistExternalDataUserAuth.apexp" value="Add Slybroadcast Credentials to Salesforce."/>
            <apex:commandLink action="{!ValidateSlybroadcastAccount}" value="Validate Slybroadcast Credentials."/>
        </apex:pageBlockSection>
        <apex:pageBlockSection title="More" collapsible="true">
            <apex:commandLink action="https://drive.google.com/drive/folders/11X2d6Ml1249BVFMkPfaPd9VlHs4CgZfG?usp=sharing" value="Visual Aids and more instructions."/>
        </apex:pageBlockSection>
    </apex:form>
</apex:pageBlock>

Callout error.

2
  • If your named credentials is coming from the managed packaged then You will need to add the namespace to access the named Credentials
    – Sam
    Commented Aug 21, 2018 at 8:55
  • I'm not sure what you mean? Commented Aug 21, 2018 at 11:43

1 Answer 1

1

I also had the same issue today.

Try to prefix the name of your named credential with ".__" as shown in the sample below.

final String DEV_ORG_ID = <my_dev_org_Id>;
String endpointURL = 'callout:.__SlyUserCred/vmb.aflist.php'; 
if(UserInfo.getOrganizationId() == DEV_ORG_ID){ 
    endpointURL = 'callout:SlyUserCred/vmb.aflist.php';
}
req.setEndpoint(endpointURL);
9
  • Any idea why we would need to do that? Commented Aug 21, 2018 at 11:44
  • I get this error when I do that.The callout couldn't access the endpoint. You might not have the required permissions, or the named credential ".__SlyUserCred" might not exist. @Chandra Kiran Commented Aug 21, 2018 at 12:15
  • This is the same advice I got from Salesforce support. One catch is that using the local namespace with the '.__' breaks the code in the developer org as there is no way to create a Named Credential outside the package namespace. So the only solution I could determine to resolve the issue in both dev org and subscriber org is to check the org Id to see if we were running in the dev org and remove the name space. Commented Aug 21, 2018 at 12:18
  • .__ is not work in the developer org. It will work only in subscriber org. No need to add ".__" in developer org Commented Aug 21, 2018 at 12:20
  • Okay. I'll give that a try. Commented Aug 21, 2018 at 12:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .