Java

Send SMS with Java

🔑

A Java client library for interacting with the CloudContactAI API using Spring Boot.

Prerequisites

To get the most out of this guide, you'll need to:

  • Sign up for a CCAI Trial Account here
  • Get your Client ID from Account\Settings
  • Create\Copy an API Key from Account Settings

1. Install

Maven

Add the following dependency to your pom.xml :

<dependency>
    <groupId>com.cloudcontactai</groupId>
    <artifactId>ccai-java</artifactId>
    <version>1.0.0</version>
</dependency>

Gradle

Add the following to your build.gradle:

implementation 'com.cloudcontactai:ccai-java:1.0.0'

2. Configuration

Environmental Variables

Create a .env file in your project root or set environment variables:

CCAI_CLIENT_ID=1231
CCAI_API_KEY=your-api-key-here
CCAI_BASE_URL=https://core.cloudcontactai.com/api
CCAI_EMAIL_BASE_URL=https://email-campaigns.cloudcontactai.com
CCAI_AUTH_BASE_URL=https://auth.cloudcontactai.com

Application Properties

Add to your application.properties:

ccai.client-id=${CCAI_CLIENT_ID}
ccai.api-key=${CCAI_API_KEY}
ccai.base-url=${CCAI_BASE_URL:https://core.cloudcontactai.com/api}
ccai.email-base-url=${CCAI_EMAIL_BASE_URL:https://email-campaigns.cloudcontactai.com}
ccai.auth-base-url=${CCAI_AUTH_BASE_URL:https://auth.cloudcontactai.com}
ccai.debug-mode=false
ccai.timeout-ms=30000
ccai.max-retries=3

3. Usage

SMS Basic Usage

import com.cloudcontactai.ccai.client.CCAIClient;
import com.cloudcontactai.ccai.sms.SMSResponse;
import com.cloudcontactai.ccai.exception.CCAIApiException;

// Initialize the client
CCAIClient client = CCAIClient.builder()
    .clientId("your-client-id")
    .apiKey("your-api-key")
    .debugMode(true)
    .build();

try {
    // Send SMS to a single number
    SMSResponse response = client.getSmsService().sendSMS(
        "+1234567890", 
        "Hello from CCAI Java!"
    );
    
    System.out.println("SMS sent successfully: " + response.getCampaignId());
    
} catch (CCAIApiException e) {
    System.err.println("Failed to send SMS: " + e.getMessage());
}

SMS Bulk Usage

import java.util.Arrays;
import java.util.List;

List<String> phoneNumbers = Arrays.asList("+1234567890", "+0987654321");

SMSResponse response = client.getSmsService().sendSMS(
    phoneNumbers,
    "Hello everyone from CCAI Java!"
);

System.out.println("Sent to " + response.getSentCount() + " numbers");
System.out.println("Failed: " + response.getFailedCount() + " numbers");

SMS Advanced Usage

import com.cloudcontactai.ccai.sms.SMSRequest;
import java.util.HashMap;
import java.util.Map;

SMSRequest request = new SMSRequest();
request.setPhoneNumbers(Arrays.asList("+1234567890"));
request.setMessage("Hello {{name}}, your order {{order_id}} is ready!");
request.setCampaignId("welcome-campaign");

// Add custom data
Map<String, Object> customData = new HashMap<>();
customData.put("user_id", "12345");
customData.put("order_id", "ORD-789");
request.setCustomData(customData);

SMSResponse response = client.getSmsService().sendSMS(request);

SMS Async Usage

import java.util.concurrent.CompletableFuture;

CompletableFuture<SMSResponse> future = client.getSmsService().sendSMSAsync(
    "+1234567890",
    "Async SMS message!"
);

future.thenAccept(response -> {
    System.out.println("Async SMS sent: " + response.getCampaignId());
}).exceptionally(throwable -> {
    System.err.println("Async SMS failed: " + throwable.getMessage());
    return null;
});

Email Basic Usage

import com.cloudcontactai.ccai.email.EmailResponse;

EmailResponse response = client.getEmailService().sendEmail(
    "[email protected]",
    "Hello from CCAI Java",
    "<h1>Hello!</h1><p>This is a test email from CCAI Java.</p>"
);

System.out.println("Email sent: " + response.getMessageId());

Email Advanced Usage

import com.cloudcontactai.ccai.email.EmailRequest;

EmailRequest request = new EmailRequest();
request.setToEmails(Arrays.asList("[email protected]"));
request.setSubject("Welcome to Our Service");
request.setHtmlContent("<h1>Welcome {{name}}!</h1><p>Thanks for joining us.</p>");
request.setTextContent("Welcome {{name}}! Thanks for joining us.");
request.setFromEmail("[email protected]");
request.setFromName("Your Company");
request.setReplyTo("[email protected]");

// Add variables for template substitution
Map<String, String> variables = new HashMap<>();
variables.put("name", "John Doe");
request.setVariables(variables);

EmailResponse response = client.getEmailService().sendEmail(request);

MMS Usage

import com.cloudcontactai.ccai.mms.MMSResponse;
import java.io.File;

// Send MMS with automatic image upload (recommended)
File imageFile = new File("path/to/image.jpg");

MMSResponse mmsResponse = client.getMmsService().sendWithImage(
    imageFile,
    "image/jpeg",
    "+15551234567",
    "Hello! Check out this image.",
    "MMS Campaign"
);

System.out.println("MMS sent with ID: " + mmsResponse.getCampaignId());

// Send MMS to multiple recipients
List<String> mmsNumbers = Arrays.asList("+15551234567", "+15559876543");

MMSResponse bulkMmsResponse = client.getMmsService().sendWithImage(
    imageFile,
    "image/jpeg",
    mmsNumbers,
    "Check out this image!",
    "Bulk MMS Campaign"
);

System.out.println("Bulk MMS sent: " + bulkMmsResponse.getCampaignId());

Supported Media Types:

Content TypeExtension
image/jpeg.jpg, .jpeg
image/png.png
image/gif.gif

Webhook Handling

import com.cloudcontactai.ccai.webhook.WebhookEvent;
import com.cloudcontactai.ccai.webhook.WebhookService;
import org.springframework.web.bind.annotation.*;

@RestController
public class WebhookController {
    
    private final WebhookService webhookService;
    
    public WebhookController(CCAIClient client) {
        this.webhookService = client.getWebhookService();
    }
    
    @PostMapping("/webhook/ccai")
    public ResponseEntity<String> handleWebhook(
            @RequestBody String payload,
            @RequestHeader(value = "X-CCAI-Signature", required = false) String signature) {
        
        try {
            // Validate signature (optional but recommended)
            String webhookSecret = System.getenv("CCAI_WEBHOOK_SECRET");
            if (webhookSecret != null && !webhookService.validateWebhookSignature(payload, signature, webhookSecret)) {
                return ResponseEntity.status(401).body("Invalid signature");
            }
            
            // Parse and handle the event
            WebhookEvent event = webhookService.parseWebhookEvent(payload);
            webhookService.handleWebhookEvent(event);
            
            return ResponseEntity.ok("Webhook processed");
            
        } catch (Exception e) {
            return ResponseEntity.status(500).body("Error: " + e.getMessage());
        }
    }
}

5. Springboot Integration

Auto Configuration

The library provides auto-configuration for Spring Boot applications. Simply add the dependency and configure the properties:

@SpringBootApplication
public class MyApplication {
    
    @Autowired
    private CCAIClient ccaiClient;
    
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
    
    @EventListener(ApplicationReadyEvent.class)
    public void sendWelcomeSMS() throws CCAIApiException {
        SMSResponse response = ccaiClient.getSmsService().sendSMS(
            "+1234567890",
            "Application started successfully!"
        );
        System.out.println("Welcome SMS sent: " + response.getCampaignId());
    }
}

Custom Configuration

@Configuration
public class CCAIConfiguration {
    
    @Bean
    @Primary
    public CCAIClient customCCAIClient() {
        return CCAIClient.builder()
            .clientId(System.getenv("CCAI_CLIENT_ID"))
            .apiKey(System.getenv("CCAI_API_KEY"))
            .debugMode(true)
            .timeoutMs(60000)
            .maxRetries(5)
            .build();
    }
}

6. Error Handling

import com.cloudcontactai.ccai.exception.CCAIApiException;

try {
    SMSResponse response = client.getSmsService().sendSMS("+1234567890", "Test");
} catch (CCAIApiException e) {
    System.err.println("API Error: " + e.getMessage());
    System.err.println("Status Code: " + e.getStatusCode());
    System.err.println("Error Code: " + e.getErrorCode());
}

7. Testing

Run the tests with Maven:

mvn test

Run with coverage:

mvn test jacoco:report

8. Examples

The src/main/java/com/cloudcontactai/ccai/examples directory contains complete examples:

  • BasicSMSExample.java - Basic SMS sending examples
  • BasicEmailExample.java - Basic email sending examples
  • WebhookExample.java - Complete webhook handling server

To run the examples:

# Set environment variables
export CCAI_CLIENT_ID="your-client-id"
export CCAI_API_KEY="your-api-key"

# Run SMS example
mvn exec:java -Dexec.mainClass="com.cloudcontactai.ccai.examples.BasicSMSExample"

# Run email example
mvn exec:java -Dexec.mainClass="com.cloudcontactai.ccai.examples.BasicEmailExample"

# Run webhook server
mvn spring-boot:run -Dspring-boot.run.mainClass="com.cloudcontactai.ccai.examples.WebhookExample"

9. Building

Build the project:

mvn clean compile

Package the JAR:

mvn clean package

Install to local repository:

mvn clean install

10. Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests for your changes
  5. Ensure all tests pass
  6. Submit a pull request

11. License

This project is licensed under the MIT License - see the LICENSE file for details.

12. Contact Validator

Validate email addresses and phone numbers.

Bulk endpoints accept up to 50 contacts per request and are processed server-side in chunks.

import com.cloudcontactai.ccai.contactvalidator.ValidationResult;
import com.cloudcontactai.ccai.contactvalidator.BulkValidationResult;
import java.util.Arrays;

// Validate a single email
ValidationResult emailResult = client.getContactValidator().validateEmail("[email protected]");
System.out.println("Status: " + emailResult.getStatus()); // "valid" | "invalid" | "risky"

// Validate multiple emails (up to 50)
BulkValidationResult bulkEmails = client.getContactValidator().validateEmails(
    Arrays.asList("[email protected]", "[email protected]")
);
System.out.println("Total: " + bulkEmails.getSummary().getTotal());
System.out.println("Valid: " + bulkEmails.getSummary().getValid());

// Validate a single phone number
ValidationResult phoneResult = client.getContactValidator().validatePhone("+15551234567", "US");
System.out.println("Status: " + phoneResult.getStatus()); // "valid" | "invalid" | "landline"

// Validate multiple phone numbers (up to 50)
BulkValidationResult bulkPhones = client.getContactValidator().validatePhones(Arrays.asList(
    new PhoneInput("+15551234567", null),
    new PhoneInput("+15559876543", "US")
));
System.out.println("Landline: " + bulkPhones.getSummary().getLandline());

13. Brand Registration

Register and manage brands for TCR verification.

import com.cloudcontactai.ccai.brands.BrandRequest;
import com.cloudcontactai.ccai.brands.BrandResponse;

// Create a brand
BrandRequest brandRequest = BrandRequest.builder()
    .legalCompanyName("Your Company LLC")
    .entityType("PRIVATE_PROFIT")
    .taxId("123456789")
    .taxIdCountry("US")
    .country("US")
    .verticalType("TECHNOLOGY")
    .websiteUrl("https://www.yourcompany.com")
    .street("123 Main St")
    .city("San Francisco")
    .state("CA")
    .postalCode("94105")
    .contactFirstName("Jane")
    .contactLastName("Smith")
    .contactEmail("[email protected]")
    .contactPhone("+14155551234")
    .build();

BrandResponse brand = client.getBrandsService().create(brandRequest);
System.out.println("Brand created with ID: " + brand.getId());

// List all brands
List<BrandResponse> brands = client.getBrandsService().list();
System.out.println("Total brands: " + brands.size());

// Get a brand by ID
BrandResponse fetched = client.getBrandsService().get(brand.getId());
System.out.println("Brand name: " + fetched.getLegalCompanyName());

Entity Types: PRIVATE_PROFIT, PUBLIC_PROFIT, NON_PROFIT, GOVERNMENT, SOLE_PROPRIETOR

Vertical Types: AUTOMOTIVE, AGRICULTURE, BANKING, COMMUNICATION, CONSTRUCTION, EDUCATION, ENERGY, ENTERTAINMENT, GOVERNMENT, HEALTHCARE, HOSPITALITY, INSURANCE, LEGAL, MANUFACTURING, NON_PROFIT, PROFESSIONAL, REAL_ESTATE, RETAIL, TECHNOLOGY, TRANSPORTATION

14. Campaign Registration

Register and manage campaigns for TCR carrier vetting.

import com.cloudcontactai.ccai.campaigns.CampaignRequest;
import com.cloudcontactai.ccai.campaigns.CampaignResponse;

// Create a campaign
CampaignRequest campaignRequest = CampaignRequest.builder()
    .brandId(brand.getId())
    .useCase("MARKETING")
    .description("Promotional messages for opted-in customers")
    .messageFlow("Users opt-in via web form and receive promotional SMS")
    .hasEmbeddedLinks(true)
    .hasEmbeddedPhone(false)
    .isAgeGated(false)
    .isDirectLending(false)
    .optInKeywords(Arrays.asList("START", "YES"))
    .optInMessage("Welcome! Reply STOP to cancel.")
    .optInProofUrl("https://www.yourcompany.com/sms-opt-in")
    .helpKeywords(Arrays.asList("HELP"))
    .helpMessage("Reply HELP for assistance. Contact [email protected].")
    .optOutKeywords(Arrays.asList("STOP", "CANCEL"))
    .optOutMessage("STOP received. You are unsubscribed.")
    .sampleMessages(Arrays.asList(
        "Hi Jane, check out our deals at https://example.com. Reply STOP to opt out.",
        "Your order has shipped! Reply HELP for help."
    ))
    .build();

CampaignResponse campaign = client.getCampaignsService().create(campaignRequest);
System.out.println("Campaign created with ID: " + campaign.getId());

// List all campaigns
List<CampaignResponse> campaigns = client.getCampaignsService().list();
System.out.println("Total campaigns: " + campaigns.size());

Use Cases: TWO_FACTOR_AUTHENTICATION, ACCOUNT_NOTIFICATION, CUSTOMER_CARE, DELIVERY_NOTIFICATION, FRAUD_ALERT, HIGHER_EDUCATION, LOW_VOLUME_MIXED, MARKETING, MIXED, POLLING_VOTING, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT

MIXED and LOW_VOLUME_MIXED campaigns require 2–3 subUseCases.

Sub-Use Cases: TWO_FACTOR_AUTHENTICATION, ACCOUNT_NOTIFICATION, CUSTOMER_CARE, DELIVERY_NOTIFICATION, FRAUD_ALERT, MARKETING, POLLING_VOTING

Try it yourself

See the full source code here.


Did this page help you?