@@ -237,6 +237,70 @@ async function elmoOnboardingModal(body, client, respond, brandURL) {
237
237
} ) ;
238
238
}
239
239
240
+ async function elmoReonboardingModal ( body , client , respond , brandURL ) {
241
+ const { user } = body ;
242
+
243
+ // Update the original message to show user's choice
244
+ await respond ( {
245
+ text : `:gear: ${ user . name } started the reonboarding process... Missing configurations and entitlements will be added automatically.` ,
246
+ replace_original : true ,
247
+ } ) ;
248
+
249
+ // Capture original channel and thread context
250
+ const originalChannel = body . channel ?. id ;
251
+ const originalThreadTs = body . message ?. thread_ts || body . message ?. ts ;
252
+
253
+ await client . views . open ( {
254
+ trigger_id : body . trigger_id ,
255
+ view : {
256
+ type : 'modal' ,
257
+ callback_id : 'reonboard_llmo_modal' ,
258
+ private_metadata : JSON . stringify ( {
259
+ originalChannel,
260
+ originalThreadTs,
261
+ brandURL,
262
+ } ) ,
263
+ title : {
264
+ type : 'plain_text' ,
265
+ text : 'Reonboard Site' ,
266
+ } ,
267
+ submit : {
268
+ type : 'plain_text' ,
269
+ text : 'Update IMS Org ID' ,
270
+ } ,
271
+ close : {
272
+ type : 'plain_text' ,
273
+ text : 'Cancel' ,
274
+ } ,
275
+ blocks : [
276
+ {
277
+ type : 'section' ,
278
+ text : {
279
+ type : 'mrkdwn' ,
280
+ text : ':rocket: *Site Reonboarding*\n\nIf necessary, provide details to update the IMS organization ID.' ,
281
+ } ,
282
+ } ,
283
+ {
284
+ type : 'input' ,
285
+ block_id : 'ims_org_input' ,
286
+ element : {
287
+ type : 'plain_text_input' ,
288
+ action_id : 'ims_org_id' ,
289
+ placeholder : {
290
+ type : 'plain_text' ,
291
+ text : 'ABC123@AdobeOrg' ,
292
+ } ,
293
+ } ,
294
+ label : {
295
+ type : 'plain_text' ,
296
+ text : 'IMS Organization ID' ,
297
+ } ,
298
+ } ,
299
+ ] ,
300
+ } ,
301
+ } ) ;
302
+ }
303
+
240
304
async function createOrg ( imsOrgId , lambdaCtx , slackCtx ) {
241
305
const { log, imsClient, dataAccess } = lambdaCtx ;
242
306
const { say } = slackCtx ;
@@ -321,11 +385,9 @@ export function startLLMOOnboarding(lambdaContext) {
321
385
const brand = config . getLlmoBrand ( ) ;
322
386
323
387
if ( brand ) {
324
- await respond ( {
325
- text : `:update-progress: Brand ${ brand } of ${ brandURL } already onboarded; initiating reonboarding process` ,
326
- replace_original : true ,
327
- } ) ;
328
388
log . debug ( `Brand ${ brand } of ${ brandURL } already onboarded; initiating reonboarding process` ) ;
389
+ await elmoReonboardingModal ( body , client , respond , brandURL ) ;
390
+ return ;
329
391
}
330
392
331
393
await elmoOnboardingModal ( body , client , respond , brandURL ) ;
@@ -774,3 +836,94 @@ export function onboardLLMOModal(lambdaContext) {
774
836
}
775
837
} ;
776
838
}
839
+
840
+ /* c8 ignore start */
841
+ /* Handles submission */
842
+ export function reonboardLLMOModal ( lambdaContext ) {
843
+ const { dataAccess, log } = lambdaContext ;
844
+ const { Site } = dataAccess ;
845
+
846
+ return async ( { ack, body, client } ) => {
847
+ try {
848
+ log . debug ( 'Starting onboarding process...' ) ;
849
+ const { view, user } = body ;
850
+ const { values } = view . state ;
851
+
852
+ // Extract original channel and thread context from private metadata
853
+ let originalChannel ;
854
+ let originalThreadTs ;
855
+ let brandURL ;
856
+ try {
857
+ /* c8 ignore next */
858
+ const metadata = JSON . parse ( view . private_metadata || '{}' ) ;
859
+ originalChannel = metadata . originalChannel ;
860
+ originalThreadTs = metadata . originalThreadTs ;
861
+ brandURL = metadata . brandURL ;
862
+ } catch ( error ) {
863
+ log . warn ( 'Failed to parse private metadata:' , error ) ;
864
+ }
865
+
866
+ const imsOrgId = values . ims_org_input . ims_org_id . value ;
867
+
868
+ if ( ! imsOrgId ) {
869
+ await ack ( {
870
+ response_action : 'errors' ,
871
+ errors : {
872
+ ims_org_input : ! imsOrgId ? 'IMS Org ID is required' : undefined ,
873
+ } ,
874
+ } ) ;
875
+ return ;
876
+ }
877
+
878
+ log . info ( 'Onboarding request with parameters:' , {
879
+ imsOrgId,
880
+ brandURL,
881
+ originalChannel,
882
+ originalThreadTs,
883
+ } ) ;
884
+
885
+ // eslint-disable-next-line max-statements-per-line
886
+ await new Promise ( ( resolve ) => { setTimeout ( resolve , 500 ) ; } ) ;
887
+ await ack ( ) ;
888
+
889
+ // Create a slack context for the onboarding process
890
+ // Use original channel/thread if available, otherwise fall back to DM
891
+ const responseChannel = originalChannel || body . user . id ;
892
+ const responseThreadTs = originalChannel ? originalThreadTs : undefined ;
893
+
894
+ const slackContext = {
895
+ say : async ( message ) => {
896
+ await client . chat . postMessage ( {
897
+ channel : responseChannel ,
898
+ text : message ,
899
+ thread_ts : responseThreadTs ,
900
+ } ) ;
901
+ } ,
902
+ client,
903
+ channelId : responseChannel ,
904
+ threadTs : responseThreadTs ,
905
+ } ;
906
+
907
+ const site = await Site . findByBaseURL ( brandURL ) ;
908
+
909
+ await checkOrg ( imsOrgId , site , lambdaContext , slackContext ) ;
910
+
911
+ // create entitlement
912
+ await createEntitlementAndEnrollment ( site , lambdaContext , slackContext ) ;
913
+
914
+ // create OrganizationIdentiyProvider
915
+ await createOrganizationIdentityProvider ( site , lambdaContext , slackContext ) ;
916
+
917
+ log . debug ( `Reonboard LLMO modal processed for user ${ user . id } , site ${ brandURL } ` ) ;
918
+ } catch ( e ) {
919
+ log . error ( 'Error handling reonboard site modal:' , e ) ;
920
+ await ack ( {
921
+ response_action : 'errors' ,
922
+ errors : {
923
+ brand_name_input : 'There was an error processing the reonboarding request.' ,
924
+ } ,
925
+ } ) ;
926
+ }
927
+ } ;
928
+ }
929
+ /* c8 ignore end */
0 commit comments