Привет, Хабр!
Меня зовут Энрике, и я работаю Go-разработчиком в RuStore. Сегодня хочу рассказать про библиотеку на Go для комфортной работы с API магазина приложений RuStore.
Иногда авторизация через API и получение JWE-токена занимают больше времени, чем хотелось бы. С нашей новой библиотекой процесс становится намного проще — интегрируйте её в свой проект и используйте любые методы RuStore API.
В этой статье мы опишем небольшой пример использования методов из нашей библиотеки: как получить данные по платежу, загрузить APK/AAB-файл и оставить ответ на отзыв пользователя. Все доступные методы можно посмотреть в документации.
Как устроена библиотека
Библиотеку было решено писать на Go, так как этот язык достаточно прост в использовании и удобен для написания HTTP-запросов.
Библиотека RuStore API состоит из следующих директорий:
client
: определяет структуру Client, в которой содержатся все необходимые поля для работы. У Client есть метод Auth(), с помощью которого и происходит авторизация.cmd/examples
: здесь расположены примеры работы с библиотекой.
comments
— работа с отзывами;publishing
— загрузка и публикация приложений;payments
— получение данных платежа и подписки.
Расположенные в корне проекта comments
, payments
, publishing
— пакеты, в которых содержится логика формирования запросов и структура ответов для каждого из разделов RuStore API.
Начало работы
Представим себе, что вы Android-разработчик и планируете опубликовать ваше первое приложение в RuStore. В первую очередь вам нужно зарегистрироваться в RuStore Консоли.
Для использования библиотеки получите всего три параметра из Консоли:
Ваш приватный ключ с разрешениями на работу с нужными разделами;
ID вашего приватного ключа. Его вы получаете при генерации приватного ключа.
Сохраните эти параметры в файле формата JSON (например, options.json) в следующем виде:
{
"companyID":"ID вашей компании",
"privateKeyID":"ID вашего приватного ключа",
"privateKey":"Ваш приватный ключ"
}
Готово! Вы установили параметры, которые будут использоваться при выполнении всех запросов к API.
Авторизация
Авторизуйтесь и передайте параметры из options.json клиенту из пакета client:
package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"log"
"net/url"
"os"
"time"
"gitflic.ru/project/rustore/rustoreapi/client"
"gitflic.ru/project/rustore/rustoreapi/publishing"
"gitflic.ru/project/rustore/rustoreapi/comments"
"gitflic.ru/project/rustore/rustoreapi/payments"
)
var (
// так мы парсим все параметры из файла options.json
file = flag.String(
"file",
"",
"file with options: privateKey, privateKeyID, companyID",
)
options Options
)
// структура для того, чтобы сохранить параметры из options.json
type Options struct {
PrivateKey string `json:"privateKey"`
PrivateKeyID string `json:"privateKeyID"`
CompanyID string `json:"companyID"`
}
func main() {
// парсим всё из options.json
flag.Parse()
data, err := os.ReadFile(*file)
if err != nil {
panic(err)
}
if err = json.Unmarshal(data, &options); err != nil {
panic(err)
}
// создаём клиента с переданными из options.json параметрами
cl := client.New(
options.PrivateKeyID,
options.PrivateKey,
options.CompanyID,
)
err = cl.Auth()
if err != nil {
log.Fatal(err)
}
Схематично процесс авторизации выглядит следующим образом:
После авторизации наш JWE-токен будет передаваться в заголовке при каждом вызове метода RuStore API.
Итак, всё самое сложное позади: вы зарегистрировались в Консоли и авторизовались с полученными параметрами.
Загрузка APK-файла
Первое, что нужно сделать, чтобы познакомить пользователей с вашим приложением — загрузить APK-файл.
Чтобы начать работать с методами загрузки и публикации приложений, нужно создать новую сущность (pub в примере), которой вы передадите созданного клиента и packageName вашего приложения.
pub := publishing.New(
cl,
packageName,
)
Таким образом, вы сможете использовать любые методы для загрузки и публикации приложений.
Теперь вам нужно вызвать метод загрузки APK и передать ему необходимые параметры:
var (
//id версии вашего приложения
versionID = 123
// packageName вашего приложения
packageName = "app.example"
// параметры в URL. По умолчанию пустые
urlValues = url.Values{}
// путь к APK, который вы загружаете
fileNameAPK = "Desktop/app-release.apk"
// isMainAPK - признак, который присваивается основному APK-файлу
isMainAPK = true
)
// контекст, который передаётся во все методы
ctx, cancel := context.WithTimeout(
context.Background(),
client.TimeOutSeconds*10*time.Second,
)
defer cancel()
// загружаем APK-файл:
uploadAPK, err := pub.UploadAPKFile(
ctx,
versionID,
fileNameAPK,
isMainAPK,
urlValues,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nзагрузили APK файл: %+v\n", uploadAPK)
if uploadAPK.Message != nil {
fmt.Println(*uploadAPK.Message)
}
Вывод:
загрузили APK файл: {Code:OK Message:<nil> Timestamp:2024-03-20 15:31:57.586533733 +0300 MSK}
Вот и всё! Доступ к любому полю ответа вы можете получить с помощью uploadAPK, например:
fmt.Println("Получить код ответа:", uploadAPK.Code)
Вывод:
OK
Вывод, в случае, если есть ошибка (uploadAPK.Message != nil
):
File was not uploaded successfully: The Version Code of the downloaded file must be greater than the previous version
Для запуска программы вы можете воспользоваться командой go run и указать там файл, из которого считываются данные с помощью -file “Имя файла”, например, так:
go run main.go -file options.json
Загрузка AAB файла
В RuStore можно загружать файлы формата не только APK, но и AAB. Порядок действий идентичен загрузке файла APK, за исключением названия метода.
Важно: перед загрузкой AAB файла убедитесь, что у вас загружена подпись для публикации Android App Bundle (AAB) через RuStore Консоль.
uploadAAB, err := pub.UploadAABFile(
ctx,
versionID,
// путь к AAB, который вы загружаете
fileNameAAB,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nзагрузили AAB файл: %+v\n", uploadAAB)
if uploadAAB.Message != nil {
fmt.Println(*uploadAAB.Message)
}
Вывод:
загрузили AAB файл: {Code:OK Message:<nil> Timestamp:2024-03-20 15:35:31.486143514 +0300 MSK}
Ответ на отзыв
Итак, файл самого приложения загружен, ваши пользователи начинают реагировать на продукт, и теперь вы хотите отвечать на их отзывы.
Теперь создайте сущность coms, передав в неё клиента и packageName:
coms := comments.New(cl, packageName)
Далее нужно вызвать метод AnswerComment
, передав ID комментария, на который вы хотите ответить, и текст ответа:
var (
// текст, которым вы хотите ответить на отзыв
feedbackText= "Спасибо вам большое!"
// id отзыва, на который вы хотите ответить
commentID = "321"
)
answerComment, err := coms.AnswerComment(
ctx,
commentID,
feedbackText,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nответили на отзыв: %+v\n", answerComment)
Вывод:
ответили на отзыв: {Code:OK Message:<nil> Body:{ID:1233211} Timestamp:2024-03-20 16:14:00.06460532 +0300 MSK}
Получение информации о платеже
Вы загрузили приложение, ответили на отзывы, самое время посмотреть информацию по платежам ваших пользователей.
Как и в предыдущих примерах, создайте сущность для работы с платежами:
pay := payments.New(cl, packageName)
Получить информацию о платеже можно с помощью метода GetPaymentInfo
:
Здесь вам понадобится purchaseToken
— связка из userID
и invoiceID
в формате “userID.invoiceID”
.
var purchaseToken = "12345"
paymentInfo, err := pay.GetPaymentInfo(
ctx,
purchaseToken,
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("\nИнформация по платежу:%+v\n", paymentInfo)
Вывод:
Информация по платежу:
{Code:OK
Message:<nil>
Body:
{InvoiceID:12345
InvoiceDate:2024-03-04T17:06:40+03
InvoiceStatus:confirmed
ApplicationCode:2414512
ApplicationName:MyApp
OwnerCode:3123124
OwnerName:Иванов Иван Иванович
PaymentInfo:{PaymentDate:2024-03-04T17:07:21+03
PaymentID:123456
PaymentParams:<nil>
LoyaltyInfo:<nil>
CardID: <nil>
PaysysCode:RBS-shortname
MaskedPan:XX1234
ExpiryDate:102313
...
Заключение
Эти и многие другие методы для работы с RuStore API вы можете найти на странице проекта.
Если у вас есть вопросы и предложения по развитию библиотеки, обязательно делитесь ими в комментариях!