Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b9c9fc9
Update README.md (#130)
turtledreams Oct 30, 2023
6537dad
Release notice (#131)
turtledreams Jan 2, 2024
74ae31c
[CPP] Add warnings to all SDK example apps that would check if proppe…
arifBurakDemiray Jan 29, 2024
ac5f2c7
Http client example
turtledreams Nov 14, 2024
ccc97db
feat: add changelog
arifBurakDemiray Sep 30, 2025
b2fcfe9
feat: function to header files
arifBurakDemiray Sep 30, 2025
9326a3b
feat: function impl
arifBurakDemiray Sep 30, 2025
4d4ff54
feat: add manual session control
arifBurakDemiray Sep 30, 2025
1a21220
feat: add manual session control impl
arifBurakDemiray Sep 30, 2025
82f10eb
feat: introduce pack events
arifBurakDemiray Sep 30, 2025
afdcd28
feat: manual sessions impl
arifBurakDemiray Sep 30, 2025
417944d
feat: update runners
arifBurakDemiray Sep 30, 2025
53c1685
feat: update runner scripts
arifBurakDemiray Sep 30, 2025
c8897f1
feat: update runner scripts for windws
arifBurakDemiray Sep 30, 2025
f1d4ea4
feat: update runner scripts
arifBurakDemiray Sep 30, 2025
4a7f5c8
feat: update runner scripts
arifBurakDemiray Sep 30, 2025
7c68875
feat: update runner scripts
arifBurakDemiray Sep 30, 2025
2a0ad42
fix: a 86 interrupt instruction forapple in doctest
arifBurakDemiray Sep 30, 2025
0e93449
fix: a 86 interrupt instruction forapple in doctest
arifBurakDemiray Sep 30, 2025
8c05027
fix: a 86 interrupt instruction forapple in doctest
arifBurakDemiray Sep 30, 2025
e74b615
fix: a 86 interrupt instruction forapple in doctest
arifBurakDemiray Sep 30, 2025
b8b050d
feat: update doctest v
arifBurakDemiray Sep 30, 2025
816a5d0
feat: update windows runner
arifBurakDemiray Sep 30, 2025
007bd15
fix: reduce ubuntu v because latest break
arifBurakDemiray Sep 30, 2025
3a5e7f1
refactor: remove unnecessary downlaods
arifBurakDemiray Sep 30, 2025
8dcf335
refactor: remove unnecessary downlaods
arifBurakDemiray Sep 30, 2025
4165868
Merge pull request #137 from Countly/update_runners
turtledreams Sep 30, 2025
75f8d74
Merge pull request #135 from Countly/rq_size
turtledreams Sep 30, 2025
c5ebc79
Merge branch 'staging' into manual_sessions
turtledreams Sep 30, 2025
b6aa925
Merge pull request #136 from Countly/manual_sessions
turtledreams Sep 30, 2025
e9465ef
Update example_integration.cpp
turtledreams Sep 30, 2025
7a3ee0e
Merge pull request #134 from Countly/http-client-example
turtledreams Sep 30, 2025
4434b54
feat: 23.2.1
arifBurakDemiray Sep 30, 2025
92f795e
revert: some changes
arifBurakDemiray Oct 1, 2025
7add130
fix: behavior changes
arifBurakDemiray Oct 1, 2025
ff37b49
Merge pull request #138 from Countly/2321
turtledreams Oct 2, 2025
9e3d426
Correct header formatting for version 23.2.1
arifBurakDemiray Oct 2, 2025
29eea4f
Merge pull request #139 from Countly/arifBurakDemiray-patch-1
turtledreams Oct 2, 2025
0354e63
mutex fix
turtledreams Oct 7, 2025
797cfe0
version
turtledreams Oct 8, 2025
f725c1a
Merge pull request #140 from Countly/cpp-mutex-fix
turtledreams Oct 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/release_notice.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Release Notice
on:
release:
types: [published]
workflow_dispatch:
jobs:
build:
runs-on: ubuntu-latest
steps:
# To check the github context
- name: Dump Github context
env:
GITHUB_CONTEXT: ${{ toJSON(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Send custom JSON data to Slack workflow
id: slack
uses: slackapi/[email protected]
with:
# This data can be any valid JSON from a previous step in the GitHub Action
payload: |
{
"repository": "${{ github.repository }}",
"tag_name": "${{ github.event.release.tag_name }}",
"actor": "${{ github.actor }}",
"body": ${{ toJSON(github.event.release.body) }},
"html_url": "${{ github.event.release.html_url }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_RELEASE }}
- name: Send custom JSON data to Discord
uses: sarisia/[email protected]
with:
webhook: ${{ secrets.DISCORD_WEBHOOK_URL }}
nodetail: true
title: New ${{ github.repository }} version ${{ github.event.release.tag_name }} published by ${{ github.actor }}
description: |
Release URL: ${{ github.event.release.html_url }}
Click [here](https://github.com/Countly/countly-server/blob/master/CHANGELOG.md) to view the change log.
`${{ github.event.release.body }}`
38 changes: 20 additions & 18 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,26 @@ jobs:
fail-fast: false
matrix:
os:
- ubuntu-20.04
- macos-11.0
- windows-2019
- ubuntu-22.04
- macos-15
- windows-2022

include:
- os: windows-2019
cmake-generator: -G "Visual Studio 16 2019" -A x64
cmake-install: "choco install -y cmake"
dependencies: |
choco install -y openssl
choco install -y visualstudio2017-workload-vctools
choco upgrade -y visualstudio2017-workload-vctools
make: msbuild countly-tests.vcxproj -t:rebuild -verbosity:diag -property:Configuration=Release && .\Release\countly-tests.exe
- os: macos-11.0
cmake-install: "brew install cmake"
dependencies: "brew install openssl"
- os: windows-2022
cmake-generator: -G "Visual Studio 17 2022" -A x64
cmake-install: "" #Already installed on hosted runner
dependencies: "" #Already installed on hosted runner
make: msbuild countly-tests.vcxproj -t:rebuild -verbosity:diag -property:Configuration=Release && .\Release\countly-tests.exe
- os: macos-15
cmake-install: "" #Already installed on hosted runner
dependencies: "" #Already installed on hosted runner
make: make ./countly-tests && ./countly-tests
- os: ubuntu-20.04
cmake-install: "sudo apt-get update && sudo apt-get install -y cmake"
dependencies: "sudo apt-get update && sudo apt-get install -y libcurl4-openssl-dev"
- os: ubuntu-22.04
cmake-install: "" #Already installed on hosted runner
dependencies: |
sudo apt-get update && sudo apt-get install -y \
libcurl4-openssl-dev \
libssl-dev
make: make ./countly-tests && ./countly-tests

steps:
Expand All @@ -52,11 +52,13 @@ jobs:
run: ${{ matrix.dependencies }}

- name: Set up MSVC
if: matrix.os == 'windows-2019'
if: matrix.os == 'windows-2022'
uses: microsoft/setup-msbuild@v1

- name: Build and run tests
run: |
cmake -DCOUNTLY_BUILD_TESTS=1 -B build . ${{ matrix.cmake-generator }}
cd build
${{ matrix.make }}
env:
CMAKE_POLICY_VERSION_MINIMUM: 3.31
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 23.2.2
- Mitigated a mutex issue that can happen during update loop.

## 23.2.1
- Added manual session control via "Countly::enableManualSessionControl". When enabled, automatic session calls are ignored, while manual calls remain usable for finer control.
- Added "checkRQSize" function to return the current number of requests in the queue.

## 23.2.0
- Request queue processing now is limited to 100 requests at a time
- Added 'setEventsToRQThreshold' method that sets the number of events after which all events will be sent to the RQ. Default value is set to 100.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/f3268a85b0034b68aa4fc47c9dce596c)](https://www.codacy.com/gh/Countly/countly-sdk-cpp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Countly/countly-sdk-cpp&utm_campaign=Badge_Grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/f3268a85b0034b68aa4fc47c9dce596c)](https://app.codacy.com/gh/Countly/countly-sdk-cpp/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)

# Countly C++ SDK

Expand Down
123 changes: 121 additions & 2 deletions examples/example_integration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,115 @@ void printLog(LogLevel level, const string &msg) {
cout << lvl << msg << endl;
}

// // Callback function to write response data
// static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
// ((std::string*)userp)->append((char*)contents, size * nmemb);
// return size * nmemb;
// }

// // Custom HTTP client for macOS
// HTTPResponse customClient(bool use_post, const std::string &path, const std::string &data) {
// HTTPResponse response;
// response.success = false;
// cout << "Making real HTTP request to: " << path << endl;

// CURL *curl;
// CURLcode res;
// std::string readBuffer;

// curl = curl_easy_init();
// if(curl) {
// // Set URL
// curl_easy_setopt(curl, CURLOPT_URL, path.c_str());

// // Set callback function to write data
// curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
// curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

// // Set timeout
// curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);

// // Follow redirects
// curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);

// // SSL verification (set to 0 for testing, 1 for production)
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
// curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

// // Set User-Agent
// curl_easy_setopt(curl, CURLOPT_USERAGENT, "Countly-SDK-CPP/1.0");

// if (use_post) {
// // Set POST method
// curl_easy_setopt(curl, CURLOPT_POST, 1L);

// if (!data.empty()) {
// // Set POST data
// curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
// curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, data.length());
// }

// // Set content type for POST
// struct curl_slist *headers = NULL;
// headers = curl_slist_append(headers, "Content-Type: application/x-www-form-urlencoded");
// curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// } else {
// // For GET requests, append data as query parameters
// if (!data.empty()) {
// std::string fullUrl = path;
// fullUrl += (path.find('?') != std::string::npos) ? "&" : "?";
// fullUrl += data;
// curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
// }
// }

// // Perform the request
// res = curl_easy_perform(curl);

// if(res != CURLE_OK) {
// cout << "curl_easy_perform() failed: " << curl_easy_strerror(res) << endl;
// } else {
// // Get response code
// long response_code;
// curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);

// cout << "HTTP Response Code: " << response_code << endl;
// cout << "Raw response: " << readBuffer << endl;

// // Check if HTTP request was successful (2xx status codes)
// if (response_code >= 200 && response_code < 300) {
// // Check if response contains { result: 'Success' } or {"result":"Success"}
// if (readBuffer.find("\"result\"") != std::string::npos &&
// (readBuffer.find("\"Success\"") != std::string::npos ||
// readBuffer.find("'Success'") != std::string::npos)) {
// response.success = true;
// cout << "Success response detected!" << endl;
// } else {
// cout << "Response does not indicate success" << endl;
// }

// // Parse as JSON
// try {
// response.data = nlohmann::json::parse(readBuffer);
// } catch (const std::exception& e) {
// cout << "Failed to parse JSON response: " << e.what() << endl;
// response.data = nlohmann::json::object();
// }
// } else {
// cout << "HTTP request failed with code: " << response_code << endl;
// }
// }

// // Cleanup
// curl_easy_cleanup(curl);
// } else {
// cout << "Failed to initialize curl" << endl;
// }

// cout << "Request completed. Success: " << (response.success ? "true" : "false") << endl;
// return response;
// }

int main() {
cout << "Sample App" << endl;
Countly &ct = Countly::getInstance();
Expand All @@ -38,7 +147,10 @@ int main() {
// Please refer to the documentation for more information:
// https://support.count.ly/hc/en-us/articles/4416163384857-C-

ct.alwaysUsePost(true);
// Custom HTTP client
// HTTPClientFunction clientPtr = customClient;
// ct.setHTTPClient(clientPtr);
// ct.alwaysUsePost(true);
ct.setLogger(printLog);
ct.SetPath("databaseFileName.db"); // this will be only built into account if the correct configurations are set
ct.setDeviceID("test-device-id");
Expand All @@ -47,7 +159,14 @@ int main() {
ct.SetMetrics("Windows 10", "10.22", "Mac", "800x600", "Carrier", "1.0");

// start the SDK (initialize the SDK)
ct.start("YOUR_APP_KEY", "https://try.count.ly", 443, true);
string _appKey = "YOUR_APP_KEY";
string _serverUrl = "https://your.server.ly";

if(_appKey.compare("YOUR_APP_KEY") == 0 || _serverUrl.compare("https://your.server.ly") == 0) {
cerr << "Please do not use default set of app key and server url" << endl;
}

ct.start(_appKey, _serverUrl, 443, true);

ct.setAutomaticSessionUpdateInterval(5);// The value is set so low just for internal validation.
ct.setMaxRQProcessingBatchSize(2); // in most cases not needed to be set. The value is set so low just for internal validation
Expand Down
8 changes: 8 additions & 0 deletions include/countly.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class Countly : public cly::CountlyDelegates {

void setSha256(cly::SHA256Function fun);

void enableManualSessionControl();

void setHTTPClient(HTTPClientFunction fun);

void setMetrics(const std::string &os, const std::string &os_version, const std::string &device, const std::string &resolution, const std::string &carrier, const std::string &app_version);
Expand Down Expand Up @@ -105,6 +107,11 @@ class Countly : public cly::CountlyDelegates {
*/
int checkEQSize();

/*
* Checks and returns the size of the request queue in memory or persistent storage.
*/
int checkRQSize();

/**
* Checks and returns the size of the event queue in persistent storage.
*/
Expand Down Expand Up @@ -319,6 +326,7 @@ class Countly : public cly::CountlyDelegates {
std::chrono::system_clock::duration getSessionDuration();

void updateLoop();
void packEvents();
bool began_session = false;
bool is_being_disposed = false;
bool is_sdk_initialized = false;
Expand Down
2 changes: 1 addition & 1 deletion include/countly/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <string>

#define COUNTLY_SDK_NAME "cpp-native-unknown"
#define COUNTLY_SDK_VERSION "23.2.0"
#define COUNTLY_SDK_VERSION "23.2.2"
#define COUNTLY_POST_THRESHOLD 2000
#define COUNTLY_KEEPALIVE_INTERVAL 3000
#define COUNTLY_MAX_EVENTS_DEFAULT 200
Expand Down
2 changes: 2 additions & 0 deletions include/countly/countly_configuration.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ struct CountlyConfiguration {

SHA256Function sha256_function = nullptr;

bool manualSessionControl = false;

HTTPClientFunction http_client_function = nullptr;

nlohmann::json metrics;
Expand Down
2 changes: 2 additions & 0 deletions include/countly/request_module.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class RequestModule {
*/
void clearRequestQueue();

long long RQSize();

private:
class RequestModuleImpl;
std::unique_ptr<RequestModuleImpl> impl;
Expand Down
Loading
Loading