sfdx-hardis 6.16.1-alpha202512161824.0 → 6.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -6
- package/lib/commands/hardis/datacloud/extract/agentforce-conversations.d.ts +14 -0
- package/lib/commands/hardis/datacloud/extract/agentforce-conversations.js +283 -0
- package/lib/commands/hardis/datacloud/extract/agentforce-conversations.js.map +1 -0
- package/lib/commands/hardis/datacloud/extract/agentforce-feedback.d.ts +14 -0
- package/lib/commands/hardis/datacloud/extract/agentforce-feedback.js +331 -0
- package/lib/commands/hardis/datacloud/extract/agentforce-feedback.js.map +1 -0
- package/lib/commands/hardis/datacloud/sql-query.d.ts +14 -0
- package/lib/commands/hardis/datacloud/sql-query.js +145 -0
- package/lib/commands/hardis/datacloud/sql-query.js.map +1 -0
- package/lib/commands/hardis/org/select.js +1 -1
- package/lib/commands/hardis/org/select.js.map +1 -1
- package/lib/common/notifProvider/emailProvider.js +6 -1
- package/lib/common/notifProvider/emailProvider.js.map +1 -1
- package/lib/common/notifProvider/index.d.ts +2 -1
- package/lib/common/notifProvider/index.js.map +1 -1
- package/lib/common/notifProvider/notifProviderRoot.js +3 -0
- package/lib/common/notifProvider/notifProviderRoot.js.map +1 -1
- package/lib/common/utils/agentforceQueryUtils.d.ts +48 -0
- package/lib/common/utils/agentforceQueryUtils.js +373 -0
- package/lib/common/utils/agentforceQueryUtils.js.map +1 -0
- package/lib/common/utils/authUtils.js +16 -3
- package/lib/common/utils/authUtils.js.map +1 -1
- package/lib/common/utils/dataCloudUtils.d.ts +39 -0
- package/lib/common/utils/dataCloudUtils.js +279 -0
- package/lib/common/utils/dataCloudUtils.js.map +1 -0
- package/lib/common/utils/filesUtils.d.ts +12 -13
- package/lib/common/utils/filesUtils.js +114 -43
- package/lib/common/utils/filesUtils.js.map +1 -1
- package/lib/common/utils/orgUtils.js +5 -1
- package/lib/common/utils/orgUtils.js.map +1 -1
- package/lib/common/utils/utilsAgentforceQuery.d.ts +1 -0
- package/lib/common/utils/utilsAgentforceQuery.js +2 -0
- package/lib/common/utils/utilsAgentforceQuery.js.map +1 -0
- package/oclif.lock +697 -697
- package/oclif.manifest.json +1848 -1463
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -49,6 +49,10 @@ ___
|
|
|
49
49
|
|
|
50
50
|
___
|
|
51
51
|
|
|
52
|
+
_Featured on SalesforceBen_
|
|
53
|
+
|
|
54
|
+
[](https://www.youtube.com/watch?v=vtWx_IWoL9k)
|
|
55
|
+
|
|
52
56
|
_See Dreamforce presentation_
|
|
53
57
|
|
|
54
58
|
[](https://www.youtube.com/watch?v=o0Mm9F07UFs)
|
|
@@ -144,17 +148,21 @@ sf hardis:<COMMAND> <OPTIONS>
|
|
|
144
148
|
|
|
145
149
|
<!-- events.md start -->
|
|
146
150
|
|
|
147
|
-
###
|
|
151
|
+
### French Touch Dreamin '25
|
|
152
|
+
|
|
153
|
+
Refresh your full sandboxes without needing to reconfigure everything — with [Mehdi Abdennasser](https://www.linkedin.com/in/mehdi-abdennasser/)
|
|
148
154
|
|
|
149
|
-
|
|
155
|
+
Paris, France — 02/12/2025
|
|
150
156
|
|
|
151
|
-
<img width="
|
|
157
|
+
<img width="1920" height="1080" alt="Untitled design (14)" src="https://github.com/user-attachments/assets/853b9d66-973e-43ef-bfcf-fe044d1d4d94" />
|
|
152
158
|
|
|
153
|
-
###
|
|
159
|
+
### DevOps Dreamin
|
|
154
160
|
|
|
155
|
-
|
|
161
|
+
Why you don't need DevOps vendors tools
|
|
156
162
|
|
|
157
|
-
|
|
163
|
+
London, UK — 20/11/2025
|
|
164
|
+
|
|
165
|
+
<img width="1920" height="1080" alt="Untitled design (13)" src="https://github.com/user-attachments/assets/d626363c-64af-43fb-b0a0-d2f0afcb9c1d" />
|
|
158
166
|
|
|
159
167
|
### Trailblazer User Group '25, Casablanca
|
|
160
168
|
|
|
@@ -271,6 +279,10 @@ Here are some articles about [sfdx-hardis](https://sfdx-hardis.cloudity.com/)
|
|
|
271
279
|
|
|
272
280
|
### Podcasts
|
|
273
281
|
|
|
282
|
+
- SalesforceBen Deep Dives with Peter Chittum, 2025: _**Simplify Salesforce Deployment with SFDX Hardis**_
|
|
283
|
+
|
|
284
|
+
[](https://www.youtube.com/watch?v=vtWx_IWoL9k)
|
|
285
|
+
|
|
274
286
|
- Apex Hours 2025 - Org monitoring with Grafana + AI generated doc
|
|
275
287
|
|
|
276
288
|
[](https://www.youtube.com/watch?v=oDaCh66pRcI){target=blank}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SfCommand } from "@salesforce/sf-plugins-core";
|
|
2
|
+
import { AnyJson } from "@salesforce/ts-types";
|
|
3
|
+
export default class DataCloudExtractAgentforceConversations extends SfCommand<any> {
|
|
4
|
+
static title: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: any;
|
|
8
|
+
static requiresProject: boolean;
|
|
9
|
+
protected debugMode: boolean;
|
|
10
|
+
protected queryString: string;
|
|
11
|
+
protected outputFile: any;
|
|
12
|
+
protected outputFilesRes: any;
|
|
13
|
+
run(): Promise<AnyJson>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { Messages } from "@salesforce/core";
|
|
2
|
+
import { Flags, requiredOrgFlagWithDeprecations, SfCommand } from "@salesforce/sf-plugins-core";
|
|
3
|
+
import { dataCloudSqlQuery } from "../../../../common/utils/dataCloudUtils.js";
|
|
4
|
+
import { uxLog } from "../../../../common/utils/index.js";
|
|
5
|
+
import { generateCsvFile, generateReportPath } from "../../../../common/utils/filesUtils.js";
|
|
6
|
+
import c from "chalk";
|
|
7
|
+
import { buildConversation, buildConversationUrl, buildDateFilterClause, buildExcludedSessionFilter, extractSessionIds, extractSpeakerSegment, fetchConversationTranscripts, normalizeKeys, pickFirstMeaningfulValue, resolveConversationLinkDomain, resolveDateFilterOptions, resolveExcludedConversationIds, sanitizePlaceholderValue, stringValue, } from "../../../../common/utils/agentforceQueryUtils.js";
|
|
8
|
+
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
|
|
9
|
+
const messages = Messages.loadMessages('sfdx-hardis', 'org');
|
|
10
|
+
export default class DataCloudExtractAgentforceConversations extends SfCommand {
|
|
11
|
+
static title = 'Extract Agentforce Conversations Data from Data Cloud';
|
|
12
|
+
static description = `
|
|
13
|
+
## Command Behavior
|
|
14
|
+
|
|
15
|
+
**Extracts Agentforce conversations data from Data Cloud and generates a detailed report.**
|
|
16
|
+
|
|
17
|
+
This command allows you to retrieve and analyze conversations between users and Agentforce agents. It fetches conversation details, including transcripts, user utterances, agent responses, and any associated feedback.
|
|
18
|
+
|
|
19
|
+
Key functionalities:
|
|
20
|
+
|
|
21
|
+
- **Data Extraction:** Queries Data Cloud for Agentforce conversation records.
|
|
22
|
+
- **Transcript Retrieval:** Fetches full conversation transcripts associated with the sessions.
|
|
23
|
+
- **Filtering:** Supports filtering by date range (from/to) or a rolling window (last N days).
|
|
24
|
+
- **Report Generation:** Creates a CSV and XLSX report containing:
|
|
25
|
+
- User information
|
|
26
|
+
- Date and time
|
|
27
|
+
- Full conversation transcript
|
|
28
|
+
- Feedback sentiment and message (if available)
|
|
29
|
+
- Direct link to the conversation in Salesforce
|
|
30
|
+
- **Link Generation:** Generates clickable URLs to view the conversation in the Agentforce Analytics dashboard.
|
|
31
|
+
|
|
32
|
+
<details markdown="1">
|
|
33
|
+
<summary>Technical explanations</summary>
|
|
34
|
+
|
|
35
|
+
The command's technical implementation involves:
|
|
36
|
+
|
|
37
|
+
- **Data Cloud Query:** Executes a SQL query against Data Cloud tables (\`GenAIGeneration__dlm\`, \`GenAIGatewayRequest__dlm\`, etc.) to retrieve conversation metadata and individual turns.
|
|
38
|
+
- **Session Management:** Extracts session IDs from the initial query results.
|
|
39
|
+
- **Transcript Fetching:** Asynchronously fetches full conversation transcripts for the identified sessions in chunks to handle large volumes efficiently.
|
|
40
|
+
- **Data Merging:** Combines the SQL query results with the fetched transcripts, prioritizing full transcripts over individual turn data when available.
|
|
41
|
+
- **URL Construction:** dynamically builds deep links to the Salesforce Lightning Experience for each conversation based on the org's instance URL and conversation ID.
|
|
42
|
+
- **File Output:** Uses \`generateCsvFile\` to output the processed data into CSV and XLSX formats with custom column widths and formatting.
|
|
43
|
+
- **Exclusion Filters:** Supports excluding specific conversations or sessions via environment variables \`AGENTFORCE_FEEDBACK_EXCLUDED_CONV_IDS\` and \`AGENTFORCE_EXCLUDED_SESSION_IDS\` (comma-separated IDs).
|
|
44
|
+
</details>
|
|
45
|
+
`;
|
|
46
|
+
static examples = [
|
|
47
|
+
'$ sf hardis:datacloud:extract:agentforce-conversations',
|
|
48
|
+
];
|
|
49
|
+
static flags = {
|
|
50
|
+
outputfile: Flags.string({
|
|
51
|
+
char: 'f',
|
|
52
|
+
description: 'Force the path and name of output report file. Must end with .csv',
|
|
53
|
+
}),
|
|
54
|
+
debug: Flags.boolean({
|
|
55
|
+
char: 'd',
|
|
56
|
+
default: false,
|
|
57
|
+
description: messages.getMessage('debugMode'),
|
|
58
|
+
}),
|
|
59
|
+
'date-from': Flags.string({
|
|
60
|
+
description: 'Optional ISO-8601 timestamp (UTC) to include conversations starting from this date',
|
|
61
|
+
}),
|
|
62
|
+
'date-to': Flags.string({
|
|
63
|
+
description: 'Optional ISO-8601 timestamp (UTC) to include conversations up to this date',
|
|
64
|
+
}),
|
|
65
|
+
'last-n-days': Flags.integer({
|
|
66
|
+
description: 'Optional rolling window (days) to include only the most recent conversations',
|
|
67
|
+
}),
|
|
68
|
+
websocket: Flags.string({
|
|
69
|
+
description: messages.getMessage('websocket'),
|
|
70
|
+
}),
|
|
71
|
+
skipauth: Flags.boolean({
|
|
72
|
+
description: 'Skip authentication check when a default username is required',
|
|
73
|
+
}),
|
|
74
|
+
'target-org': requiredOrgFlagWithDeprecations,
|
|
75
|
+
};
|
|
76
|
+
static requiresProject = false;
|
|
77
|
+
debugMode = false;
|
|
78
|
+
queryString = '';
|
|
79
|
+
outputFile;
|
|
80
|
+
outputFilesRes = {};
|
|
81
|
+
/* jscpd:ignore-end */
|
|
82
|
+
async run() {
|
|
83
|
+
const { flags } = await this.parse(DataCloudExtractAgentforceConversations);
|
|
84
|
+
this.outputFile = flags.outputfile || null;
|
|
85
|
+
this.debugMode = flags.debug || false;
|
|
86
|
+
const conn = flags['target-org'].getConnection();
|
|
87
|
+
const conversationLinkDomain = resolveConversationLinkDomain(conn.instanceUrl);
|
|
88
|
+
const dateFilterOptions = resolveDateFilterOptions({
|
|
89
|
+
dateFromInput: flags['date-from'],
|
|
90
|
+
dateToInput: flags['date-to'],
|
|
91
|
+
lastNDaysInput: flags['last-n-days'],
|
|
92
|
+
});
|
|
93
|
+
this.queryString = buildConversationQuery(dateFilterOptions).trim();
|
|
94
|
+
uxLog("action", this, c.cyan("Querying Agentforce conversations..."));
|
|
95
|
+
const rawResult = await dataCloudSqlQuery(this.queryString, conn, {});
|
|
96
|
+
const sessionIds = extractSessionIds(rawResult.records, { sanitizer: sanitizePlaceholderValue });
|
|
97
|
+
uxLog("action", this, c.cyan("Fetching conversation transcripts..."));
|
|
98
|
+
const transcriptsBySession = await fetchConversationTranscripts(sessionIds, conn, {
|
|
99
|
+
chunkSize: 50,
|
|
100
|
+
sanitizeSessionId: sanitizePlaceholderValue,
|
|
101
|
+
});
|
|
102
|
+
uxLog("action", this, c.cyan("Building export records..."));
|
|
103
|
+
const exportRecords = buildConversationRecords(rawResult.records, {
|
|
104
|
+
conversationLinkDomain,
|
|
105
|
+
transcriptsBySession,
|
|
106
|
+
timeFilterDays: DEFAULT_CONVERSATION_TIME_FILTER_DAYS,
|
|
107
|
+
});
|
|
108
|
+
const result = { ...rawResult, records: exportRecords, returnedRows: exportRecords.length };
|
|
109
|
+
const { records: _records, ...resultCopy } = result;
|
|
110
|
+
void _records;
|
|
111
|
+
uxLog("other", this, JSON.stringify(resultCopy, null, 2));
|
|
112
|
+
this.outputFile = await generateReportPath('datacloud-agentforce-conversations', this.outputFile);
|
|
113
|
+
this.outputFilesRes = await generateCsvFile(exportRecords, this.outputFile, {
|
|
114
|
+
fileTitle: 'DataCloud Agentforce Conversations',
|
|
115
|
+
columnsCustomStyles: {
|
|
116
|
+
'DateTime': { width: 26 },
|
|
117
|
+
'Conversation transcript': { width: 90, wrap: true, maxHeight: 50 },
|
|
118
|
+
'Feedback': { width: 12 },
|
|
119
|
+
'Feedback message': { width: 45, wrap: true, maxHeight: 50 },
|
|
120
|
+
'ConversationId': { width: 36 },
|
|
121
|
+
'ConversationUrl': { width: 80, hyperlinkFromValue: true },
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
return {
|
|
125
|
+
result: JSON.parse(JSON.stringify(result)),
|
|
126
|
+
csvLogFile: this.outputFile,
|
|
127
|
+
xlsxLogFile: this.outputFilesRes?.xlsxFile,
|
|
128
|
+
conversationCount: exportRecords.length
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const DEFAULT_CONVERSATION_TIME_FILTER_DAYS = 365;
|
|
133
|
+
function buildConversationQuery(filters = {}) {
|
|
134
|
+
const dateFilterClause = buildDateFilterClause(filters);
|
|
135
|
+
const excludedConversationClause = buildExcludedConversationFilter();
|
|
136
|
+
const excludedSessionClause = buildExcludedSessionFilter();
|
|
137
|
+
return `
|
|
138
|
+
WITH conversation_base AS (
|
|
139
|
+
SELECT
|
|
140
|
+
COALESCE(usr.ssot__username__c, gar.userId__c) AS userName,
|
|
141
|
+
ggn.timestamp__c AS conversationDate,
|
|
142
|
+
gar.generationGroupId__c AS conversationId,
|
|
143
|
+
gar.gatewayRequestId__c AS gatewayRequestId,
|
|
144
|
+
gat.tagValue__c AS userUtterance,
|
|
145
|
+
ggn.responseText__c AS agentResponse,
|
|
146
|
+
ROW_NUMBER() OVER (
|
|
147
|
+
PARTITION BY gar.generationGroupId__c
|
|
148
|
+
ORDER BY ggn.timestamp__c DESC,
|
|
149
|
+
gar.gatewayRequestId__c DESC
|
|
150
|
+
) AS rowNum
|
|
151
|
+
FROM GenAIGeneration__dlm ggn
|
|
152
|
+
JOIN GenAIGatewayResponse__dlm grs ON ggn.generationResponseId__c = grs.generationResponseId__c
|
|
153
|
+
JOIN GenAIGatewayRequest__dlm gar ON grs.generationRequestId__c = gar.gatewayRequestId__c
|
|
154
|
+
LEFT JOIN GenAIGatewayRequestTag__dlm gat ON gar.gatewayRequestId__c = gat.parent__c AND gat.tag__c = 'user_utterance'
|
|
155
|
+
LEFT JOIN ssot__User__dlm usr ON usr.ssot__Id__c = gar.userId__c
|
|
156
|
+
WHERE gar.generationGroupId__c IS NOT NULL${excludedConversationClause}${dateFilterClause}
|
|
157
|
+
), session_lookup AS (
|
|
158
|
+
SELECT
|
|
159
|
+
ais.ssot__GenAiGatewayRequestId__c AS gatewayRequestId,
|
|
160
|
+
ai.ssot__AiAgentSessionId__c AS sessionId,
|
|
161
|
+
ROW_NUMBER() OVER (
|
|
162
|
+
PARTITION BY ais.ssot__GenAiGatewayRequestId__c
|
|
163
|
+
ORDER BY ais.ssot__StartTimestamp__c DESC
|
|
164
|
+
) AS rowNum
|
|
165
|
+
FROM ssot__AiAgentInteractionStep__dlm ais
|
|
166
|
+
JOIN ssot__AiAgentInteraction__dlm ai ON ai.ssot__Id__c = ais.ssot__AiAgentInteractionId__c
|
|
167
|
+
), session_agent_info AS (
|
|
168
|
+
SELECT
|
|
169
|
+
part.ssot__AiAgentSessionId__c AS sessionId,
|
|
170
|
+
MAX(part.ssot__AiAgentApiName__c) AS agentApiName
|
|
171
|
+
FROM ssot__AiAgentSessionParticipant__dlm part
|
|
172
|
+
WHERE part.ssot__AiAgentApiName__c IS NOT NULL
|
|
173
|
+
GROUP BY part.ssot__AiAgentSessionId__c
|
|
174
|
+
), latest_feedback AS (
|
|
175
|
+
SELECT
|
|
176
|
+
gaf.generationGroupId__c AS conversationId,
|
|
177
|
+
gaf.feedback__c AS feedbackSentiment,
|
|
178
|
+
gfd.feedbackText__c AS feedbackMessage,
|
|
179
|
+
COALESCE(
|
|
180
|
+
gaf.timestamp__c,
|
|
181
|
+
TIMESTAMP '1900-01-01 00:00:00Z'
|
|
182
|
+
) AS feedbackTimestamp,
|
|
183
|
+
ROW_NUMBER() OVER (
|
|
184
|
+
PARTITION BY gaf.generationGroupId__c
|
|
185
|
+
ORDER BY COALESCE(
|
|
186
|
+
gaf.timestamp__c,
|
|
187
|
+
TIMESTAMP '1900-01-01 00:00:00Z'
|
|
188
|
+
) DESC,
|
|
189
|
+
gaf.feedbackId__c DESC
|
|
190
|
+
) AS rowNum
|
|
191
|
+
FROM GenAIFeedback__dlm gaf
|
|
192
|
+
LEFT JOIN GenAIFeedbackDetail__dlm gfd ON gaf.feedbackId__c = gfd.parent__c
|
|
193
|
+
), conversation_primary AS (
|
|
194
|
+
SELECT *
|
|
195
|
+
FROM conversation_base
|
|
196
|
+
WHERE rowNum = 1
|
|
197
|
+
)
|
|
198
|
+
SELECT
|
|
199
|
+
base.userName,
|
|
200
|
+
base.conversationDate,
|
|
201
|
+
base.conversationId,
|
|
202
|
+
base.gatewayRequestId,
|
|
203
|
+
sess.sessionId,
|
|
204
|
+
agent.agentApiName,
|
|
205
|
+
base.userUtterance,
|
|
206
|
+
base.agentResponse,
|
|
207
|
+
fb.feedbackSentiment,
|
|
208
|
+
fb.feedbackMessage
|
|
209
|
+
FROM conversation_primary base
|
|
210
|
+
LEFT JOIN (SELECT gatewayRequestId, sessionId FROM session_lookup WHERE rowNum = 1) sess ON sess.gatewayRequestId = base.gatewayRequestId
|
|
211
|
+
LEFT JOIN session_agent_info agent ON agent.sessionId = sess.sessionId
|
|
212
|
+
LEFT JOIN (
|
|
213
|
+
SELECT conversationId, feedbackSentiment, feedbackMessage
|
|
214
|
+
FROM latest_feedback
|
|
215
|
+
WHERE rowNum = 1
|
|
216
|
+
) fb ON fb.conversationId = base.conversationId
|
|
217
|
+
${excludedSessionClause}
|
|
218
|
+
ORDER BY base.conversationDate DESC
|
|
219
|
+
;
|
|
220
|
+
`;
|
|
221
|
+
}
|
|
222
|
+
function buildConversationRecords(records, options) {
|
|
223
|
+
const safeRecords = Array.isArray(records) ? records : [];
|
|
224
|
+
const safeOptions = options || {
|
|
225
|
+
conversationLinkDomain: null,
|
|
226
|
+
transcriptsBySession: new Map(),
|
|
227
|
+
timeFilterDays: DEFAULT_CONVERSATION_TIME_FILTER_DAYS,
|
|
228
|
+
};
|
|
229
|
+
const filteredRecords = [];
|
|
230
|
+
const seenConversationIds = new Set();
|
|
231
|
+
safeRecords.forEach((record) => {
|
|
232
|
+
const normalized = normalizeKeys(record);
|
|
233
|
+
const conversationDate = stringValue(normalized["conversationdate"] ?? normalized["timestamp__c"]);
|
|
234
|
+
const userName = sanitizePlaceholderValue(stringValue(normalized["username"] ?? normalized["userid"]));
|
|
235
|
+
const rawSessionId = stringValue(normalized["sessionid"] ?? normalized["ssot__aiagentsessionid__c"]);
|
|
236
|
+
const sessionId = sanitizePlaceholderValue(rawSessionId);
|
|
237
|
+
const agentApiName = sanitizePlaceholderValue(stringValue(normalized["agentapiname"] ?? normalized["ssot__aiagentapiname__c"]));
|
|
238
|
+
const conversationId = sanitizePlaceholderValue(stringValue(normalized["conversationid"] ?? normalized["generationgroupid__c"]));
|
|
239
|
+
const baseUserUtterance = stringValue(normalized["userutterance"] ?? normalized["tagvalue__c"]);
|
|
240
|
+
const baseAgentResponse = stringValue(normalized["agentresponse"] ?? normalized["responsetext"]);
|
|
241
|
+
const feedbackValueRaw = sanitizePlaceholderValue(stringValue(normalized["feedbacksentiment"] ?? normalized["feedback__c"]));
|
|
242
|
+
const feedbackValue = feedbackValueRaw ? feedbackValueRaw.toUpperCase() : '';
|
|
243
|
+
const feedbackMessage = sanitizePlaceholderValue(stringValue(normalized["feedbackmessage"] ?? normalized["feedbacktext__c"]));
|
|
244
|
+
const transcript = sessionId ? safeOptions.transcriptsBySession.get(sessionId) || '' : '';
|
|
245
|
+
const transcriptUserUtterance = extractSpeakerSegment(transcript, 'USER');
|
|
246
|
+
const transcriptAgentResponse = extractSpeakerSegment(transcript, 'AGENT');
|
|
247
|
+
const resolvedUserUtterance = pickFirstMeaningfulValue([baseUserUtterance, transcriptUserUtterance]);
|
|
248
|
+
const resolvedAgentResponse = pickFirstMeaningfulValue([baseAgentResponse, transcriptAgentResponse]);
|
|
249
|
+
const conversation = transcript || buildConversation(resolvedUserUtterance, resolvedAgentResponse);
|
|
250
|
+
const conversationUrl = buildConversationUrl({
|
|
251
|
+
domain: safeOptions.conversationLinkDomain,
|
|
252
|
+
conversationId,
|
|
253
|
+
sessionId,
|
|
254
|
+
agentApiName,
|
|
255
|
+
timeFilterDays: safeOptions.timeFilterDays,
|
|
256
|
+
});
|
|
257
|
+
if (!conversationId || !conversationUrl) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
if (seenConversationIds.has(conversationId)) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
seenConversationIds.add(conversationId);
|
|
264
|
+
filteredRecords.push({
|
|
265
|
+
"User": userName,
|
|
266
|
+
"DateTime": conversationDate,
|
|
267
|
+
"Conversation transcript": conversation,
|
|
268
|
+
"Feedback": feedbackValue,
|
|
269
|
+
"Feedback message": feedbackMessage,
|
|
270
|
+
"ConversationId": conversationId,
|
|
271
|
+
"ConversationUrl": conversationUrl,
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
return filteredRecords;
|
|
275
|
+
}
|
|
276
|
+
function buildExcludedConversationFilter() {
|
|
277
|
+
const excludedConversationIds = resolveExcludedConversationIds();
|
|
278
|
+
if (!excludedConversationIds.length) {
|
|
279
|
+
return '';
|
|
280
|
+
}
|
|
281
|
+
return ` AND gar.generationGroupId__c NOT IN (${excludedConversationIds.map((id) => `'${id}'`).join(', ')})`;
|
|
282
|
+
}
|
|
283
|
+
//# sourceMappingURL=agentforce-conversations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agentforce-conversations.js","sourceRoot":"","sources":["../../../../../src/commands/hardis/datacloud/extract/agentforce-conversations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SfCommand } from "@salesforce/sf-plugins-core";
|
|
2
|
+
import { AnyJson } from "@salesforce/ts-types";
|
|
3
|
+
export default class DataCloudExtractAgentforceFeedback extends SfCommand<any> {
|
|
4
|
+
static title: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static flags: any;
|
|
8
|
+
static requiresProject: boolean;
|
|
9
|
+
protected debugMode: boolean;
|
|
10
|
+
protected queryString: string;
|
|
11
|
+
protected outputFile: any;
|
|
12
|
+
protected outputFilesRes: any;
|
|
13
|
+
run(): Promise<AnyJson>;
|
|
14
|
+
}
|