Как начать работать с AWS SDK для С++ в Yandex Cloud Notification Service
Примечание
Сервис находится на стадии Preview.
Чтобы начать работу с AWS SDK для С++:
- Подготовьте облако к работе.
- Получите статический ключ доступа.
- Настройте AWS SDK.
- Создайте канал уведомлений.
- Получите список каналов.
- Создайте эндпоинт.
- Отправьте уведомление.
Подготовьте облако к работе
Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:
- Перейдите в консоль управления
, затем войдите в Yandex Cloud или зарегистрируйтесь. - На странице Yandex Cloud Billing
убедитесь, что у вас подключен платежный аккаунт, и он находится в статусеACTIVE
илиTRIAL_ACTIVE
. Если платежного аккаунта нет, создайте его и привяжите к нему облако.
Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака
Подробнее об облаках и каталогах.
Получите статический ключ доступа
Для аутентификации в Cloud Notification Service используется статический ключ доступа. Этот ключ выпускается на сервисный аккаунт, и все действия выполняются от имени этого сервисного аккаунта.
Чтобы получить статический ключ доступа:
-
Создайте сервисный аккаунт.
-
Для сервисного аккаунта создайте статический ключ доступа.
Сохраните идентификатор и секретный ключ.
Настройте AWS SDK
Чтобы получить AWS SDK для C++, скомпилируйте и соберите
Ниже приведена инструкция по сборке и установке исходных файлов на Linux и macOS.
Для Windows см. документацию AWS
Пререквизиты и инструкция также описаны в документации AWS
Подготовьте ОС к работе
Для работы с AWS SDK для С++ потребуется:
Для Linux дополнительно установите dev-пакеты для библиотек libcurl
, libopenssl
, libuuid
и zlib
:
sudo apt-get install libcurl4-openssl-dev libssl-dev uuid-dev zlib1g-dev
sudo yum install libcurl-devel openssl-devel libuuid-devel
Установите AWS SDK для С++
-
Создайте директорию для хранения исходных файлов и перейдите в нее:
mkdir -p ~/dev/aws-sdk-cpp cd ~/dev/aws-sdk-cpp
-
Получите исходные файлы:
git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp
-
Создайте директорию для сборки и перейдите в нее:
mkdir ~/aws-sdk-build cd ~/aws-sdk-build
-
Сгенерируйте файлы для сборки:
cmake ~/dev/aws-sdk-cpp/aws-sdk-cpp -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=/usr/local/ -DCMAKE_INSTALL_PREFIX=/usr/local/ -DBUILD_ONLY="sns"
-
Соберите и установите SDK:
make make install
Создайте приложение
-
Создайте проект:
mkdir -p ~/example-app cd ~/example-app
-
Создайте файл cmake
CMakeLists.txt
и добавьте в него следующее содержимое:cmake_minimum_required(VERSION 3.13) # Set the AWS service components used by this project. set(SERVICE_COMPONENTS sns) # Set this project's name. project("example_app") # Set the C++ standard to use to build this target. # At least C++ 11 is required for the AWS SDK for C++. set(CMAKE_CXX_STANDARD 11) # Use the MSVC variable to determine if this is a Windows build. set(WINDOWS_BUILD ${MSVC}) if (WINDOWS_BUILD) # Set the location where CMake can find the installed libraries for the AWS SDK. string(REPLACE ";" "/aws-cpp-sdk-all;" SYSTEM_MODULE_PATH "${CMAKE_SYSTEM_PREFIX_PATH}/aws-cpp-sdk-all") list(APPEND CMAKE_PREFIX_PATH ${SYSTEM_MODULE_PATH}) endif () # Find the AWS SDK for C++ package. find_package(AWSSDK REQUIRED COMPONENTS ${SERVICE_COMPONENTS}) if (WINDOWS_BUILD AND AWSSDK_INSTALL_AS_SHARED_LIBS) # Copy relevant AWS SDK for C++ libraries into the current binary directory for running and debugging. # set(BIN_SUB_DIR "/Debug") # If you are building from the command line you may need to uncomment this # and set the proper subdirectory to the executables' location. AWSSDK_CPY_DYN_LIBS(SERVICE_COMPONENTS "" ${CMAKE_CURRENT_BINARY_DIR}${BIN_SUB_DIR}) endif () add_executable(${PROJECT_NAME} example_app.cpp) target_link_libraries(${PROJECT_NAME} ${AWSSDK_LINK_LIBRARIES})
-
Создайте файл проекта
example_app.cpp
и добавьте в него следующее содержимое:#include <aws/core/Aws.h> #include <aws/core/auth/AWSCredentials.h> #include <aws/sns/SNSClient.h> #include <iostream> int main(int argc, char **argv) { std::string endpoint = "https://notifications.yandexcloud.net/"; std::string accessKeyId = "<идентификатор_статического_ключа>"; std::string secretKey = "<секретный_ключ>"; std::string region = "ru-central1"; Aws::SDKOptions options; Aws::InitAPI(options); // Should only be called once. { Aws::Auth::AWSCredentials credentials(accessKeyId, secretKey); Aws::Client::ClientConfiguration clientConfig; clientConfig.endpointOverride = endpoint; clientConfig.region = region; Aws::SNS::SNSClient snsClient(credentials, clientConfig); } Aws::ShutdownAPI(options); // Should only be called once. return 0; }
Где:
accessKeyId
— идентификатор статического ключа.secretKey
— секретный ключ.
-
Создайте директорию для сборки:
cd ~/example-app mkdir build cd build
-
Сконфигурируйте
cmake
и соберите проект:cmake .. cmake --build .
См. также официальный пример Hello SNS
Создайте канал уведомлений
try {
Aws::SNS::Model::CreatePlatformApplicationRequest request;
request.SetName("<имя_канала>");
request.SetPlatform("<тип_платформы>");
Aws::Map<Aws::String, Aws::String> attributes;
attributes["<тип_аутентификации>"] = "<ключ>";
request.SetAttributes(attributes);
auto outcome = snsClient.CreatePlatformApplication(request);
if (outcome.IsSuccess()) {
std::cout << "Platform application ARN: " << outcome.GetResult().GetPlatformApplicationArn() << std::endl;
} else {
std::cerr << "Error creating platform application: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
Где:
-
SetName
— имя канала уведомлений, задается пользователем. Должно быть уникальным в облаке. Может содержать строчные и заглавные буквы латинского алфавита, цифры, подчеркивания, дефисы и точки. Допустимая длина — от 1 до 256 символов. Рекомендуется для каналов APNs указывать в имени идентификатор приложения (Bundle ID), для FCM и HMS — полное название пакета приложения (Package name). -
SetPlatform
— тип мобильной платформы:APNS
иAPNS_SANDBOX
— Apple Push Notification service (APNs). Для тестирования приложения используйтеAPNS_SANDBOX
.GCM
— Firebase Cloud Messaging (FCM).HMS
— Huawei Mobile Services (HMS).
-
attributes
— параметры аутентификации на мобильной платформе в форматеключ=значение
. Значения зависят от типа платформы:-
APNs:
-
Аутентификация с токеном:
PlatformPrincipal
— путь к файлу с ключом подписи токена, полученный в Apple.PlatformCredential
— идентификатор ключа подписи (Key ID).ApplePlatformTeamID
— идентификатор разработчика (Team ID).ApplePlatformBundleID
— идентификатор приложения (Bundle ID).
-
Аутентификация с сертификатом:
-
PlatformPrincipal
— SSL-сертификат в формате.pem
. -
PlatformCredential
— закрытый ключ сертификата в формате.pem
.Чтобы сохранить сертификат и закрытый ключ в отдельных файлах формата
.pem
, вы можете воспользоваться утилитой openssl в Linux:openssl pkcs12 -in Certificates.p12 -nokeys -nodes -out certificate.pem openssl pkcs12 -in Certificates.p12 -nocerts -nodes -out privatekey.pem
-
Аутентификация с токеном — более современный и безопасный метод.
-
-
FCM:
PlatformCredential
— ключ сервисного аккаунта Google Cloud в формате JSON для аутентификации с помощью HTTP v1 API или API-ключ (server key) для аутентификации с помощью Legacy API.Используйте HTTP v1 API, так как с июля 2024 года FCM legacy API не поддерживается
. -
HMS:
PlatformPrincipal
— идентификатор ключа.PlatformCredential
— API-ключ.
-
В результате вы получите идентификатор (ARN) канала уведомлений.
Получите список каналов уведомлений
Aws::SNS::Model::ListPlatformApplicationsRequest request;
Aws::SNS::Model::ListPlatformApplicationsOutcome outcome = snsClient.ListPlatformApplications(request);
if (outcome.IsSuccess()) {
Aws::Vector<Aws::SNS::Model::PlatformApplication> &applications =
outcome.GetResult().GetPlatformApplications();
std::cout << "You have " << applications.size() << " platform application"
<< (applications.size() == 1 ? "" : "s") << " in your account." << std::endl;
if (!applications.empty()) {
std::cout << "Here are your platform application ARNs:" << std::endl;
for (const Aws::SNS::Model::PlatformApplication &app : applications) {
std::cout << " * " << app.GetPlatformApplicationArn() << std::endl;
}
}
} else {
std::cerr << "Error listing platform applications: " << outcome.GetError().GetMessage() << std::endl;
}
В результате будет выведен список каналов уведомлений, размещенных в том же каталоге, в котором находится сервисный аккаунт.
Создайте эндпоинт
try {
std::string appArn = "<ARN_канала_уведомлений>";
std::string token = "<Push-токен>";
Aws::SNS::Model::CreatePlatformEndpointRequest request;
request.SetPlatformApplicationArn(appArn);
request.SetToken(token);
auto outcome = snsClient.CreatePlatformEndpoint(request);
if (outcome.IsSuccess()) {
std::cout << "Endpoint ARN: " << outcome.GetResult().GetEndpointArn() << std::endl;
} else {
std::cerr << "Error creating platform endpoint: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
Где:
appArn
— идентификатор (ARN) канала уведомлений.token
— уникальный Push-токен приложения на устройстве пользователя.
В результате вы получите идентификатор (ARN) мобильного эндпоинта.
Отправьте уведомление
Явные уведомления (Bright Push)
try {
std::string targetArn = "<ARN_эндпоинта>";
std::string message = R"({
"default": "<текст_уведомления>",
"APNS": "{\"aps\": {\"alert\": \"<текст_уведомления>\"}}"
})";
std::string messageStructure = "json";
Aws::SNS::Model::PublishRequest request;
request.SetTargetArn(targetArn);
request.SetMessage(message);
request.SetMessageStructure(messageStructure);
auto outcome = snsClient.Publish(request);
if (outcome.IsSuccess()) {
std::cout << "Message ID: " << outcome.GetResult().GetMessageId() << std::endl;
} else {
std::cerr << "Error publishing message: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
try {
std::string targetArn = "<ARN_эндпоинта>";
std::string message = R"({
"default": "<текст_уведомления>",
"GCM": "{\"notification\": {\"body\": \"<текст_уведомления>\"}}"
})";
std::string messageStructure = "json";
Aws::SNS::Model::PublishRequest request;
request.SetTargetArn(targetArn);
request.SetMessage(message);
request.SetMessageStructure(messageStructure);
auto outcome = snsClient.Publish(request);
if (outcome.IsSuccess()) {
std::cout << "Message ID: " << outcome.GetResult().GetMessageId() << std::endl;
} else {
std::cerr << "Error publishing message: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
Где:
targetArn
— идентификатор (ARN) мобильного эндпоинта.message
— сообщение.messageStructure
— формат сообщения.
Тихие уведомления (Silent Push)
try {
std::string targetArn = "<ARN_эндпоинта>";
std::string silentMessage = R"({
"default": "<текст_уведомления>",
"APNS": "{\"key\": \"value\"}"
})";
std::string messageStructure = "json";
Aws::SNS::Model::PublishRequest request;
request.SetTargetArn(targetArn);
request.SetMessage(message);
request.SetMessageStructure(messageStructure);
auto outcome = snsClient.Publish(request);
if (outcome.IsSuccess()) {
std::cout << "Message ID: " << outcome.GetResult().GetMessageId() << std::endl;
} else {
std::cerr << "Error publishing message: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
try {
std::string targetArn = "<ARN_эндпоинта>";
std::string message = R"({
"default": "<текст_уведомления>",
"GCM": "{\"data\": {\"key\": \"value\"}}"
})";
std::string messageStructure = "json";
Aws::SNS::Model::PublishRequest request;
request.SetTargetArn(targetArn);
request.SetMessage(message);
request.SetMessageStructure(messageStructure);
auto outcome = snsClient.Publish(request);
if (outcome.IsSuccess()) {
std::cout << "Message ID: " << outcome.GetResult().GetMessageId() << std::endl;
} else {
std::cerr << "Error publishing message: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
Где:
targetArn
— идентификатор (ARN) мобильного эндпоинта.message
— сообщение.messageStructure
— формат сообщения.
SMS-сообщения
try {
std::string phoneNumber = "<номер_телефона>";
std::string message = "<текст_уведомления>";
Aws::SNS::Model::PublishRequest request;
request.SetPhoneNumber(phoneNumber);
request.SetMessage(message);
Aws::Map<Aws::String, Aws::SNS::Model::MessageAttributeValue> messageAttributes;
Aws::SNS::Model::MessageAttributeValue senderIdAttribute;
senderIdAttribute.SetDataType("String");
senderIdAttribute.SetStringValue("<текстовое_имя_отправителя>");
messageAttributes["AWS.SNS.SMS.SenderID"] = senderIdAttribute;
request.SetMessageAttributes(messageAttributes);
auto outcome = snsClient.Publish(request);
if (outcome.IsSuccess()) {
std::cout << "Message ID: " << outcome.GetResult().GetMessageId() << std::endl;
} else {
std::cerr << "Error sending SMS: " << outcome.GetError().GetMessage() << std::endl;
}
} catch (std::exception &ex) {
std::cerr << "Exception occurred: " << ex.what() << std::endl;
}
Где:
phoneNumber
— номер телефона получателя.message
— текст уведомления.senderIdAttribute.SetStringValue
— текстовое имя отправителя.