Adding account fails with obscure exception( i.e. IncompleteArgumentException) - yodlee

I am trying to use the REST API to add accounts to my private zone implementation. I have been modifying SDK sample code, but my minor modification seems to result in failure and I'm not sure why. Note: obviously, I'm not including the actual username and password. Also, the site ID is for AMEX.
Here's the code (again, which is modified from example code):
public String addSiteAccount(String cobrandSessionToken,
String userSessionToken) {
DefaultHttpClient httpclient = new DefaultHttpClient();
String url = HOST_URI + ADD_SITE_ACC;
try {
HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());
PostMethod pm = new PostMethod(url);
pm.addParameter(paramNameCobSessionToken, cobrandSessionToken);
pm.addParameter(paramNameUserSessionToken, userSessionToken);
String theUsername = "...whatever...";
String thePassword = "...whatever...";
pm.addParameter("credentialFields[0].name", "LOGIN");
pm.addParameter("credentialFields[0].displayName", "Username");
pm.addParameter("credentialFields[0].isEditable", "true");
pm.addParameter("credentialFields[0].isOptional", "false");
pm.addParameter("credentialFields[0].helpText", "22059");
pm.addParameter("credentialFields[0].valuePattern", "null");
pm.addParameter("credentialFields[0].defaultValue", "null");
pm.addParameter("credentialFields[0].value", theUsername);
pm.addParameter("credentialFields[0].validValues", theUsername);
pm.addParameter("credentialFields[0].displayValidValues", "null");
pm.addParameter("credentialFields[0].valueIdentifier", "LOGIN");
pm.addParameter("credentialFields[0].valueMask", "LOGIN_FIELD");
pm.addParameter("credentialFields[0].fieldType", "LOGIN");
pm.addParameter("credentialFields[0].validationRules", "null");
pm.addParameter("credentialFields[0].size", "20");
pm.addParameter("credentialFields[0].maxlength", "40");
pm.addParameter("credentialFields[0].userProfileMappingExpression",
"null");
pm.addParameter("credentialFields[0].fieldErrorCode", "1");
pm.addParameter("credentialFields[0].fieldErrorMessage", "null");
pm.addParameter("credentialFields[1].name", "PASSWORD");
pm.addParameter("credentialFields[1].displayName", "Password");
pm.addParameter("credentialFields[1].isEditable", "true");
pm.addParameter("credentialFields[1].isOptional", "false");
pm.addParameter("credentialFields[1].helpText", "AUS_Row_Name");
pm.addParameter("credentialFields[1].valuePattern", "null");
pm.addParameter("credentialFields[1].defaultValue", "null");
pm.addParameter("credentialFields[1].value", thePassword);
pm.addParameter("credentialFields[1].validValues", thePassword);
pm.addParameter("credentialFields[1].displayValidValues", "null");
pm.addParameter("credentialFields[1].valueIdentifier", "PASSWORD");
pm.addParameter("credentialFields[1].valueMask", "LOGIN_FIELD");
pm.addParameter("credentialFields[1].fieldType", "PASSWORD");
pm.addParameter("credentialFields[1].validationRules", "null");
pm.addParameter("credentialFields[1].size", "20");
pm.addParameter("credentialFields[1].maxlength", "40");
pm.addParameter("credentialFields[1].userProfileMappingExpression",
"null");
pm.addParameter("credentialFields[1].fieldErrorCode", "1");
pm.addParameter("credentialFields[1].fieldErrorMessage", "null");
pm.addParameter("credentialFields.objectInstanceType",
"[Lcom.yodlee.common.FieldInfoSingle;");
pm.addParameter("siteId", "12");
// pm.addParameter("siteId.objectInstanceType", "long");
HttpClient hc = new HttpClient();
hc.executeMethod(pm);
String source = pm.getResponseBodyAsString();
System.out.println(pm.getResponseBodyAsString());
} catch (Exception e) {
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
return userSessionToken;
}
The result I get is:
{"errorOccurred":"true","exceptionType":"Exception Occurred","referenceCode":"_2ee6cfc1450c-42b8-86ec-7caef38f17bc"}
After failing here, I tried to simplify the code based on the minimum required parameters as mentioned here.
pm.addParameter("siteId", "12");
pm.addParameter("credentialFields.enclosedType",
"com.yodlee.common.FieldInfoSingle");
pm.addParameter("credentialFields[0].fieldType.typeName", "IF_LOGIN");
pm.addParameter("credentialFields[0].name", "LOGIN1");
pm.addParameter("credentialFields[0].size", "20");
pm.addParameter("credentialFields[0].value", theUsername);
pm.addParameter("credentialFields[0].valueIdentifier", "LOGIN");
pm.addParameter("credentialFields[0].valueMask", "LOGIN_FIELD");
pm.addParameter("credentialFields[0].isEditable", "true");
pm.addParameter("credentialFields[0].displayName", "Username");
pm.addParameter("credentialFields[1].fieldType.typeName", "IF_PASSWORD");
pm.addParameter("credentialFields[1].name", "PASSWORD");
pm.addParameter("credentialFields[1].size", "20");
pm.addParameter("credentialFields[1].value", thePassword);
pm.addParameter("credentialFields[1].valueIdentifier", "PASSWORD1");
pm.addParameter("credentialFields[1].valueMask", "LOGIN_FIELD");
pm.addParameter("credentialFields[1].isEditable", "true");
However, this fails with:
{"errorOccurred": "true", "exceptionType": "com.yodlee.core.IncompleteArgumentException", "referenceCode": "_0a549c3d-11f4-4c98-8e65-7f845fd83f54","message":"LOGIN"}
This also makes me wonder: do I need to make calls to searchSite() and getLoginForm() before issuing the code above? In our application, we have the site IDs and the login information, so we do not need to interact with a user per se. But I'm not sure if workflow is somehow being tracked on the backend, and we're violating it or something.
Any help would be appreciated. Incidentally, if there are any better examples for using REST to add accounts, it would be greatly appreciated. I have searched the developer portal, but it's a bit difficult to find a concise example. Thank you.

Yes, please we suggest you to use the field's value which you receive in response of getLoginForm API to provide the required input parameters in addSiteAccount1 API.
And to get this working please correct this parameter's value.
credentialFields[0].name= "LOGIN1" instead of "LOGIN"
Ideally that should work but in case you still get same error then please change below mentioned parameter's value as well.
"credentialFields[0].valueIdentifier", "LOGIN" to "LOGIN1"
This should help.

Related

OneDrive Service don't get a refresh token

I use Xamarin.Auth to authenticate with the OneDrive Service. This worked fine for a while now, but I seems there where changes on the service so it stopped working..
I upgraded to the new version 2.0 and try to make it work again. The Initial authentication works well so far. But after a while it always started to crash. I realized that there isn't any refrehs token sent back from the onedrive service.
This is the code to call the Auth UI:
private Task<IDictionary<string, string>> ShowWebView()
{
var tcs = new TaskCompletionSource<IDictionary<string, string>>();
var auth = new OAuth2Authenticator(ServiceConstants.MSA_CLIENT_ID,
string.Join(",", ServiceConstants.Scopes),
new Uri(GetAuthorizeUrl()),
new Uri(ServiceConstants.RETURN_URL));
auth.Completed +=
(sender, eventArgs) =>
{
tcs.SetResult(eventArgs.IsAuthenticated ? eventArgs.Account.Properties : null);
};
var intent = auth.GetUI(Application.Context);
intent.SetFlags(ActivityFlags.NewTask);
Application.Context.StartActivity(intent);
return tcs.Task;
}
private string GetAuthorizeUrl()
{
var requestUriStringBuilder = new StringBuilder();
requestUriStringBuilder.Append(ServiceConstants.AUTHENTICATION_URL);
requestUriStringBuilder.AppendFormat("?{0}={1}", ServiceConstants.REDIRECT_URI,
ServiceConstants.RETURN_URL);
requestUriStringBuilder.AppendFormat("&{0}={1}", ServiceConstants.CLIENT_ID,
ServiceConstants.MSA_CLIENT_ID);
requestUriStringBuilder.AppendFormat("&{0}={1}", ServiceConstants.SCOPE,
WebUtility.UrlEncode(string.Join(" ", ServiceConstants.Scopes)));
requestUriStringBuilder.AppendFormat("&{0}={1}", ServiceConstants.RESPONSE_TYPE, ServiceConstants.CODE);
return requestUriStringBuilder.ToString();
}
The Authorize URI is:
https://login.live.com/oauth20_authorize.srf?redirect_uri=https://login.live.com/oauth20_desktop.srf&client_id=["id"]&scope=onedrive.readwrite+wl.offline_access+wl.signin&response_type=code
The response I get contains 6 Elements:
access_token: "EwAIA..."
token_type: "bearer"
expires_in: "3600"
scope: "onedrive.readwrite wl.offline_access wl.signin wl.basic wl.skydrive wl.skydrive_update onedrive.readonly"
user_id: "41...."
state: "ykjfmttehzjebqtp"
When I check it with the Documentation (https://dev.onedrive.com/auth/msa_oauth.htm) I can't see what's wrong here. Any ideas?
I called wrong constructor. This one works:
authenticator = new OAuth2Authenticator(ServiceConstants.MSA_CLIENT_ID,
ServiceConstants.MSA_CLIENT_SECRET,
string.Join(",", ServiceConstants.Scopes),
new Uri(ServiceConstants.AUTHENTICATION_URL),
new Uri(ServiceConstants.RETURN_URL),
new Uri(ServiceConstants.TOKEN_URL));
With these constants:
Scopes = {"onedrive.readwrite", "wl.offline_access", "wl.signin"};
RETURN_URL = "https://login.live.com/oauth20_desktop.srf";
AUTHENTICATION_URL = "https://login.live.com/oauth20_authorize.srf";
TOKEN_URL = "https://login.live.com/oauth20_token.srf";

Exception handling ExchangeWebServices php-ews

I use https://github.com/jamesiarmes/php-ews library to access my exchange account.
If I used correct credentials to create a ExchangeWebServices object, I get accurate response.
$ews = new ExchangeWebServices("outlook.office365.com", "tes#abc.com", "test123");
$request = new EWSType_FindItemType();
$response = $ews->FindItem($request);
But If the credentials are wrong it breaks the site by throwing an exception as
EWS_Exception: SOAP client returned status of 401 in ExchangeWebServices->processResponse()
Is there any way to get the response as "failed" or some boolean value instead of the error message?
There's no way to get the response as a boolean, but you can do something like
$ews = new ExchangeWebServices("outlook.office365.com", "tes#abc.com", "test123");
$request = new EWSType_FindItemType();
try {
$response = $ews->FindItem($request);
} catch (\Exception $e) {
//The response failed.
}
Also, that version of php-ews is out of date and unmaintained. Might I suggest you try https://github.com/Garethp/php-ews

Windows Phone Silverlight request does not update

I'm quite new to the Windows Phone dev and I have to do an application to communicate with a Restful API. Everything works fine to get the informations back from the API but my problem occurs when I try to update the content. For example, I have a profile and I try to update the user's information (change the city let's say). On the server side I can see that my update worked properly but when I go back to my profile in my WP app nothing has changed, the city is still the same as the old one. This is my code :
public MainPage()
{
InitializeComponent();
this.ApplicationBar = this.Resources["HomeBar"] as ApplicationBar;
Requester requester = new Requester();
requester.initGetRequest("/me/", GetResponseCallback, true);
}
private void GetResponseCallback(IAsyncResult asynchronousResult)
{
try
{
HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
Stream streamResponse = response.GetResponseStream();
StreamReader streamRead = new StreamReader(streamResponse);
string read = streamRead.ReadToEnd();
GlobalData.GetInstance().user = JsonConvert.DeserializeObject<MeClass>(read);
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(read);
});
//Create the profile and stuff
streamResponse.Close();
streamRead.Close();
response.Close();
}
catch (WebException webException)
{
HttpStatusCode status = ((HttpWebResponse)webException.Response).StatusCode;
Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(status.ToString());
});
}
}
I figured out that the string 'read' is always equal to the old one, even after the update so this is why the content is not updated but how can the response be exactly the same as before, even if the update worked fine on the server side (if I check in Postman after my update, I can see that my city is the new one). If I restart my app I can see the update.
I can also show you my initGetRequest() :
public void initGetRequest(String endPoint, Action<IAsyncResult> callback, Boolean header)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + endPoint);
if (header == true)
request.Headers["Authorization"] = GlobalData.GetInstance().Header;
request.BeginGetResponse(new AsyncCallback(callback), request);
}
Thank you for your help !
I finally found why my request was still the same even after the update. The HttpWebRequest uses a cache by default. I only added a small bit of code before calling my request :
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url + endPoint);
if (header == true)
request.Headers["Authorization"] = GlobalData.GetInstance().Header;
request.Headers[HttpRequestHeader.IfModifiedSince] = DateTime.UtcNow.ToString();
request.BeginGetResponse(new AsyncCallback(callback), request);
I had no idea about that cache so I hope this answer will help someone having the same issue !

Marketo rest Api create lead

I have a question about this create/Update leads API, http://developers.marketo.com/documentation/rest/createupdate-leads/.
There is no sample code for C# or JAVA. Only ruby available. So I have to try it by myself. But I always get null return from the response.
Here is my code:
private async Task<CreateLeadResponseResult> CreateLead(string token)
{
string url = String.Format(marketoInstanceAddress+"/rest/v1/leads.json?access_token={0}", token);
var fullUri = new Uri(url, UriKind.Absolute);
CreateLeadResponseResult createLeadResponse = new CreateLeadResponseResult();
CreateLeadInput input = new CreateLeadInput { email = "123#123.com", lastName = "Lee", firstName = "testtesttest", postCode = "00000" };
CreateLeadInput input2 = new CreateLeadInput { email = "321#gagaga.com", lastName = "Lio", firstName = "ttttttt", postCode = "00000" };
List<CreateLeadInput> inputList = new List<CreateLeadInput>();
inputList.Add(input);
inputList.Add(input2);
CreateLeadRequest createLeadRequest = new CreateLeadRequest() { input = inputList };
JavaScriptSerializer createJsonString = new JavaScriptSerializer();
string inputJsonString = createJsonString.Serialize(createLeadRequest);
using (var client = new HttpClient())
{
HttpResponseMessage response = await client.PostAsJsonAsync(fullUri.OriginalString, inputJsonString).ConfigureAwait(false);
// I can see the JSON string is in the message body in debugging mode.
if (response.IsSuccessStatusCode)
{
createLeadResponse = await response.Content.ReadAsAsync<CreateLeadResponseResult>();
}
else
{
if (response.StatusCode == HttpStatusCode.Forbidden)
throw new AuthenticationException("Invalid username/password combination.");
else
throw new ApplicationException("Not able to get token");
}
}
return createLeadResponse;}
//get null here.
Thank you.
-C.
The best way to debug this is to capture the exact URL, parameters and JSON that are submitted by your app and try submitting those manually via a tool like Postman (Chrome plug-in) or SOAP UI. Then you see the exact error message, which you can look up here: http://developers.marketo.com/documentation/rest/error-codes/. Based on that you can update your code. I don't know much about Java, but this is how I got my Python code to work.
Your example code was really helpful in getting my own implementation off the ground. Thanks!
After playing with it for a bit, I realized that the JavaScriptSerializer step is unnecessary since PostAsJsonAsync automatically serializes whatever object you pass to it. The double serialization prevents Marketo's API from processing the input.
Also, I agree with Jep that Postman is super helpful. But in the case of this error, Postman was working fine (using the contents of inputJsonString) but my C# code still didn't work properly. So I temporarily modified the code to return a dynamic object instead of a CreateLeadResponseResult. In debugging mode this allowed me to see fields that were discarded because they didn't fit the CreateLeadResponseResult type, which led me to the solution above.

Error 415 from IAV Rest API - Get verbose error message

I have been trying the Instant Account Verification using the REST api but have run into a couple issues. I receive an error 415(Problem Updating Account) when calling either the addTransferAccountForItem or addItemAndStartVerificationDataRequest api. I'm wondering if there is any way to get a more detailed error message to understand what I'm doing wrong when making these calls. The error message is being returned in XML format although it should be returned in JSON.
Here's an example snippet of how I'm making the addItemAndStartVerificationDataRequest call. GDURL is a simple class that holds the url and concatenates all parameters into a string in format "param1=param1Value&param2=param2Value...".
Any nudge in the right direction would be appreciated. Thank you.
The url I am using are:
addItemAndStartVerificationDataRequestURL=
baseUrl+jsonsdk/ExtendedInstantVerificationDataService/addItemAndStartVerificationDataRequest/
addTransferAccountForItem=
baseUrl+jsonsdk/TransferAccountManagement/addTransferAccountForItem/
logger.info("Attempting to add item and start verification");
try{
GDURL iavUrl = new GDURL(restURL + addItemAndStartVerificationDataRequestURL);
iavUrl.addParameter("cobSessionToken", cobrandSessionToken);
iavUrl.addParameter("userSessionToken", userSessionToken);
iavUrl.addParameter("contentServiceId", contentServiceId);
iavUrl.addParameter("accountNumber", accountNumber);
iavUrl.addParameter("routingNumber", routingNumber);
iavUrl.addParameter("credentialFields.enclosedType", "com.yodlee.common.FieldInfoSingle");
iavUrl.addParameter("credentialFields[0].displayName", "UserID");
iavUrl.addParameter("credentialFields[0].fieldType.typeName", "IF_LOGIN");
iavUrl.addParameter("credentialFields[0].helpText", "4710");
iavUrl.addParameter("credentialFields[0].isEditable", "true");
iavUrl.addParameter("credentialFields[0].maxlength", "32");
iavUrl.addParameter("credentialFields[0].name", "LOGIN");
iavUrl.addParameter("credentialFields[0].size", "20");
iavUrl.addParameter("credentialFields[0].value", bankUsername);
iavUrl.addParameter("credentialFields[0].valueIdentifier", "LOGIN");
iavUrl.addParameter("credentialFields[0].valueMask", "LOGIN_FIELD");
iavUrl.addParameter("credentialFields[1].displayName", "Password");
iavUrl.addParameter("credentialFields[1].fieldType.typeName", "IF_PASSWORD");
iavUrl.addParameter("credentialFields[1].helpText", "11976");
iavUrl.addParameter("credentialFields[1].isEditable", "true");
iavUrl.addParameter("credentialFields[1].maxlength", "40");
iavUrl.addParameter("credentialFields[1].name", "PASSWORD");
iavUrl.addParameter("credentialFields[1].size", "20");
iavUrl.addParameter("credentialFields[1].value", bankPassword);
iavUrl.addParameter("credentialFields[1].valueIdentifier", "PASSWORD");
iavUrl.addParameter("credentialFields[1].valueMask", "LOGIN_FIELD");
HttpURLConnection connection = null;
connection = (HttpURLConnection) iavUrl.getURL().openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.connect();
String s="";
DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
wr.writeBytes(iavUrl.getParamString());
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
while(bufferedReader.ready())
s+=bufferedReader.readLine()+"/n";
}
System.out.println("add item response: /n" + s);
}catch(IOException e){
logger.error("error occured", e);
}
The 415(problem updating account) is an error thrown by Yodlee's data agent when it encounters an exception while trying to aggregate the account from end site. This particular error is thrown for situations where the end site terminates the session established by the data agent as the user might have already been logged in to the end site directly.
To know more about error code please refer this document