How to Retrieve Current balance of the bank Account in Netsuite - web-services

I need to retrieve the current balance of bank Account in Netsuite using SuiteTalk(Netsuite Webservise).In suite talk API there is no field/parameter to refer the balance of account.But There is UI field Balance which shows the current balance of the account.Any help/suggestions on this is appreciated

If there is no field/parameter in the API referencing that UI field, it is most likely that the field is not supported by the API.

It's definitely not intuitive, but it is possible to pull this data using the API. Here's an example using the netsuite ruby bindings.
def balance_for_account(ns_account)
search = NetSuite::Records::Account.search(
criteria: {
basic: [
{
field: 'internalIdNumber',
operator: 'equalTo',
value: ns_account.internal_id
}
]
},
columns: {
'listAcct:basic' => {
'platformCommon:internalId/' => {},
'platformCommon:balance' => {}
}
}
)
search.results.first.attributes[:balance].to_f
end

Related

AWS Kendra PreHook Lambdas for Data Enrichment

I am working on a POC using Kendra and Salesforce. The connector allows me to connect to my Salesforce Org and index knowledge articles. I have been able to set this up and it is currently working as expected.
There are a few custom fields and data points I want to bring over to help enrich the data even more. One of these is an additional answer / body that will contain key information for the searching.
This field in my data source is rich text containing HTML and is often larger than 2048 characters, a limit that seems to be imposed in a String data field within Kendra.
I came across two hooks that are built in for Pre and Post data enrichment. My thought here is that I can use the pre hook to strip HTML tags and truncate the field before it gets stored in the index.
Hook Reference: https://docs.aws.amazon.com/kendra/latest/dg/API_CustomDocumentEnrichmentConfiguration.html
Current Setup:
I have added a new field to the index called sf_answer_preview. I then mapped this field in the data source to the rich text field in the Salesforce org.
If I run this as is, it will index about 200 of the 1,000 articles and give an error that the remaining articles exceed the 2048 character limit in that field, hence why I am trying to set up the enrichment.
I set up the above enrichment on my data source. I specified a lambda to use in the pre-extraction, as well as no additional filtering, so run this on every article. I am not 100% certain what the S3 bucket is for since I am using a data source, but it appears to be needed so I have added that as well.
For my lambda, I create the following:
exports.handler = async (event) => {
// Debug
console.log(JSON.stringify(event))
// Vars
const s3Bucket = event.s3Bucket;
const s3ObjectKey = event.s3ObjectKey;
const meta = event.metadata;
// Answer
const answer = meta.attributes.find(o => o.name === 'sf_answer_preview');
// Remove HTML Tags
const removeTags = (str) => {
if ((str===null) || (str===''))
return false;
else
str = str.toString();
return str.replace( /(<([^>]+)>)/ig, '');
}
// Truncate
const truncate = (input) => input.length > 2000 ? `${input.substring(0, 2000)}...` : input;
let result = truncate(removeTags(answer.value.stringValue));
// Response
const response = {
"version" : "v0",
"s3ObjectKey": s3ObjectKey,
"metadataUpdates": [
{"name":"sf_answer_preview", "value":{"stringValue":result}}
]
}
// Debug
console.log(response)
// Response
return response
};
Based on the contract for the lambda described here, it appears pretty straight forward. I access the event, find the field in the data called sf_answer_preview (the rich text field from Salesforce) and I strip and truncate the value to 2,000 characters.
For the response, I am telling it to update that field to the new formatted answer so that it complies with the field limits.
When I log the data in the lambda, the pre-extraction event details are as follows:
{
"s3Bucket": "kendrasfdev",
"s3ObjectKey": "pre-extraction/********/22736e62-c65e-4334-af60-8c925ef62034/https://*********.my.salesforce.com/ka1d0000000wkgVAAQ",
"metadata": {
"attributes": [
{
"name": "_document_title",
"value": {
"stringValue": "What majors are under the Exploratory track of Health and Life Sciences?"
}
},
{
"name": "sf_answer_preview",
"value": {
"stringValue": "A complete list of majors affiliated with the Exploratory Health and Life Sciences track is available online. This track allows you to explore a variety of majors related to the health and life science professions. For more information, please visit the Exploratory program description. "
}
},
{
"name": "_data_source_sync_job_execution_id",
"value": {
"stringValue": "0fbfb959-7206-4151-a2b7-fce761a46241"
}
},
]
}
}
The Problem:
When this runs, I am still getting the same field limit error that the content exceeds the character limit. When I run the lambda on the raw data, it strips and truncates it as expected. I am thinking that the response in the lambda for some reason isn't setting the field value to the new content correctly and still trying to use the data directly from Salesforce, thus throwing the error.
Has anyone set up lambdas for Kendra before that might know what I am doing wrong? This seems pretty common to be able to do things like strip PII information before it gets indexed, so I must be slightly off on my setup somewhere.
Any thoughts?
since you are still passing the rich text as a metadata filed of a document, the character limit still applies so the document would fail at validation step of the API call and would not reach the enrichment step. A work around is to somehow append those rich text fields to the body of the document so that your lambda can access it there. But if those fields are auto generated for your documents from your data sources, that might not be easy.

How can I get available license via Google Workspace Admin SDK?

On Google Admin screen, I can get numbers of available licenses and used licenses shown below:
How can I get these numbers via API?
Note: I read this question and tried, but not worked well.
-- EDIT: 2021/07/15 --
My request:
https://developers.google.com/admin-sdk/reports/reference/rest/v1/customerUsageReports/get
date: (few days before now)
parameters: accounts:gsuite_unlimited_total_licenses (comes from Account Parameters)
Response from API:
{
"kind": "admin#reports#usageReports",
"etag": "\"occ7bTD-Q2yefKPIae3LMOtCT9xQVZYBzlAbHU5b86Q/gt9BLwRjoWowpJCRESV3vBMjYMc\""
}
Expectation: I want to get the data same as 2 available, 1132 assigned as the GUI shows.
To be honestly, I'm not satisfying even if I can get info via this API, because it seems not responding real-time data like GUI.
I think there are 2 ways this information can be obtain, but I can confirm for only one of them.
1. Using the Report API that you mentioned.
NOTE : The report is not live data, so you must run the API call with a "date" parameter set at least 2 days before the execution date
Given that, you would have to run this GET method with the proper date in the {date} param
GET https://admin.googleapis.com/admin/reports/v1/usage/dates/{date}
Then you would need to parse through the parameters to find the desired license you are looking for.
reference - https://developers.google.com/admin-sdk/reports/reference/rest/v1/customerUsageReports#UsageReports
Here is how it look like after parsing
[
{
"BoolValue": null,
"DatetimeValueRaw": null,
"DatetimeValue": null,
"IntValue": 12065,
"MsgValue": null,
"Name": "accounts:gsuite_enterprise_total_licenses",
"StringValue": null
},
{
"BoolValue": null,
"DatetimeValueRaw": null,
"DatetimeValue": null,
"IntValue": 12030,
"MsgValue": null,
"Name": "accounts:gsuite_enterprise_used_licenses",
"StringValue": null
}
]
Important : The repot will always date 2 day back, so you can get the total number of licenses gsuite_enterprise_total_licenses in my example, and then use the Enterprise License Manager API to retrieve all currently assigned licenses
reference https://developers.google.com/admin-sdk/licensing/reference/rest
2. Using the Reseller API
Retrieving the information from the reseller point of view you would need to use the subscriptions.get method, providing your customerId and subscriptionId , calling the following GET request:
GET https://reseller.googleapis.com/apps/reseller/v1/customers/{customerId}/subscriptions/{subscriptionId}
The response of that would be a subscriptions resource, that contains various information about the license and the Seats object , which if you expand looks like this :
{
"numberOfSeats": integer,
"maximumNumberOfSeats": integer,
"licensedNumberOfSeats": integer,
"kind": string
}
numberOfSeats should be the total amount of licenses and licensedNumberOfSeats should be the number of users having that license assigned to them.
NOTE : in order to use this API , the given tenant should have a "fully executed and signed reseller contract" - https://developers.google.com/admin-sdk/reseller/v1/how-tos/prerequisites
Reference - https://developers.google.com/admin-sdk/reseller/reference/rest/v1/subscriptions
Answer:
You can only get the number of assigned licenses using the API, the number available isn't exposed and so does not get returned.
More Information:
Given that you have licenses assigned for your domain, and the user that is querying the API has access to this information, you can retrieve the data with the following request:
curl \
'https://admin.googleapis.com/admin/reports/v1/usage/dates/2021-07-10?parameters=accounts%3Agsuite_unlimited_total_licenses&fields=*&key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--compressed
While not necessary, I added the parameter field=* in order to make sure all data is returned.
This gave me a response as such:
{
"kind": "admin#reports#usageReports",
"etag": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"usageReports": [
{
"kind": "admin#reports#usageReport",
"date": "2021-07-10",
"etag": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"entity": {
"type": "CUSTOMER",
"customerId": "C0136mgul"
},
"parameters": [
{
"name": "accounts:gsuite_unlimited_total_licenses",
"intValue": "233"
}
]
}
]
}
Here you can see that the intValue for accounts:gsuite_unlimited_total_licenses is 233 - which is reflected in the UI:
Feature Request:
You can however let Google know that this is a feature that is important for access to their APIs, and that you would like to request they implement it.
Google's Issue Tracker is a place for developers to report issues and make feature requests for their development services, I'd urge you to make a feature request there. The best component to file this under would be the Google Admin SDK component, with the Feature Request template.
I was not able to use Reseller API (ran into some authorization issues) and Reports API (contained null values in all relevant attributes). The only way I was able to find how many licenses were remaining was through Enterprise License Manager API.
After getting assignments, I used sdkName to filter records based on the type of license.
Here is the complete code.
function getRemainingGoogleUserLicensesCount() {
const GOOGLE_USER_LICENSES_TOTAL = 100 // You can find this from Google Admin -> Billing -> Subscriptions
const productId = 'Google-Apps';
const customerId = 'C03az79cb'; // You can find this from this response, https://developers.google.com/admin-sdk/directory/v1/guides/manage-users#json-response
let assignments = [];
let usedLicenseCount = 0
let pageToken = null;
do {
const response = AdminLicenseManager.LicenseAssignments.listForProduct(productId, customerId, {
maxResults: 500,
pageToken: pageToken
});
assignments = assignments.concat(response.items);
pageToken = response.nextPageToken;
} while (pageToken);
for (const assignment of assignments) {
if (assignment["skuName"] == "Google Workspace Business Plus") {
usedLicenseCount += 1
}
}
return GOOGLE_USER_LICENSES_TOTAL - usedLicenseCount
}

How can I do Google drive data migration?

I am trying to do drive data migration from one user to another using https://developers.google.com/admin-sdk/data-transfer/v1/reference/transfers/insert
Code Block:
{
"newOwnerUserId": "new user id",
"oldOwnerUserId": "old user id",
"applicationDataTransfers": [
{
"applicationId": 122344
}
]
}
I am getting 200 response but I don't see any new folder in newOwnerUserId with oldOwnerUser Data.
Can somebody please suggest what am I doing wrong?
Define Privacy level otherwise it will not work

Google Cloud Datastore query values in array

I have entities that look like that:
{
name: "Max",
nicknames: [
"bestuser"
]
}
how can I query for nicknames to get the name?
I have created the following index,
indexes:
- kind: users
properties:
- name: name
- name: nicknames
I use the node.js client library to query the nickname,
db.createQuery('default','users').filter('nicknames', '=', 'bestuser')
the response is only an empty array.
Is there a way to do that?
You need to actually fetch the query from datastore, not just create the query. I'm not familiar with the nodejs library, but this is the code given on the Google Cloud website:
datastore.runQuery(query).then(results => {
// Task entities found.
const tasks = results[0];
console.log('Tasks:');
tasks.forEach(task => console.log(task));
});
where query would be
const query = db.createQuery('default','users').filter('nicknames', '=', 'bestuser')
Check the documentation at https://cloud.google.com/datastore/docs/concepts/queries#datastore-datastore-run-query-nodejs
The first point to notice is that you don't need to create an index to this kind of search. No inequalities, no orders and no projections, so it is unnecessary.
As Reuben mentioned, you've created the query but you didn't run it.
ds.runQuery(query, (err, entities, info) => {
if (err) {
reject(err);
} else {
response.resultStatus = info.moreResults;
response.cursor = info.moreResults == TNoMoreResults? null: info.endCursor;
resolve(entities);
};
});
In my case, the response structure was made to collect information on the cursor (if there is more data than I've queried because I've limited the query size using limit) but you don't need to anything more than the resolve(entities)
If you are using the default namespace you need to remove it from your query. Your query needs to be like this:
const query = db.createQuery('users').filter('nicknames', '=', 'bestuser')
I read the entire plob as a string to get the bytes of a binary file here. I imagine you simply parse the Json per your requirement

How to get user attributes (username, email, etc.) using cognito identity id

I have AWS Cognito Identity Pool that is configured with Cognito User Pool as an authentication provider.
Assume I have identity ID of an identity in Cognito Identity Pool (e.g. us-east-1:XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX) where this identity has a linked login to a user in Cognito User Pool.
Using identity ID, how can I get the linked user details (email, phone, username)?
The ID Token that you exchange with Cognito federated identity service to get the identity id and credentials already has all user attributes. You do not need an extra call to any service.
It is a JWT token and you can use any library on the client to decode the values. You can read this guide for more information about the tokens vended by Cognito user pools.
Alternatively, you can also use the Access Token to call GetUser API which will return all the user information.
Using REST API
AccessToken
Thought that this could be very helpful to someone as I've spent a lot of time trying to figure out how to get UserAttributes with only accessToken and region ( Similar to this but with REST API ( Without using aws-sdk )
You can get UserAttributes with accessToken using this HTTP request. ( GetUser )
Method: POST
Endpoint: https://cognito-idp.{REGION}.amazonaws.com/
Content-Type: application/x-amz-json-1.1
Content-Length: 1162 // Access Token bytes length
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
Body: {"AccessToken":"ACCESS_TOKEN"}
And if the accessToken is valid, you should receive example response like the following
{
"UserAttributes": [
{
"Name": "sub",
"Value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "name",
"Value": "Jason"
},
{
"Name": "phone_number_verified",
"Value": "true"
},
{
"Name": "phone_number",
"Value": "+xxxxxxxxxxx"
},
{
"Name": "email",
"Value": "xxxx#gmail.com"
}
],
"Username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
}
AWS cognito-idp list-users has a filter option that allows you to filter based on attribute. 'sub' is the attribute that matches the identity id you are describing.
e.g. at the command line:
aws cognito-idp list-users --user-pool-id us-east-1_abcdFghjI --filter "sub=\":XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX\""
This also requires the user-pool-id, which I suspect you have. Additionally, I have no idea how this is implemented or how it performances when filtering a large number of users, but I take custom attributes not being usable in filters as a hint that there is some form of indexing behind the curtain.
I faced the similar issue and after too much of scratching i was not able to find the exact way of pulling out the details. My usecase was to get the details in android APP.
After looking into their AWSMobile client API code. I found below and it is working from me.
Log.i(TAG, "User Details"+ AWSMobileClient.getInstance().getUserAttributes().toString());
Recommendation - Try use AWSMobileclient incase you are using it for Android Development as this is new library that is recommended for development.
Just struggled with this for a while, and the way I got the user name, using Java API is:
identityManager.login(this, new DefaultSignInResultHandler() {
#Override
public void onSuccess(Activity activity, IdentityProvider identityProvider) {
...
String userName = ((CognitoUserPoolsSignInProvider) identityProvider).getCognitoUserPool().getCurrentUser().getUserId();
There is a listener we can initialize that will listen to changes in our authentication state and allow us to have access to the type of authentication event that happened and update the application state based on that data.
With Amplify, the Hub module allows us to do this pretty easily:
import { Hub } from 'aws-amplify';
Hub.listen('auth', (data) => {
const {payload} = data;
if (payload.event === 'signOut') {
console.log('signOut');
} else if (payload.event === 'signIn') {
console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
}
});
For those who are looking how to get the value of email parameter in Java programmatically
I assume you have already figured out how to get the needed / all users from the pool.
Say I have ListUsersResult with my all users and say I want to check the email value of the first user:
ListUsersResult allUsers = getAllUsers();
UserType userType = allUsers.getUsers().get(0);
First I can get user's all attributes:
List<AttributeType> attributes = userType.getAttributes();
Then loop through the attributes looking for the one we're interested in (our case email):
for (AttributeType att : attributes) {
if (att.getName().equals("email")) {
// do whatever you want
}
}
Remember that printing in to the console will most probably not work since it is sensitive data. But you can compare it like this:
att.getValue().equals("mymail#mail")
Use this piece of code
GetDetailsHandler detailsHandler = new GetDetailsHandler() {
#Override
public void onSuccess(CognitoUserDetails cognitoUserDetails) {
CognitoUserAttributes cognitoUserAttributes=cognitoUserDetails.getAttributes();
stringStringHashMap=new HashMap<>();
stringStringHashMap =cognitoUserAttributes.getAttributes();
userNumber=stringStringHashMap.get("phone_number");
e1.setText(userNumber);
Log.d("Response"," Inside DEATILS HANDLER");
// Store details in the AppHandler
AppHelper.setUserDetails(cognitoUserDetails);
// Trusted devices?
handleTrustedDevice();
// e1.setText(input.getText().toString());
}
#Override
public void onFailure(Exception exception) {
closeWaitDialog();
showDialogMessage("Could not fetch user details!", AppHelper.formatException(exception), true);
}
};
private void getDetails() {
AppHelper.getPool().getUser(username).getDetailsInBackground(detailsHandler);
}
console.log('username is ' + cognitoUser.getUsername());