How to get started with the AWS SDK for C++ in Yandex Cloud Notification Service
Note
The service is at the preview stage.
To get started with the AWS SDK for C++:
- Get your cloud ready.
- Get a static access key.
- Configure the AWS SDK.
- Create a notification channel.
- Get a list of channels.
- Create an endpoint.
- Send a notification.
Get your cloud ready
Sign up for Yandex Cloud and create a billing account:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Get a static access key
For authentication in Cloud Notification Service, use a static access key. The key is issued for the service account, and all actions are performed on behalf of that service account.
To get a static access key:
-
Create a service account.
-
Assign the
editor
role for the folder to the service account. -
Create a static access key for the service account.
Save the ID and secret key.
Configure the AWS SDK
To get the AWS SDK for C++, compile and build
Below is a guide on how to build and install the source files on Linux and macOS.
For Windows, see the relevant AWS documentation
You can also find the prerequisites and a guide in the AWS documentation
Get your OS ready
To use the AWS SDK for C++ you will need:
For Linux, additionally install dev packages for the libcurl
, libopenssl
, libuuid
, and zlib
libraries:
sudo apt-get install libcurl4-openssl-dev libssl-dev uuid-dev zlib1g-dev
sudo yum install libcurl-devel openssl-devel libuuid-devel
Install AWS SDK for C++
-
Create a directory to store the source files in and navigate to it:
mkdir -p ~/dev/aws-sdk-cpp cd ~/dev/aws-sdk-cpp
-
Get the source files:
git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp
-
Create a directory for your build and navigate to it:
mkdir ~/aws-sdk-build cd ~/aws-sdk-build
-
Generate files for the 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"
-
Build and install the SDK:
make make install
Create an app
-
Create a project:
mkdir -p ~/example-app cd ~/example-app
-
Create a file named
CMakeLists.txt
and add the following contents to it: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})
-
Create a project file named
example_app.cpp
and add the following contents to it:#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 = "<static_key_ID>"; std::string secretKey = "<secret_key>"; 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; }
Where:
accessKeyId
: Static key IDsecretKey
: Secret key
-
Create a directory for the build:
cd ~/example-app mkdir build cd build
-
Configure
cmake
and build the project:cmake .. cmake --build .
See also the official Hello SNS example
Create a notification channel
try {
Aws::SNS::Model::CreatePlatformApplicationRequest request;
request.SetName("<channel_name>");
request.SetPlatform("<platform_type>");
Aws::Map<Aws::String, Aws::String> attributes;
attributes["<authentication_type>"] = "<key>";
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;
}
Where:
-
SetName
: Notification channel name, user-defined. The name must be unique within the cloud. It may contain lowercase and uppercase Latin letters, numbers, underscores, hyphens, and periods. It may be from 1 to 256 characters long. For APNs channels, we recommend specifying the bundle ID in the name, and for FCM and HMS, the full package name. -
SetPlatform
: Mobile platform type:APNS
andAPNS_SANDBOX
: Apple Push Notification service (APNs). UseAPNS_SANDBOX
to test the application.GCM
: Firebase Cloud Messaging (FCM).HMS
: Huawei Mobile Services (HMS).
-
attributes
: Mobile platform authentication parameters inkey=value
format. The values depend on platform:-
APNs:
-
Token-based authentication:
PlatformPrincipal
: Path to the token signature key file from ApplePlatformCredential
: Key IDApplePlatformTeamID
: Team IDApplePlatformBundleID
: Bundle ID
-
Certificate-based authentication:
-
PlatformPrincipal
: SSL certificate in.pem
format -
PlatformCredential
: Certificate private key in.pem
formatTo save the certificate and the private key in individual
.pem
files, use the openssl Linux utility:openssl pkcs12 -in Certificates.p12 -nokeys -nodes -out certificate.pem openssl pkcs12 -in Certificates.p12 -nocerts -nodes -out privatekey.pem
-
Token-based authentication: The more modern and secure method.
-
-
FCM:
PlatformCredential
is the Google Cloud service account key in JSON format for authentication with the HTTP v1 API or API key (server key) for authentication with the legacy API.Use the HTTP v1 API because the FCM legacy API is no longer supported
starting July 2024. -
HMS:
PlatformPrincipal
: Key IDPlatformCredential
: API key
-
As a result, you will get a notification channel ID (ARN).
Get a list of notification channels
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;
}
You will get the list of notification channels located in the same folder as the service account.
Create an endpoint
try {
std::string appArn = "<notification_channel_ARN>";
std::string token = "<push_token>";
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;
}
Where:
appArn
: Notification channel ID (ARN).token
: Unique push token for the application on the user’s device.
As a result, you will get a mobile endpoint ID (ARN).
Send a notification
Explicit notifications (Bright Push)
try {
std::string targetArn = "<endpoint_ARN>";
std::string message = R"({
"default": "<notification_text>",
"APNS": "{\"aps\": {\"alert\": \"<notification_text>\"}}"
})";
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 = "<endpoint_ARN>";
std::string message = R"({
"default": "<notification_text>",
"GCM": "{\"notification\": {\"body\": \"<notification_text>\"}}"
})";
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;
}
Where:
targetArn
: Mobile endpoint ID (ARN)message
: MessagemessageStructure
: Message format
Silent notifications (Silent Push)
try {
std::string targetArn = "<endpoint_ARN>";
std::string silentMessage = R"({
"default": "<notification_text>",
"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 = "<endpoint_ARN>";
std::string message = R"({
"default": "<notification_text>",
"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;
}
Where:
targetArn
: Mobile endpoint ID (ARN)message
: MessagemessageStructure
: Message format
Text message
try {
std::string phoneNumber = "<phone_number>";
std::string message = "<notification_text>";
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("<sender's_text_name>");
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;
}
Where:
phoneNumber
: Recipient's phone numbermessage
: Notification textsenderIdAttribute.SetStringValue
: Sender's text name