diff --git a/Makefile b/Makefile index d85f552..de6fcf7 100644 --- a/Makefile +++ b/Makefile @@ -279,7 +279,6 @@ listTargets: $(SRCS) $(EXAMPLES_DIR)/messaging/messages/listTargets.cpp @mkdir -p ./$(TESTS_DIR) $(CXX) $(CXXFLAGS) -o ./$(TESTS_DIR)/listTargets $(SRCS) $(EXAMPLES_DIR)/messaging/messages/listTargets.cpp $(LDFLAGS) - listProviderLogs: $(SRCS) $(EXAMPLES_DIR)/messaging/messages/listProviderLogs.cpp @mkdir -p ./$(TESTS_DIR) $(CXX) $(CXXFLAGS) -o ./$(TESTS_DIR)/listProviderLogs $(SRCS) $(EXAMPLES_DIR)/messaging/messages/listProviderLogs.cpp $(LDFLAGS) @@ -288,6 +287,10 @@ createSms: $(SRCS) $(EXAMPLES_DIR)/messaging/messages/createSms.cpp @mkdir -p ./$(TESTS_DIR) $(CXX) $(CXXFLAGS) -o ./$(TESTS_DIR)/createSms $(SRCS) $(EXAMPLES_DIR)/messaging/messages/createSms.cpp $(LDFLAGS) +createEmail: $(SRCS) $(EXAMPLES_DIR)/messaging/messages/createEmail.cpp + @mkdir -p ./$(TESTS_DIR) + $(CXX) $(CXXFLAGS) -o ./$(TESTS_DIR)/createEmail $(SRCS) $(EXAMPLES_DIR)/messaging/messages/createEmail.cpp $(LDFLAGS) + # Messaging - Topics getTopic: $(SRCS) $(EXAMPLES_DIR)/messaging/topics/getTopic.cpp @mkdir -p ./$(TESTS_DIR) diff --git a/examples/messaging/messages/createEmail.cpp b/examples/messaging/messages/createEmail.cpp new file mode 100644 index 0000000..a7a8227 --- /dev/null +++ b/examples/messaging/messages/createEmail.cpp @@ -0,0 +1,49 @@ +#include "Appwrite.hpp" +#include +#include + +int main() { + std::string projectId = ""; + std::string apiKey = ""; + + Appwrite appwrite(projectId, apiKey); + + std::string messageId = "email001"; + std::string subject = "Hello from C++ Appwrite SDK!"; + std::string content = + "Testing Email message creation with topics, users, and targets."; + + std::vector topics = {}; + std::vector users = {}; + std::vector targets = {}; + std::vector cc = {}; + std::vector bcc = {}; + std::vector attachments = {}; + + auto now = std::chrono::system_clock::now(); + auto future_time = now + std::chrono::minutes(5); + auto time_t = std::chrono::system_clock::to_time_t(future_time); + auto ms = std::chrono::duration_cast( + future_time.time_since_epoch()) % + 1000; + + std::stringstream ss; + ss << std::put_time(std::gmtime(&time_t), "%Y-%m-%dT%H:%M:%S"); + ss << "." << std::setfill('0') << std::setw(3) << ms.count() << "+00:00"; + std::string scheduled_at = ss.str(); + + bool draft = true; + bool html = false; + + try { + std::string response = appwrite.getMessaging().createEmail( + messageId, subject, content, topics, users, targets, cc, bcc, + attachments, draft, html, scheduled_at); + std::cout << "Email Message Created!\nResponse: " << response + << std::endl; + } catch (const AppwriteException &ex) { + std::cerr << "Exception: " << ex.what() << std::endl; + } + + return 0; +} \ No newline at end of file diff --git a/include/classes/Messaging.hpp b/include/classes/Messaging.hpp index 4fbe293..1573b91 100644 --- a/include/classes/Messaging.hpp +++ b/include/classes/Messaging.hpp @@ -177,6 +177,36 @@ class Messaging { bool draft = false, const std::string &scheduled_at = ""); + /** + * @brief Create a new email message. + * + * @param messageId Unique ID for the message. + * @param subject Subject line of the email. + * @param content Email Content. + * @param topics List of topic IDs (optional). + * @param users List of User IDs (optional). + * @param targets List of target IDs (optional). + * @param cc List of target IDs to be added as CC. + * @param bcc List of target IDs to be added as BCC. + * @param attachments List of compound ID strings of bucket IDs and file IDs + * to be attached to the email. + * @param draft If true, saves the message as a draft. + * @param html Is content of type HTML + * @param scheduled_at Scheduled delivery time for message. + * @return JSON response. + */ + std::string createEmail(const std::string &messageId, + const std::string &subject, + const std::string &content, + const std::vector &topics = {}, + const std::vector &users = {}, + const std::vector &targets = {}, + const std::vector &cc = {}, + const std::vector &bcc = {}, + const std::vector &attachments = {}, + bool draft = false, bool html = false, + const std::string &scheduled_at = ""); + /** * @brief Updates an existing push notification * message. diff --git a/src/services/Messaging.cpp b/src/services/Messaging.cpp index 1dac611..e77ee64 100644 --- a/src/services/Messaging.cpp +++ b/src/services/Messaging.cpp @@ -548,6 +548,83 @@ std::string Messaging::createSms(const std::string &messageId, } } +// Added method to create a new email message. +std::string Messaging::createEmail( + const std::string &messageId, const std::string &subject, + const std::string &content, const std::vector &topics, + const std::vector &users, + const std::vector &targets, const std::vector &cc, + const std::vector &bcc, + const std::vector &attachments, bool draft, bool html, + const std::string &scheduled_at) { + + if (messageId.empty()) { + throw AppwriteException("Missing required parameter: 'messageId'"); + } + if (subject.empty()) { + throw AppwriteException("Missing required parameter: 'subject'"); + } + if (content.empty()) { + throw AppwriteException("Missing required parameter: 'content'"); + } + + std::string payload = + R"({"messageId":")" + Utils::escapeJsonString(messageId) + + R"(","subject":")" + Utils::escapeJsonString(subject) + + R"(","content":")" + Utils::escapeJsonString(content) + R"(")"; + + auto addFieldToPayload = [](std::string &payload, + const std::string &fieldName, + const std::vector &items) { + if (items.empty()) + return; + + payload += R"(,")" + fieldName + R"(":[)"; + for (size_t i = 0; i < items.size(); ++i) { + payload += "\"" + Utils::escapeJsonString(items[i]) + "\""; + if (i != items.size() - 1) + payload += ","; + } + payload += "]"; + }; + + addFieldToPayload(payload, "topics", topics); + addFieldToPayload(payload, "users", users); + addFieldToPayload(payload, "targets", targets); + addFieldToPayload(payload, "cc", cc); + addFieldToPayload(payload, "bcc", bcc); + addFieldToPayload(payload, "attachments", attachments); + + payload += std::string(R"(,"draft":)") + (draft ? "true" : "false"); + + payload += std::string(R"(,"html":)") + (html ? "true" : "false"); + + if (!scheduled_at.empty()) { + payload += R"(,"scheduledAt":")" + + Utils::escapeJsonString(scheduled_at) + "\""; + } + + payload += "}"; + + std::string url = Config::API_BASE_URL + "/messaging/messages/email"; + + std::vector headers = Config::getHeaders(projectId); + headers.push_back("X-Appwrite-Key: " + apiKey); + headers.push_back("Content-Type: application/json"); + + std::string response; + + int statusCode = Utils::postRequest(url, payload, headers, response); + + if (statusCode == HttpStatus::CREATED || statusCode == HttpStatus::OK) { + return response; + } else { + throw AppwriteException( + "Error creating a new email message. Status code: " + + std::to_string(statusCode) + "\n\nResponse: " + response); + } +} + std::string Messaging::updateEmail(const std::string &messageId, const std::string &subject, const std::string &content) { @@ -827,7 +904,8 @@ std::string Messaging::listTopicLogs(const std::string &topicId, throw AppwriteException("Missing required parameter: 'topicId'"); } - std::string url = Config::API_BASE_URL + "/messaging/topics/" + topicId + "/logs"; + std::string url = + Config::API_BASE_URL + "/messaging/topics/" + topicId + "/logs"; std::string queryParam = ""; if (!queries.empty()) { @@ -846,8 +924,8 @@ std::string Messaging::listTopicLogs(const std::string &topicId, if (statusCode == HttpStatus::OK) { return response; } else { - throw AppwriteException( - "Error fetching topic logs. Status code: " + std::to_string(statusCode) + - "\n\nResponse: " + response); + throw AppwriteException("Error fetching topic logs. Status code: " + + std::to_string(statusCode) + + "\n\nResponse: " + response); } }