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>