-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
TRELLO-2203: add social blade client (#1545)
* TRELLO-2203: integrate social blade client
- Loading branch information
1 parent
7b72f9b
commit d6d9642
Showing
11 changed files
with
158 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package config | ||
|
||
case class SocialBladeClientConfiguration( | ||
url: String, | ||
clientId: String, | ||
token: String | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 21 additions & 3 deletions
24
app/orchestrators/socialmedia/InfluencerOrchestrator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,35 @@ | ||
package orchestrators.socialmedia | ||
|
||
import models.report.SocialNetworkSlug | ||
import models.report.socialnetwork.CertifiedInfluencer | ||
import repositories.influencer.InfluencerRepositoryInterface | ||
|
||
import java.util.UUID | ||
import scala.concurrent.ExecutionContext | ||
import scala.concurrent.Future | ||
|
||
class InfluencerOrchestrator( | ||
influencerRepository: InfluencerRepositoryInterface | ||
influencerRepository: InfluencerRepositoryInterface, | ||
socialBladeClient: SocialBladeClient | ||
)(implicit | ||
val executionContext: ExecutionContext | ||
) { | ||
|
||
def get(name: String, socialNetwork: SocialNetworkSlug): Future[Boolean] = | ||
influencerRepository.get(name, socialNetwork).map(_.nonEmpty) | ||
def exist(name: String, socialNetwork: SocialNetworkSlug): Future[Boolean] = { | ||
val curated = name.toLowerCase.replaceAll("\\s", "") | ||
influencerRepository.get(curated, socialNetwork).flatMap { signalConsoCertifiedInfluencers => | ||
if (signalConsoCertifiedInfluencers.nonEmpty) { | ||
Future.successful(true) | ||
} else { | ||
socialBladeClient.checkSocialNetworkUsername(socialNetwork, curated).flatMap { existsOnSocialBlade => | ||
if (existsOnSocialBlade) { | ||
influencerRepository.create(CertifiedInfluencer(UUID.randomUUID(), socialNetwork, curated)).map(_ => true) | ||
} else { | ||
Future.successful(false) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package orchestrators.socialmedia | ||
|
||
import config.SocialBladeClientConfiguration | ||
import models.report.SocialNetworkSlug | ||
import play.api.Logger | ||
import play.api.libs.json.JsError | ||
import play.api.libs.json.JsSuccess | ||
import play.api.libs.json.Json | ||
import sttp.client3.asynchttpclient.future.AsyncHttpClientFutureBackend | ||
import sttp.client3.Identity | ||
import sttp.client3.RequestT | ||
import sttp.client3.Response | ||
import sttp.client3.UriContext | ||
import sttp.client3.asString | ||
import sttp.client3.basicRequest | ||
import utils.Logs.RichLogger | ||
|
||
import scala.concurrent.ExecutionContext | ||
import scala.concurrent.Future | ||
import scala.util.Try | ||
|
||
class SocialBladeClient(config: SocialBladeClientConfiguration)(implicit ec: ExecutionContext) { | ||
|
||
val logger = Logger(this.getClass) | ||
val backend = AsyncHttpClientFutureBackend() | ||
|
||
def checkSocialNetworkUsername( | ||
platform: SocialNetworkSlug, | ||
username: String | ||
): Future[Boolean] = { | ||
|
||
val request: RequestT[Identity, Either[String, String], Any] = basicRequest | ||
.get(uri"${config.url}/b/${platform.entryName.toLowerCase}/statistics?query=${username}") | ||
.header("clientid", config.clientId) | ||
.header("token", config.token) | ||
.header("history", "default") | ||
.response(asString) | ||
|
||
logger.infoWithTitle("socialblade_client", request.toCurl(Set("clientid", "token"))) | ||
|
||
request.send(backend).map { | ||
case Response(Right(body), statusCode, _, _, _, _) if statusCode.isSuccess => | ||
handleSuccessResponse(body, username, platform) | ||
|
||
case Response(Right(body), statusCode, _, _, _, _) => | ||
logger.errorWithTitle( | ||
"socialblade_client_error", | ||
s"Unexpected status code $statusCode calling Social blade : $body" | ||
) | ||
// Act as the username does not exist in social blade | ||
false | ||
|
||
case Response(Left(error), statusCode, _, _, _, _) => | ||
if (statusCode.code == 404) { | ||
logger.infoWithTitle("socialblade_client_notfound", s"${username} not found for ${platform.entryName}") | ||
} else { | ||
logger.errorWithTitle("socialblade_client_error", s"Error $statusCode calling Social blade : $error") | ||
} | ||
// Act as the username does not exist in social blade | ||
false | ||
} | ||
|
||
} | ||
|
||
private def handleSuccessResponse(body: String, username: String, platform: SocialNetworkSlug): Boolean = | ||
Try(Json.parse(body)) | ||
.map { jsonBody => | ||
jsonBody.validate[SocialBladeResponse] match { | ||
case JsSuccess(response, _) => | ||
val found = response.data.id.username.equalsIgnoreCase(username) | ||
if (found) { | ||
logger.infoWithTitle("socialblade_client_found", s"${username} found for ${platform.entryName}") | ||
} else { | ||
logger.infoWithTitle("socialblade_client_notfound", s"${username} not found for ${platform.entryName}") | ||
} | ||
found | ||
case JsError(errors) => | ||
logger.errorWithTitle( | ||
"socialblade_client_error", | ||
s"Cannot parse json to SocialBladeResponse: ${jsonBody.toString}, errors : ${errors}" | ||
) | ||
// Act as the username does not exist in social blade | ||
false | ||
} | ||
} | ||
.recover { case exception: Exception => | ||
logger.errorWithTitle("socialblade_client_error", "Cannot parse SocialBladeResponse to json", exception) | ||
// Act as the username does not exist in social blade | ||
false | ||
} | ||
.getOrElse(false) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package orchestrators.socialmedia | ||
|
||
import play.api.libs.json.Json | ||
import play.api.libs.json.OFormat | ||
|
||
case class SocialBladeStatus(success: Boolean, status: Int) | ||
|
||
case class Id(username: String) | ||
|
||
case class Data(id: Id) | ||
case class SocialBladeResponse(status: SocialBladeStatus, data: Data) | ||
|
||
object SocialBladeResponse { | ||
implicit val SocialBladeStatusFormat: OFormat[SocialBladeStatus] = Json.format[SocialBladeStatus] | ||
implicit val IdFormat: OFormat[Id] = Json.format[Id] | ||
implicit val DataFormat: OFormat[Data] = Json.format[Data] | ||
implicit val SocialBladeResponseFormat: OFormat[SocialBladeResponse] = Json.format[SocialBladeResponse] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
social-blade { | ||
url: "https://matrix.sbapis.com" | ||
url: ${?SOCIALBLADE_URL} | ||
client-id: "" | ||
client-id: ${?SOCIALBLADE_CLIENT_ID} | ||
token: "" | ||
token: ${?SOCIALBLADE_TOKEN} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters