+async function refreshActorIfNeeded <T extends MActorFull | MActorAccountChannelId> (
+ actorArg: T,
+ fetchedType: ActorFetchByUrlType
+): Promise<{ actor: T | MActorFull, refreshed: boolean }> {
+ if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
+
+ // We need more attributes
+ const actor = fetchedType === 'all'
+ ? actorArg as MActorFull
+ : await ActorModel.loadByUrlAndPopulateAccountAndChannel(actorArg.url)
+
+ try {
+ let actorUrl: string
+ try {
+ actorUrl = await getUrlFromWebfinger(actor.preferredUsername + '@' + actor.getHost())
+ } catch (err) {
+ logger.warn('Cannot get actor URL from webfinger, keeping the old one.', err)
+ actorUrl = actor.url
+ }
+
+ const { result } = await fetchRemoteActor(actorUrl)
+
+ if (result === undefined) {
+ logger.warn('Cannot fetch remote actor in refresh actor.')
+ return { actor, refreshed: false }
+ }
+
+ return sequelizeTypescript.transaction(async t => {
+ updateInstanceWithAnother(actor, result.actor)
+
+ await updateActorImageInstance(actor, ActorImageType.AVATAR, result.avatar, t)
+ await updateActorImageInstance(actor, ActorImageType.BANNER, result.banner, t)
+
+ // Force update
+ actor.setDataValue('updatedAt', new Date())
+ await actor.save({ transaction: t })
+
+ if (actor.Account) {
+ actor.Account.name = result.name
+ actor.Account.description = result.summary
+
+ await actor.Account.save({ transaction: t })
+ } else if (actor.VideoChannel) {
+ actor.VideoChannel.name = result.name
+ actor.VideoChannel.description = result.summary
+ actor.VideoChannel.support = result.support
+
+ await actor.VideoChannel.save({ transaction: t })
+ }
+
+ return { refreshed: true, actor }
+ })
+ } catch (err) {
+ if ((err as PeerTubeRequestError).statusCode === HttpStatusCode.NOT_FOUND_404) {
+ logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
+ actor.Account
+ ? await actor.Account.destroy()
+ : await actor.VideoChannel.destroy()
+
+ return { actor: undefined, refreshed: false }
+ }
+
+ logger.warn('Cannot refresh actor %s.', actor.url, { err })
+ return { actor, refreshed: false }
+ }
+}
+