@@ -40,6 +40,23 @@ export default async function ({ log, msg }, interaction) {
4040 const tmpdir = `/opt/discopy/backups/backup-${ backup . metadata . guildId || 'unknown' } -${ ts } ` ;
4141 try { await fs . mkdir ( tmpdir , { recursive : true } ) ; await fs . mkdir ( path . join ( tmpdir , 'emojis' ) , { recursive : true } ) ; await fs . mkdir ( path . join ( tmpdir , 'stickers' ) , { recursive : true } ) ; } catch ( err ) { log . warn ( 'Failed to create temp dirs' , { err : String ( err ) } ) ; }
4242
43+ // IMPORTANT: Ensure we have an up-to-date members cache before collecting member metadata.
44+ // This mirrors the fetch performed on client ready and ensures scheduled backups (which call this command
45+ // with a fake interaction) also pull all guild members before the backup is saved.
46+ try {
47+ if ( guild && guild . members && typeof guild . members . fetch === 'function' ) {
48+ try {
49+ log . info ( `Fetching members for guild ${ guild . id } (${ guild . name } ) before backup` ) ;
50+ await guild . members . fetch ( ) ;
51+ log . info ( `Fetched members for guild ${ guild . id } ; cached=${ guild . members . cache ? guild . members . cache . size : 'unknown' } ` ) ;
52+ } catch ( err ) {
53+ log . warn ( `Failed to fetch members for guild ${ guild . id } before backup: ${ String ( err ) } ` ) ;
54+ }
55+ }
56+ } catch ( err ) {
57+ log . warn ( 'Error attempting to fetch members before backup' , { err : String ( err ) } ) ;
58+ }
59+
4360 // Step 1: Guild settings
4461 try {
4562 backup . data . guild = await collectGuild ( guild , tmpdir , log ) ;
@@ -116,7 +133,17 @@ export default async function ({ log, msg }, interaction) {
116133 await markNext ( ) ;
117134
118135 // Step 11: Members metadata
119- try { backup . data . members = ( guild && guild . members && guild . members . cache ) ? guild . members . cache . map ( m => ( { id : m . id , user : { id : m . user ?. id || null , username : m . user ?. username || null } , nickname : m . nickname || null , roles : m . roles ? ( m . roles . cache ? m . roles . cache . map ( r => r . id ) : ( Array . isArray ( m . roles ) ? m . roles : [ ] ) ) : [ ] } ) ) : [ ] ; } catch ( err ) { log . warn ( 'Members failed' , { err : String ( err ) } ) ; backup . data . members = { error : String ( err ) } ; }
136+ try {
137+ try {
138+ // If members were not fetched earlier for some reason, attempt again immediately before collecting.
139+ if ( guild && guild . members && typeof guild . members . fetch === 'function' && ( ! guild . members . cache || ( guild . members . cache && guild . members . cache . size === 0 ) ) ) {
140+ log . info ( `Attempting members.fetch() for guild ${ guild ? guild . id : 'unknown' } right before member metadata collection` ) ;
141+ await guild . members . fetch ( ) . catch ( e => log . warn ( 'members.fetch() failed during members collection' , String ( e ) ) ) ;
142+ }
143+ } catch ( e ) { log . warn ( 'members.fetch() pre-collection attempt failed' , String ( e ) ) ; }
144+
145+ backup . data . members = ( guild && guild . members && guild . members . cache ) ? guild . members . cache . map ( m => ( { id : m . id , user : { id : m . user ?. id || null , username : m . user ?. username || null } , nickname : m . nickname || null , roles : m . roles ? ( m . roles . cache ? m . roles . cache . map ( r => r . id ) : ( Array . isArray ( m . roles ) ? m . roles : [ ] ) ) : [ ] } ) ) : [ ] ;
146+ } catch ( err ) { log . warn ( 'Members failed' , { err : String ( err ) } ) ; backup . data . members = { error : String ( err ) } ; }
120147 await markNext ( ) ;
121148
122149 // Step 12: Save JSON and ZIP
0 commit comments