Packages
mob_dev
0.3.37
0.6.23
0.6.22
0.6.21
0.6.20
0.6.19
0.6.18
0.6.17
0.6.16
0.6.15
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.17
0.5.16
0.5.15
0.5.14
0.5.13
0.5.12
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.37
0.3.35
0.3.34
0.3.33
0.3.28
0.3.26
0.3.23
0.3.21
0.3.19
0.3.18
0.3.17
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.18
0.2.17
0.2.15
0.2.14
0.2.13
0.2.12
0.2.11
0.2.10
0.2.9
0.2.8
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.0
Development tooling for the Mob mobile framework
Current section
Files
Jump to
Current section
Files
lib/mob_dev/google_play/play_setup.ex
defmodule MobDev.GooglePlay.PlaySetup do
@moduledoc """
Google Play Developer API operations for granting service account access.
Handles the one automatable step in the Play Console setup: granting
"Release manager" permissions to the service account via the Play
Developer API `accounts.grants` resource.
## What this replaces
The manual steps documented in the publishing guide (Part A and Part B of
section 1.4.4) grant the service account two types of access:
- **API access page** (Part A) — account-level permissions to manage releases
- **Users and permissions** (Part B) — the same grant surfaced via a different
Play Console UI path
Both are handled by a single `accounts.grants.create` API call here.
## Prerequisite that cannot be automated
Before this call will work, you must manually link your Google Cloud project
to Play Console:
Play Console → Setup → API access → Link to a Google Cloud project
This one-time step has no API — it must be done in the browser.
## Finding your developer account ID
The `developer_account_id` is the numeric ID visible in the Play Console URL:
https://play.google.com/console/u/0/developers/**5074092065751960701**/...
It is also printed on the Play Console dashboard.
## Permission note
The Release Manager role grants `CAN_MANAGE_RELEASES` and `CAN_ACCESS_DRAFT_APPS`.
Verify the exact permission enum values against the Play Developer API docs if this
call returns a 400 — Google has not always published these consistently.
"""
alias MobDev.GooglePlay.HTTP
@play "https://androidpublisher.googleapis.com/androidpublisher/v3"
# Permissions that together approximate the "Release Manager" role in Play Console.
# Verify these at: https://developers.google.com/android-publisher/api-ref/rest/v3/accounts.grants
@release_manager_permissions ["CAN_MANAGE_RELEASES", "CAN_ACCESS_DRAFT_APPS"]
@doc """
Grants Release Manager access to a service account on the developer's Play account.
`developer_account_id` — the numeric ID from the Play Console URL (see moduledoc).
`service_account_email` — the service account email (e.g. `play-publisher@project.iam.gserviceaccount.com`).
`package_name` — optional; if provided, grants app-level access only.
Omit (or pass `nil`) for account-level access.
Returns `:ok` or `{:error, reason}`.
"""
@spec grant_release_manager(String.t(), String.t(), String.t(), String.t() | nil) ::
:ok | {:error, String.t()}
def grant_release_manager(
token,
developer_account_id,
service_account_email,
package_name \\ nil
) do
HTTP.ensure_started!()
url = "#{@play}/accounts/#{developer_account_id}/grants"
body = build_grant_request(service_account_email, package_name)
case HTTP.post(url, HTTP.json_headers(token), Jason.encode!(body)) do
{:ok, _} -> :ok
{:error, "HTTP 409: " <> _} -> :ok
{:error, _} = err -> err
end
end
@doc """
Builds the request body for an `accounts.grants.create` API call.
Pure function — useful for testing without making HTTP calls.
When `package_name` is nil, returns an account-level grant (Release Manager
permissions on all apps in the developer account). When `package_name` is
provided, returns an app-level grant for that package only.
"""
@spec build_grant_request(String.t(), String.t() | nil) :: map()
def build_grant_request(service_account_email, nil) do
%{
"grantee" => service_account_email,
"developerAccountPermissions" => @release_manager_permissions
}
end
def build_grant_request(service_account_email, package_name) do
%{
"grantee" => service_account_email,
"packageName" => package_name,
"appLevelPermissions" => @release_manager_permissions
}
end
@doc """
Returns the permission strings used for the Release Manager role.
"""
@spec release_manager_permissions() :: [String.t()]
def release_manager_permissions, do: @release_manager_permissions
end