mirror of
https://github.com/twitter/the-algorithm.git
synced 2024-06-27 13:36:03 +02:00
ef4c5eb65e
Please note we have force-pushed a new initial commit in order to remove some publicly-available Twitter user information. Note that this process may be required in the future.
68 lines
2.8 KiB
Scala
68 lines
2.8 KiB
Scala
package com.twitter.home_mixer.functional_component.feature_hydrator
|
|
|
|
import com.twitter.home_mixer.model.HomeFeatures.AuthorIdFeature
|
|
import com.twitter.home_mixer.model.HomeFeatures.InNetworkFeature
|
|
import com.twitter.product_mixer.component_library.model.candidate.TweetCandidate
|
|
import com.twitter.product_mixer.core.feature.Feature
|
|
import com.twitter.product_mixer.core.feature.featuremap.FeatureMap
|
|
import com.twitter.product_mixer.core.feature.featuremap.FeatureMapBuilder
|
|
import com.twitter.product_mixer.core.functional_component.feature_hydrator.BulkCandidateFeatureHydrator
|
|
import com.twitter.product_mixer.core.model.common.CandidateWithFeatures
|
|
import com.twitter.product_mixer.core.model.common.identifier.FeatureHydratorIdentifier
|
|
import com.twitter.product_mixer.core.pipeline.PipelineQuery
|
|
import com.twitter.socialgraph.{thriftscala => sg}
|
|
import com.twitter.stitch.Stitch
|
|
import com.twitter.stitch.socialgraph.{SocialGraph => SocialGraphStitchClient}
|
|
import javax.inject.Inject
|
|
import javax.inject.Singleton
|
|
|
|
@Singleton
|
|
class SocialGraphServiceFeatureHydrator @Inject() (socialGraphStitchClient: SocialGraphStitchClient)
|
|
extends BulkCandidateFeatureHydrator[PipelineQuery, TweetCandidate] {
|
|
|
|
override val identifier: FeatureHydratorIdentifier =
|
|
FeatureHydratorIdentifier("SocialGraphService")
|
|
|
|
override val features: Set[Feature[_, _]] = Set(InNetworkFeature)
|
|
|
|
override def apply(
|
|
query: PipelineQuery,
|
|
candidates: Seq[CandidateWithFeatures[TweetCandidate]]
|
|
): Stitch[Seq[FeatureMap]] = {
|
|
val viewerId = query.getRequiredUserId
|
|
|
|
// We use authorId and not sourceAuthorId here so that retweets are defined as in network
|
|
val authorIds = candidates.map(_.features.getOrElse(AuthorIdFeature, None).getOrElse(0L))
|
|
val distinctNonSelfAuthorIds = authorIds.filter(_ != viewerId).distinct
|
|
|
|
val idsRequest = createIdsRequest(
|
|
userId = viewerId,
|
|
relationshipTypes = Set(sg.RelationshipType.Following),
|
|
targetIds = Some(distinctNonSelfAuthorIds)
|
|
)
|
|
|
|
socialGraphStitchClient
|
|
.ids(request = idsRequest, requestContext = None)
|
|
.map { idResult =>
|
|
authorIds.map { authorId =>
|
|
// Users cannot follow themselves but this is in network by definition
|
|
val isSelfTweet = authorId == viewerId
|
|
val inNetworkAuthorIds = idResult.ids.toSet
|
|
val isInNetwork = isSelfTweet || inNetworkAuthorIds.contains(authorId) || authorId == 0L
|
|
FeatureMapBuilder().add(InNetworkFeature, isInNetwork).build()
|
|
}
|
|
}
|
|
}
|
|
|
|
private def createIdsRequest(
|
|
userId: Long,
|
|
relationshipTypes: Set[sg.RelationshipType],
|
|
targetIds: Option[Seq[Long]] = None
|
|
): sg.IdsRequest = sg.IdsRequest(
|
|
relationshipTypes.map { relationshipType =>
|
|
sg.SrcRelationship(userId, relationshipType, targets = targetIds)
|
|
}.toSeq,
|
|
Some(sg.PageRequest(selectAll = Some(true)))
|
|
)
|
|
}
|