Current section
Files
Jump to
Current section
Files
lib/explay/request/api.ex
defmodule ExPlay.Request.API do
use ExPlay.Request.Base
@moduledoc """
Google Play API call handler methods
"""
@doc """
Returns all details about a Google Play APK package,
needs an authorized account object
"""
def package_details(account, package) do
ExPlay.Account.verify_authenticated!(account)
details =
get!("details", [{"doc", package}], api_headers(account, :get))
|> ExPlay.Protobuf.decode
|> ExUtils.Map.symbolize_keys
|> handle_response
case details do
{:ok, details} -> {:ok, details.detailsResponse.docV2}
{:error, message} -> {:error, message}
end
end
@doc """
Attempts to retrieve APK download information
"""
def package_download_info(account, {package, version}) do
ExPlay.Account.verify_authenticated!(account)
data =
post!("purchase", download_params(package, version), api_headers(account, :post))
|> ExPlay.Protobuf.decode
|> ExUtils.Map.symbolize_keys
|> handle_response
case data do
{:ok, data} ->
resp = data.buyResponse
cond do
!!resp.purchaseStatusResponse -> {:ok, resp.purchaseStatusResponse.appDeliveryData}
!!resp.checkoutinfo -> {:error, "App not free"}
true -> {:error, "Cannot parse download data"}
end
{:error, message} ->
{:error, message}
end
end
def package_download_info(account, package) when is_binary(package) do
package_download_info(account, {package, nil})
end
@doc "Parses Google API request response to check if it was successful"
def handle_response(response) do
cond do
!!response.payload ->
{:ok, response.payload}
!!response.commands ->
{:error, response.commands.displayErrorMessage}
true ->
{:error, "Unknown Error"}
end
end
@doc "Prepares body for Download information request"
def download_params(package, version_code \\ nil) do
body = [
{ "doc", package },
{ "ot", "1" }
]
case version_code do
nil -> body
_ -> body ++ [{"vc", version_code}]
end
end
@doc "Generates API specific URLs from specified paths"
def process_url(path) do
@url.api <> path
end
@doc "API specific GET requests"
def get!(path, params, headers) do
super(process_url(path), params, headers)
end
@doc "API specific POST requests"
def post!(path, params, headers) do
super(process_url(path), params, headers)
end
@doc "Prepare headers depending on the type of api request"
def api_headers(account, type \\ :get) do
common = [
{ "Authorization", "GoogleLogin auth=#{account.auth_token}" },
{ "X-DFE-Device-Id", account.device_id },
{ "User-Agent", @user_agent.api },
{ "Accept-Language", @defaults.language },
{ "Host", @defaults.host },
{ "X-DFE-Client-Id", @defaults.xdfe.client_id },
{ "X-DFE-SmallestScreenWidthDp", @defaults.xdfe.screen_width },
{ "X-DFE-Filter-Level", @defaults.xdfe.filter_level },
{ "X-DFE-No-Prefetch", @defaults.xdfe.no_prefetch },
{ "X-DFE-Enabled-Experiments", @defaults.xdfe.enabled_experiments },
{ "X-DFE-Unsupported-Experiments", @defaults.xdfe.unsupported_experiments }
]
case type do
:get -> common
:post -> common ++ [{"Content-type", @defaults.content_type}]
_ -> raise "Unknown Request Type"
end
end
end