package Ġio . app v ox . google play . review Ċ Ċ import Ġcom . fasterxml . jackson . databind . JsonNode Ċ import Ġcom . fasterxml . jackson . databind . ObjectMapper Ċ import Ġcom . fasterxml . jackson . databind . node . Null Node Ċ import Ġio . app v ox . core . configuration . Request Configuration Ċ import Ġio . app v ox . core . exception . App V ox Error .* Ċ import Ġio . app v ox . core . exception . App V ox Exception Ċ import Ġio . app v ox . google play . review . domain . Google Play Review Request Parameters Ċ import Ġio . app v ox . google play . review . domain . Google Play Review Result Ċ import Ġio . app v ox . core . review . Review Request Ċ import Ġio . app v ox . core . review . Review Result Ċ import Ġio . app v ox . core . util . Http Util Ċ import Ġio . app v ox . core . util . Json Util . get JsonNode ByIndex Ċ import Ġjava . io . IOException Ċ Ċ internal Ġclass ĠGoogle Play Review Repository ( ĊĠĠĠ Ġprivate Ġval Ġconfig : ĠRequest Configuration Ċ ) Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġinternal Ġvar ĠREQUEST _ URL _ DOMAIN Ġ= Ġ" https :// play . google . com " ĊĠĠĠĠĠĠĠ Ġinternal Ġconst Ġval ĠREQUEST _ URL _ PATH Ġ= Ġ"/ _/ Play Store Ui / data / bat che xec ute " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠREQUEST _ URL _ PARAMS Ġ= Ġ"? rpc ids = U sv DT d " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& f . sid =% s " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& bl =% s " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& hl =% s " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& auth user " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& soc - app = 1 2 1 " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& soc - platform = 1 " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& soc - device = 1 " Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ"& _ req id =% s " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠREQUEST _ BODY _ WITH _ PARAMS Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" f . req =[ [[ \" U sv DT d \",\" [ null , null ,[ 2 ,% d ,[ % d , null , null ], null ,[ null , null ,% s ]], [ \\\" % s \\ \", 7 ]] \", null ,\" generic \"] ]] " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠREQUEST _ BODY _ WITH _ PARAMS _ AND _ BODY Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" f . req =[ [[ \" U sv DT d \",\" [ null , null ,[ 2 , null ,[ % d , null , \\\" % s \\\" ], null ,[ null , null ,% s ]], [ \\\" % s \\ \", 7 ]] \", null ,\" generic \"] ]] " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠREQUEST _ BODY _ HISTORY Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ" f . req =[ [[ \" U sv DT d \",\" [ null , null ,[ 4 , null ,[ % d ]], [ \\\" % s \\ \", 7 ], \\\" % s \\ \"] \", null ,\" 1 \"] ]] " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠRE VIEW _ URL Ġ= Ġ" https :// play . google . com / store / apps / details ? id =% s & hl =% s & review Id =% s " ĊĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠROOT _ ARRAY _ INDEX Ġ= Ġint ArrayOf ( 0 , Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠRE VIEW _ ID _ INDEX Ġ= Ġint ArrayOf ( 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠUSER _ NAME _ INDEX Ġ= Ġint ArrayOf ( 1 , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠUSER _ PROFILE _ PIC _ INDEX Ġ= Ġint ArrayOf ( 1 , Ġ 1 , Ġ 3 , Ġ 2 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠR ATING _ INDEX Ġ= Ġint ArrayOf ( 2 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCOMMENT _ INDEX Ġ= Ġint ArrayOf ( 4 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠSUB MIT _ TIME _ INDEX Ġ= Ġint ArrayOf ( 5 , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠLIKE _ COUNT _ INDEX Ġ= Ġint ArrayOf ( 6 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠAPP _ VERSION _ INDEX Ġ= Ġint ArrayOf ( 1 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠRE PLY _ COMMENT _ INDEX Ġ= Ġint ArrayOf ( 7 , Ġ 1 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠRE PLY _ SUBMIT _ TIME _ INDEX Ġ= Ġint ArrayOf ( 7 , Ġ 2 , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCR ITER IA _ INDEX Ġ= Ġint ArrayOf ( 1 2 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCR ITER IA _ CATEGORY _ INDEX Ġ= Ġint ArrayOf ( 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠCR ITER IA _ RAT ING _ INDEX Ġ= Ġint ArrayOf ( 1 , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠHAS _ EDIT _ HISTORY Ġ= Ġint ArrayOf ( 1 4 , Ġ 0 ) ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTOKEN _ INDEX Ġ= Ġint ArrayOf ( 1 , Ġ 1 ) ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠGOOGLE _ PLAY _ SUB _ RESPONSE _ START _ INDEX Ġ= Ġ 4 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMIN _ BATCH _ SIZE Ġ= Ġ 1 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ BATCH _ SIZE Ġ= Ġ 1 5 0 ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMIN _ RANDOM _ REQ ID _ INIT _ NUMBER Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠMAX _ RANDOM _ REQ ID _ INIT _ NUMBER Ġ= Ġ 9 9 9 9 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠREQ ID _ INCREMENT Ġ= Ġ 1 0 0 0 0 0 ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġhttp Utils Ġ= ĠHttp Util ĊĊĠĠĠ Ġprivate Ġvar Ġreq Id Ġ= Ġ( MIN _ RANDOM _ REQ ID _ INIT _ NUMBER .. MAX _ RANDOM _ REQ ID _ INIT _ NUMBER ). random () ĊĊĠĠĠ Ġfun Ġget Reviews By AppId ( ĊĠĠĠĠĠĠĠ Ġrequest : ĠReview Request < Google Play Review Request Parameters > ĊĠĠĠ Ġ): ĠReview Result < Google Play Review Result > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( request . parameters . batch Size Ġ! in ĠMIN _ BATCH _ SIZE .. MAX _ BATCH _ SIZE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApp V ox Exception ( INVALID _ ARGUMENT ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Url Ġ= Ġbuild Request Url ( request ) ĊĠĠĠĠĠĠĠ Ġval Ġrequest Body Ġ= Ġif Ġ( request . nextToken . isNull OrEmpty ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ BODY _ WITH _ PARAMS . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . sort Type . sort Type , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . batch Size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . device Name ?. let Ġ{ Ġ"\\ \" ${ request . parameters . device Name }\\ \"" Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . appId ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ BODY _ WITH _ PARAMS _ AND _ BODY . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . batch Size , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . nextToken , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . device Name ?. let Ġ{ Ġ"\\ \" ${ request . parameters . device Name }\\ \"" Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . appId ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġreviews Ġ= ĠArrayList < Google Play Review Result >() ĊĠĠĠĠĠĠĠ Ġval Ġgoogle Play Response : ĠJsonNode ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Content Ġ= Ġhttp Utils . post Request ( request Url , Ġrequest Body , Ġconfig . proxy ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle Play Response Ġ= Ġparse Reviews From Response ( response Content ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( google Play Response . isNull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApp V ox Exception ( DE SERIAL IZATION ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! google Play Response . isEmpty ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgoogle Play Raw Reviews Ġ= Ġgoogle Play Response . first () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( google Play Raw Review Ġin Ġgoogle Play Raw Reviews ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreview Ġ= Ġparse Review From Response ( request , Ġgoogle Play Raw Review ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreviews . add ( review ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApp V ox Exception ( NETWORK ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġtoken JsonNode Ġ= Ġget JsonNode ByIndex ( google Play Response , ĠTOKEN _ INDEX ) ĊĠĠĠĠĠĠĠ Ġreturn ĠReview Result ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresults Ġ= Ġreviews , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġnext Token Ġ= Ġtoken JsonNode . as Text ( null ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġget Review History ById ( ĊĠĠĠĠĠĠĠ Ġreview Id : ĠString , ĊĠĠĠĠĠĠĠ Ġrequest : ĠReview Request < Google Play Review Request Parameters > ĊĠĠĠ Ġ): ĠList < Google Play Review Result > Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( request . parameters . batch Size Ġ! in ĠMIN _ BATCH _ SIZE .. MAX _ BATCH _ SIZE ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApp V ox Exception ( INVALID _ ARGUMENT ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġrequest Url Ġ= Ġbuild Request Url ( request ) ĊĠĠĠĠĠĠĠ Ġval Ġrequest Body Ġ= ĠREQUEST _ BODY _ HISTORY . format ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . batch Size , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . appId , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreview Id ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġval Ġresponse Content Ġ= Ġhttp Utils . post Request ( request Url , Ġrequest Body , Ġconfig . proxy ) ĊĠĠĠĠĠĠĠ Ġval Ġreviews Ġ= ĠArrayList < Google Play Review Result >() ĊĠĠĠĠĠĠĠ Ġval Ġgoogle Play Response Ġ= Ġparse Reviews From Response ( response Content ) ĊĠĠĠĠĠĠĠ Ġif Ġ( google Play Response . isEmpty ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠApp V ox Exception ( DE SERIAL IZATION ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġgoogle Play Raw Reviews Ġ= Ġgoogle Play Response . first () ĊĠĠĠĠĠĠĠ Ġfor Ġ( google Play Raw Review Ġin Ġgoogle Play Raw Reviews ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreview Ġ= Ġparse Review From Response ( request , Ġgoogle Play Raw Review ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreviews . add ( review ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġreviews ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Review From Response ( ĊĠĠĠĠĠĠĠ Ġrequest : ĠReview Request < Google Play Review Request Parameters >, ĊĠĠĠĠĠĠĠ Ġgoogle Play Raw Review : ĠJsonNode ĊĠĠĠ Ġ): ĠGoogle Play Review Result Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn ĠGoogle Play Review Result ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreview Id Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠRE VIEW _ ID _ INDEX ). as Text (), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠuserName Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠUSER _ NAME _ INDEX ). as Text (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Profile Pic Url Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠUSER _ PROFILE _ PIC _ INDEX ). as Text (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġrating Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠR ATING _ INDEX ). as Int (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Comment Text Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠCOMMENT _ INDEX ). as Text (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġuser Comment Time Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠSUB MIT _ TIME _ INDEX ). as Long (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlike Count Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠLIKE _ COUNT _ INDEX ). as Int (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġapp Version Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠAPP _ VERSION _ INDEX ). when NotNull Ġ{ Ġit . as Text () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġc riter ias Ġ= Ġempty List (), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreview Url Ġ= ĠRE VIEW _ URL . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . appId , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . language . code , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġget JsonNode ByIndex ( google Play Raw Review , ĠRE VIEW _ ID _ INDEX ). as Text () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ), ĊĠĠĠĠĠĠĠĠĠĠĠ Ġhas Edit History Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠHAS _ EDIT _ HISTORY ). when NotNull Ġ{ Ġit . as Boolean () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdeveloper Comment Text Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠRE PLY _ COMMENT _ INDEX ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. when NotNull Ġ{ Ġit . as Text () Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdeveloper Comment Time Ġ= Ġget JsonNode ByIndex ( google Play Raw Review , ĠRE PLY _ SUBMIT _ TIME _ INDEX ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. when NotNull Ġ{ Ġit . as Long () Ġ} ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġbuild Request Url ( ĊĠĠĠĠĠĠĠ Ġrequest : ĠReview Request < Google Play Review Request Parameters > ĊĠĠĠ Ġ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġreq Id Ġ+= ĠREQ ID _ INCREMENT ĊĠĠĠĠĠĠĠ Ġreturn ĠREQUEST _ URL _ DOMAIN Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ URL _ PATH Ġ+ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠREQUEST _ URL _ PARAMS . format ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġrequest . parameters . sid , Ġrequest . parameters . bl , Ġrequest . parameters . language . code , Ġreq Id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġparse Reviews From Response ( g Play Response : ĠString ): ĠJsonNode Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġclean Response Ġ= Ġg Play Response . substring ( GOOGLE _ PLAY _ SUB _ RESPONSE _ START _ INDEX ) ĊĠĠĠĠĠĠĠ Ġval Ġroot Node Ġ= ĠObjectMapper (). read Tree ( clean Response ) ĊĠĠĠĠĠĠĠ Ġval Ġsub Node Ġ= Ġget JsonNode ByIndex ( root Node , ĠROOT _ ARRAY _ INDEX ) ĊĠĠĠĠĠĠĠ Ġval Ġsub Node AsString Ġ= Ġsub Node . text Value () ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( sub Node AsString Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠObjectMapper (). read Tree ( sub Node AsString ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠNull Node . getInstance () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinline Ġfun Ġ< R > ĠJsonNode . when NotNull ( block : Ġ( JsonNode ) Ġ-> ĠR ): ĠR ? Ġ{ ĊĠĠĠĠĠĠĠ Ġreturn Ġif Ġ(! this . isNull ) Ġblock ( this ) Ġelse Ġnull ĊĠĠĠ Ġ} Ċ } Ċ