Skip to content

Instantly share code, notes, and snippets.

@mcho71
Last active December 22, 2023 08:35
Show Gist options
  • Save mcho71/a59e097d55afbf0f7c6f6471c7c82a3d to your computer and use it in GitHub Desktop.
Save mcho71/a59e097d55afbf0f7c6f6471c7c82a3d to your computer and use it in GitHub Desktop.
InsightsExternalDataをREST APIで作成する例
/* global fetch */
/* global Blob */
/* global btoa */
// AWS Lambdaのライブラリをインポート
const INSTANCE_URL = "https://yourInstance.salesforce.com";
const API_VERSION = "51.0";
const ANALYTICS_APP_NAME = "yourApp";
// PackageUsageLogのデータ用JSONです。
const METADATA_JSON_STRING = `{"fileFormat":{"charsetName":"UTF-8","fieldsDelimitedBy":",","linesTerminatedBy":"\\n"},"objects":[{"connector":"CSV","fullyQualifiedName":"X0e4581f5_a821_467e_b81b_84f3d9f7d6fa_results_csv","label":"0e4581f5-a821-467e-b81b-84f3d9f7d6fa_results.csv","name":"X0e4581f5_a821_467e_b81b_84f3d9f7d6fa_results_csv","fields":[{"fullyQualifiedName":"timestamp_derived","name":"timestamp_derived","type":"Date","label":"timestamp_derived","format":"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"},{"fullyQualifiedName":"log_record_type","name":"log_record_type","type":"Text","label":"log_record_type"},{"fullyQualifiedName":"request_id","name":"request_id","type":"Text","label":"request_id"},{"fullyQualifiedName":"organization_id","name":"organization_id","type":"Text","label":"organization_id"},{"fullyQualifiedName":"organization_name","name":"organization_name","type":"Text","label":"organization_name"},{"fullyQualifiedName":"organization_status","name":"organization_status","type":"Text","label":"organization_status"},{"fullyQualifiedName":"organization_edition","name":"organization_edition","type":"Text","label":"organization_edition"},{"fullyQualifiedName":"organization_country_code","name":"organization_country_code","type":"Text","label":"organization_country_code"},{"fullyQualifiedName":"organization_language_locale","name":"organization_language_locale","type":"Text","label":"organization_language_locale"},{"fullyQualifiedName":"organization_time_zone","name":"organization_time_zone","type":"Text","label":"organization_time_zone"},{"fullyQualifiedName":"organization_instance","name":"organization_instance","type":"Text","label":"organization_instance"},{"fullyQualifiedName":"organization_type","name":"organization_type","type":"Text","label":"organization_type"},{"fullyQualifiedName":"cloned_from_organization_id","name":"cloned_from_organization_id","type":"Text","label":"cloned_from_organization_id"},{"fullyQualifiedName":"user_id_token","name":"user_id_token","type":"Text","label":"user_id_token"},{"fullyQualifiedName":"user_type","name":"user_type","type":"Text","label":"user_type"},{"fullyQualifiedName":"url","name":"url","type":"Text","label":"url"},{"fullyQualifiedName":"package_id","name":"package_id","type":"Text","label":"package_id"},{"fullyQualifiedName":"package_version_id","name":"package_version_id","type":"Text","label":"package_version_id"},{"fullyQualifiedName":"managed_package_namespace","name":"managed_package_namespace","type":"Text","label":"managed_package_namespace"},{"fullyQualifiedName":"custom_entity","name":"custom_entity","type":"Text","label":"custom_entity"},{"fullyQualifiedName":"custom_entity_type","name":"custom_entity_type","type":"Text","label":"custom_entity_type"},{"fullyQualifiedName":"operation_type","name":"operation_type","type":"Text","label":"operation_type"},{"fullyQualifiedName":"operation_count","name":"operation_count","type":"Numeric","label":"operation_count","precision":18,"defaultValue":"0","scale":0,"format":"0","decimalSeparator":"","groupsSeparator":"","currencySymbol":""},{"fullyQualifiedName":"request_status","name":"request_status","type":"Text","label":"request_status"},{"fullyQualifiedName":"referrer_uri","name":"referrer_uri","type":"Text","label":"referrer_uri"},{"fullyQualifiedName":"session_key","name":"session_key","type":"Text","label":"session_key"},{"fullyQualifiedName":"login_key","name":"login_key","type":"Text","label":"login_key"},{"fullyQualifiedName":"user_agent","name":"user_agent","type":"Text","label":"user_agent"},{"fullyQualifiedName":"user_country_code","name":"user_country_code","type":"Text","label":"user_country_code"},{"fullyQualifiedName":"user_time_zone","name":"user_time_zone","type":"Text","label":"user_time_zone"},{"fullyQualifiedName":"api_type","name":"api_type","type":"Text","label":"api_type"},{"fullyQualifiedName":"api_version","name":"api_version","type":"Numeric","label":"api_version","precision":18,"defaultValue":"0","scale":1,"format":"0.0","decimalSeparator":".","groupsSeparator":"","currencySymbol":""},{"fullyQualifiedName":"rows_processed","name":"rows_processed","type":"Text","label":"rows_processed"},{"fullyQualifiedName":"request_size","name":"request_size","type":"Numeric","label":"request_size","precision":18,"defaultValue":"0","scale":0,"format":"0","decimalSeparator":"","groupsSeparator":"","currencySymbol":""},{"fullyQualifiedName":"response_size","name":"response_size","type":"Numeric","label":"response_size","precision":18,"defaultValue":"0","scale":0,"format":"0","decimalSeparator":"","groupsSeparator":"","currencySymbol":""},{"fullyQualifiedName":"http_method","name":"http_method","type":"Text","label":"http_method"},{"fullyQualifiedName":"http_status_code","name":"http_status_code","type":"Text","label":"http_status_code"},{"fullyQualifiedName":"num_fields","name":"num_fields","type":"Text","label":"num_fields"},{"fullyQualifiedName":"app_name","name":"app_name","type":"Text","label":"app_name"},{"fullyQualifiedName":"page_app_name","name":"page_app_name","type":"Text","label":"page_app_name"},{"fullyQualifiedName":"page_context","name":"page_context","type":"Text","label":"page_context"},{"fullyQualifiedName":"ui_event_source","name":"ui_event_source","type":"Text","label":"ui_event_source"},{"fullyQualifiedName":"ui_event_type","name":"ui_event_type","type":"Text","label":"ui_event_type"},{"fullyQualifiedName":"ui_event_sequence_num","name":"ui_event_sequence_num","type":"Text","label":"ui_event_sequence_num"},{"fullyQualifiedName":"target_ui_element","name":"target_ui_element","type":"Text","label":"target_ui_element"},{"fullyQualifiedName":"parent_ui_element","name":"parent_ui_element","type":"Text","label":"parent_ui_element"},{"fullyQualifiedName":"page_url","name":"page_url","type":"Text","label":"page_url"},{"fullyQualifiedName":"prevpage_url","name":"prevpage_url","type":"Text","label":"prevpage_url"},{"fullyQualifiedName":"class_name","name":"class_name","type":"Text","label":"class_name"},{"fullyQualifiedName":"method_name","name":"method_name","type":"Text","label":"method_name"},{"fullyQualifiedName":"event","name":"event","type":"Text","label":"event"},{"fullyQualifiedName":"event_subscriber","name":"event_subscriber","type":"Text","label":"event_subscriber"},{"fullyQualifiedName":"event_count","name":"event_count","type":"Text","label":"event_count"},{"fullyQualifiedName":"entry_point","name":"entry_point","type":"Text","label":"entry_point"},{"fullyQualifiedName":"quiddity","name":"quiddity","type":"Text","label":"quiddity"},{"fullyQualifiedName":"num_soql_queries","name":"num_soql_queries","type":"Numeric","label":"num_soql_queries","precision":18,"defaultValue":"0","scale":0,"format":"0","decimalSeparator":"","groupsSeparator":"","currencySymbol":""},{"fullyQualifiedName":"stack_trace","name":"stack_trace","type":"Text","label":"stack_trace"},{"fullyQualifiedName":"bulk_job_id","name":"bulk_job_id","type":"Text","label":"bulk_job_id"},{"fullyQualifiedName":"bulk_batch_id","name":"bulk_batch_id","type":"Text","label":"bulk_batch_id"},{"fullyQualifiedName":"bulk_operation","name":"bulk_operation","type":"Text","label":"bulk_operation"}]}]}`;
const CHUNK_SIZE = 1024 * 1024 * 9; // 9MB;
const DOWNLOAD_URL = 'AppAnalyticsQueryRequest.DownloadUrl';
const ACCESS_TOKEN = 'yourAccessToken';
const fileResponse = await fetch(DOWNLOAD_URL);
const blob = await fileResponse.blob();
const blobToBase64 = async (blob) => {
const arrayBuffer = await blob.arrayBuffer();
return arrayBufferToBase64(arrayBuffer);
};
const arrayBufferToBase64 = (buffer) => {
let binary = "";
const bytes = new Uint8Array(buffer);
for (let i = 0; i < bytes.byteLength; i++) {
binary += String.fromCharCode(bytes[i]);
}
return btoa(binary);
};
// InsightsExternalDataの作成
const response = await fetch(
`${INSTANCE_URL}/services/data/v${API_VERSION}/sobjects/InsightsExternalData/`,
{
method: "POST",
body: JSON.stringify({
Format: "Csv",
EdgemartAlias: "alias",
EdgemartContainer: ANALYTICS_APP_NAME,
Action: "None",
Operation: "Overwrite",
EdgemartLabel: "label",
FileName: filename,
MetadataJson: await blobToBase64(
new Blob([METADATA_JSON_STRING], { type: "application/json" })
),
}),
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
}
).catch((error) =>
console.error("Error at createInsightsExternalData:", error)
);
const insightsExternalDataId = (await response.json()).id;
// InsightsExternalDataPartの作成。ファイルデータをアップロードします。
for (let i = 0; i < blob.size; i += CHUNK_SIZE) {
const partNumber = i / CHUNK_SIZE + 1;
const chunk = blob.slice(i, i + CHUNK_SIZE);
await fetch(
`${INSTANCE_URL}/services/data/v${API_VERSION}/sobjects/InsightsExternalDataPart/`,
{
method: "POST",
body: JSON.stringify({
InsightsExternalDataId: insightsExternalDataId,
PartNumber: partNumber,
DataFile: await blobToBase64(new Blob([chunk], { type: "text/csv" })),
}),
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
}
).catch((error) =>
console.error("Error at createInsightsExternalDataPart:", error)
);
}
// InsightsExternalDataのActionをProcessに更新し、データ処理をリクエストします。
await fetch(
`${instanceUrl}/services/data/v${API_VERSION}/sobjects/InsightsExternalData/${insightsExternalDataId}`,
{
method: "PATCH",
body: JSON.stringify({
Action: "Process",
MetadataJson: await blobToBase64(
new Blob([METADATA_JSON_STRING], { type: "application/json" })
),
}),
headers: {
Authorization: `Bearer ${ACCESS_TOKEN}`,
"Content-Type": "application/json",
},
}
).catch((error) =>
console.error("Error at submitInsightsExternalData:", error)
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment