+async function refreshActorIfNeeded (
+ actorArg: ActorModel,
+ fetchedType: ActorFetchByUrlType
+): Promise<{ actor: ActorModel, refreshed: boolean }> {
+ if (!actorArg.isOutdated()) return { actor: actorArg, refreshed: false }
+
+ // We need more attributes
+ const actor = fetchedType === 'all' ? actorArg : 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, statusCode } = await fetchRemoteActor(actorUrl)
+
+ if (statusCode === 404) {
+ logger.info('Deleting actor %s because there is a 404 in refresh actor.', actor.url)
+ actor.Account ? actor.Account.destroy() : actor.VideoChannel.destroy()
+ return { actor: undefined, refreshed: false }
+ }
+
+ 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)
+
+ if (result.avatarName !== undefined) {
+ await updateActorAvatarInstance(actor, result.avatarName, t)
+ }
+
+ // Force update
+ actor.setDataValue('updatedAt', new Date())
+ await actor.save({ transaction: t })
+
+ if (actor.Account) {
+ actor.Account.set('name', result.name)
+ actor.Account.set('description', result.summary)
+
+ await actor.Account.save({ transaction: t })
+ } else if (actor.VideoChannel) {
+ actor.VideoChannel.set('name', result.name)
+ actor.VideoChannel.set('description', result.summary)
+ actor.VideoChannel.set('support', result.support)
+
+ await actor.VideoChannel.save({ transaction: t })
+ }
+
+ return { refreshed: true, actor }
+ })
+ } catch (err) {
+ logger.warn('Cannot refresh actor.', { err })
+ return { actor, refreshed: false }
+ }
+}
+