Skip to content

Commit 97f6b13

Browse files
fix: simplify create command
1 parent 392a756 commit 97f6b13

2 files changed

Lines changed: 662 additions & 148 deletions

File tree

src/commands/org/create/agent-user.ts

Lines changed: 82 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,6 @@ export type AgentUserCreateResponse = {
2929
permissionSetErrors: Array<{ permissionSet: string; error: string }>;
3030
};
3131

32-
type UserLicenseInfo = {
33-
totalLicenses: number;
34-
usedLicenses: number;
35-
availableLicenses: number;
36-
};
37-
3832
export default class OrgCreateAgentUser extends SfCommand<AgentUserCreateResponse> {
3933
public static readonly summary = messages.getMessage('summary');
4034
public static readonly description = messages.getMessage('description');
@@ -78,12 +72,8 @@ export default class OrgCreateAgentUser extends SfCommand<AgentUserCreateRespons
7872
const profileId = await this.getProfileId(connection);
7973
this.log('Using profile: Einstein Agent User');
8074

81-
// Infer locale settings from current user
82-
const localeSettings = await this.inferLocaleSettings(connection);
83-
this.log(`Using locale settings from org: ${localeSettings.locale}`);
84-
8575
// Create the agent user
86-
const userId = await this.createAgentUser(connection, username, profileId, localeSettings, {
76+
const userId = await this.createAgentUser(connection, username, profileId, {
8777
firstName: flags['first-name'],
8878
lastName: flags['last-name'],
8979
});
@@ -183,69 +173,69 @@ export default class OrgCreateAgentUser extends SfCommand<AgentUserCreateRespons
183173
}
184174

185175
private async checkAgentUserLicenses(connection: Connection): Promise<void> {
186-
try {
187-
// Query for Agentforce Service Agent license type
188-
const licenseQuery = `
189-
SELECT TotalLicenses, UsedLicenses, Name, MasterLabel
190-
FROM UserLicense
191-
WHERE Name LIKE '%Agent%' OR MasterLabel LIKE '%Agent%'
192-
`;
193-
const licenseResult = await connection.query<{
194-
TotalLicenses: number;
195-
UsedLicenses: number;
176+
// Query the Einstein Agent User profile to get its associated license
177+
const profileResult = await connection.query<{
178+
UserLicense: {
179+
Id: string;
196180
Name: string;
197181
MasterLabel: string;
198-
}>(licenseQuery);
199-
200-
if (licenseResult.totalSize === 0) {
201-
throw new SfError(
202-
'No Agent user licenses found in this org. Agent user licenses are required to create agent users.',
203-
'NoAgentLicensesError',
204-
[
205-
'Contact your Salesforce account team to add Agent user licenses to your org',
206-
'Verify that Agentforce is enabled for your org',
207-
]
208-
);
209-
}
182+
TotalLicenses: number;
183+
UsedLicenses: number;
184+
};
185+
}>(`
186+
SELECT UserLicense.Id, UserLicense.Name, UserLicense.MasterLabel,
187+
UserLicense.TotalLicenses, UserLicense.UsedLicenses
188+
FROM Profile
189+
WHERE Name = 'Einstein Agent User'
190+
`);
191+
192+
if (profileResult.totalSize === 0) {
193+
throw new SfError(
194+
'Einstein Agent User profile not found in this org. This profile is required for agent users.',
195+
'ProfileNotFoundError',
196+
[
197+
'Verify that Agentforce is enabled for your org',
198+
'Contact your Salesforce account team to enable Agentforce features',
199+
]
200+
);
201+
}
210202

211-
// Check each license type for availability
212-
const licenseInfo: UserLicenseInfo[] = licenseResult.records.map((record) => ({
213-
totalLicenses: record.TotalLicenses,
214-
usedLicenses: record.UsedLicenses,
215-
availableLicenses: record.TotalLicenses - record.UsedLicenses,
216-
}));
203+
const license = profileResult.records[0].UserLicense;
204+
if (!license) {
205+
throw new SfError(
206+
'No license information found for Einstein Agent User profile. This may indicate an org configuration issue.',
207+
'NoAgentLicensesError',
208+
['Contact your Salesforce account team', 'Verify that Agentforce is properly configured in your org']
209+
);
210+
}
217211

218-
const hasAvailableLicense = licenseInfo.some((info) => info.availableLicenses > 0);
212+
// Check if licenses are available
213+
const availableLicenses = license.TotalLicenses - license.UsedLicenses;
219214

220-
if (!hasAvailableLicense) {
221-
const licenseDetails = licenseResult.records
222-
.map((r) => `${r.MasterLabel}: ${r.UsedLicenses}/${r.TotalLicenses} used`)
223-
.join(', ');
224-
throw new SfError(
225-
`No available Agent user licenses in this org. License usage: ${licenseDetails}`,
226-
'NoAvailableAgentLicensesError',
227-
[
228-
'Remove an existing agent user to free up a license',
229-
'Contact your Salesforce account team to add more Agent user licenses',
230-
]
231-
);
232-
}
215+
if (license.TotalLicenses === 0) {
216+
throw new SfError(
217+
`No ${license.MasterLabel} licenses are provisioned in this org. These licenses are required to create agent users.`,
218+
'NoAgentLicensesError',
219+
[
220+
`Contact your Salesforce account team to add ${license.MasterLabel} licenses to your org`,
221+
'Verify that Agentforce is enabled for your org',
222+
]
223+
);
224+
}
233225

234-
// Log license availability
235-
licenseResult.records.forEach((record) => {
236-
const available = record.TotalLicenses - record.UsedLicenses;
237-
this.log(`${record.MasterLabel}: ${available} of ${record.TotalLicenses} licenses available`);
238-
});
239-
} catch (error) {
240-
if (error instanceof SfError) {
241-
throw error;
242-
}
226+
if (availableLicenses <= 0) {
243227
throw new SfError(
244-
`Failed to check agent user license availability: ${error instanceof Error ? error.message : String(error)}`,
245-
'LicenseCheckError',
246-
['Verify your connection to the org', 'Check that you have permission to query UserLicense records']
228+
`No available ${license.MasterLabel} licenses in this org. License usage: ${license.UsedLicenses}/${license.TotalLicenses} used`,
229+
'NoAvailableAgentLicensesError',
230+
[
231+
'Remove an existing agent user to free up a license',
232+
`Contact your Salesforce account team to add more ${license.MasterLabel} licenses`,
233+
]
247234
);
248235
}
236+
237+
// Log license availability
238+
this.log(`${license.MasterLabel}: ${availableLicenses} of ${license.TotalLicenses} licenses available`);
249239
}
250240

251241
// eslint-disable-next-line class-methods-use-this
@@ -272,101 +262,45 @@ export default class OrgCreateAgentUser extends SfCommand<AgentUserCreateRespons
272262
}
273263
}
274264

275-
private async inferLocaleSettings(connection: Connection): Promise<{
276-
timeZone: string;
277-
locale: string;
278-
emailEncoding: string;
279-
language: string;
280-
}> {
281-
try {
282-
// Get locale settings from the current user (the one running the command)
283-
const userId = connection.getAuthInfoFields().userId;
284-
if (!userId) {
285-
throw new Error('Unable to determine current user ID');
286-
}
287-
288-
const soql = `SELECT TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, LanguageLocaleKey FROM User WHERE Id = '${userId}'`;
289-
const userResult = await connection.singleRecordQuery<{
290-
TimeZoneSidKey: string;
291-
LocaleSidKey: string;
292-
EmailEncodingKey: string;
293-
LanguageLocaleKey: string;
294-
}>(soql);
295-
296-
return {
297-
timeZone: userResult.TimeZoneSidKey,
298-
locale: userResult.LocaleSidKey,
299-
emailEncoding: userResult.EmailEncodingKey,
300-
language: userResult.LanguageLocaleKey,
301-
};
302-
} catch (error) {
303-
// Fallback to sensible defaults if we can't query the current user
304-
this.warn('Unable to infer locale settings from current user, using defaults');
305-
return {
306-
timeZone: 'America/Los_Angeles',
307-
locale: 'en_US',
308-
emailEncoding: 'UTF-8',
309-
language: 'en_US',
310-
};
311-
}
312-
}
313-
314265
// eslint-disable-next-line class-methods-use-this
315266
private async createAgentUser(
316267
connection: Connection,
317268
username: string,
318269
profileId: string,
319-
localeSettings: {
320-
timeZone: string;
321-
locale: string;
322-
emailEncoding: string;
323-
language: string;
324-
},
325270
nameFields: {
326271
firstName: string;
327272
lastName: string;
328273
}
329274
): Promise<string> {
330-
try {
331-
// Generate alias from username (max 8 chars)
332-
// Take first part before @ or first 8 chars of username
333-
const aliasPart = username.split('@')[0].replace(/[^a-zA-Z0-9]/g, '');
334-
const alias = aliasPart.substring(0, 8);
335-
336-
const userRecord = await connection.sobject('User').create({
337-
FirstName: nameFields.firstName,
338-
LastName: nameFields.lastName,
339-
Alias: alias,
340-
Email: username,
341-
Username: username,
342-
ProfileId: profileId,
343-
TimeZoneSidKey: localeSettings.timeZone,
344-
LocaleSidKey: localeSettings.locale,
345-
EmailEncodingKey: localeSettings.emailEncoding,
346-
LanguageLocaleKey: localeSettings.language,
347-
});
348-
349-
if (!userRecord.success || !userRecord.id) {
350-
const errorMessages = userRecord.errors?.map((e) => e.message).join(', ') ?? 'Unknown error';
351-
throw new SfError(`Failed to create agent user: ${errorMessages}`, 'UserCreationError', [
352-
'Verify that the username is globally unique',
353-
'Ensure the Einstein Agent User profile exists in your org',
354-
'Check that Agentforce is enabled for your org',
355-
'Verify you have permission to create User records',
356-
]);
357-
}
275+
// Generate alias from username (max 8 chars)
276+
// Take first part before @ or first 8 chars of username
277+
const aliasPart = username.split('@')[0].replace(/[^a-zA-Z0-9]/g, '');
278+
const alias = aliasPart.substring(0, 8);
279+
280+
const userRecord = await connection.sobject('User').create({
281+
FirstName: nameFields.firstName,
282+
LastName: nameFields.lastName,
283+
Alias: alias,
284+
Email: username,
285+
Username: username,
286+
ProfileId: profileId,
287+
TimeZoneSidKey: 'America/Los_Angeles',
288+
LocaleSidKey: 'en_US',
289+
EmailEncodingKey: 'UTF-8',
290+
LanguageLocaleKey: 'en_US',
291+
});
358292

359-
return userRecord.id;
360-
} catch (error) {
361-
if (error instanceof SfError) {
362-
throw error;
363-
}
364-
throw new SfError(
365-
`Failed to create agent user: ${error instanceof Error ? error.message : String(error)}`,
366-
'UserCreationError',
367-
['Verify your connection to the org', 'Check that you have permission to create User records']
368-
);
293+
if (!userRecord.success || !userRecord.id) {
294+
const errorMessages = userRecord.errors?.map((e) => e.message).join(', ') ?? 'Unknown error';
295+
throw new SfError(`Failed to create agent user: ${errorMessages}`, 'UserCreationError', [
296+
'Verify that the username is globally unique',
297+
'Ensure the Einstein Agent User profile exists in your org',
298+
'Check that Agentforce is enabled for your org',
299+
'Verify you have permission to create User records',
300+
]);
369301
}
302+
303+
return userRecord.id;
370304
}
371305

372306
private async assignPermissionSets(

0 commit comments

Comments
 (0)