diff --git a/examples/ContentApiAdvanced.md b/examples/ContentApiAdvanced.md new file mode 100644 index 000000000..76593dff6 --- /dev/null +++ b/examples/ContentApiAdvanced.md @@ -0,0 +1,287 @@ +# Content API - Advanced Content Types (Carousel & Catalog) + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class AdvancedContentExample +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create carousel content for multiple products + CreateCarouselContent(); + + // Create catalog content for product browsing + CreateCatalogContent(); + + Console.WriteLine("Advanced content examples created successfully!"); + } + catch (Exception ex) + { + Console.WriteLine($"Error: {ex.Message}"); + } + } + + static void CreateCarouselContent() + { + Console.WriteLine("=== Creating Carousel Content ==="); + + // Create carousel cards + var cards = new List(); + + // Card 1 - Premium Plan + var premiumActions = new List + { + new ContentResource.CarouselAction.Builder() + .WithType(ContentResource.CarouselActionType.Url) + .WithTitle("Choose Premium") + .WithUrl("https://example.com/premium") + .WithId("premium_select") + .Build(), + new ContentResource.CarouselAction.Builder() + .WithType(ContentResource.CarouselActionType.QuickReply) + .WithTitle("Learn More") + .WithId("premium_info") + .Build() + }; + + var premiumCard = new ContentResource.CarouselCard.Builder() + .WithTitle("Premium Plan") + .WithBody("Full access with priority support - $99/month") + .WithMedia("https://example.com/premium-plan.jpg") + .WithActions(premiumActions) + .Build(); + + // Card 2 - Standard Plan + var standardActions = new List + { + new ContentResource.CarouselAction.Builder() + .WithType(ContentResource.CarouselActionType.Url) + .WithTitle("Choose Standard") + .WithUrl("https://example.com/standard") + .WithId("standard_select") + .Build(), + new ContentResource.CarouselAction.Builder() + .WithType(ContentResource.CarouselActionType.QuickReply) + .WithTitle("Learn More") + .WithId("standard_info") + .Build() + }; + + var standardCard = new ContentResource.CarouselCard.Builder() + .WithTitle("Standard Plan") + .WithBody("Core features with email support - $49/month") + .WithMedia("https://example.com/standard-plan.jpg") + .WithActions(standardActions) + .Build(); + + // Card 3 - Basic Plan + var basicActions = new List + { + new ContentResource.CarouselAction.Builder() + .WithType(ContentResource.CarouselActionType.Url) + .WithTitle("Choose Basic") + .WithUrl("https://example.com/basic") + .WithId("basic_select") + .Build(), + new ContentResource.CarouselAction.Builder() + .WithType(ContentResource.CarouselActionType.QuickReply) + .WithTitle("Learn More") + .WithId("basic_info") + .Build() + }; + + var basicCard = new ContentResource.CarouselCard.Builder() + .WithTitle("Basic Plan") + .WithBody("Essential features - $19/month") + .WithMedia("https://example.com/basic-plan.jpg") + .WithActions(basicActions) + .Build(); + + cards.Add(premiumCard); + cards.Add(standardCard); + cards.Add(basicCard); + + // Create carousel content + var carouselContent = new ContentResource.TwilioCarousel.Builder() + .WithBody("Choose the plan that best fits your needs:") + .WithCards(cards) + .Build(); + + // Create content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioCarousel(carouselContent) + .Build(); + + // Create content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Subscription Plans Carousel") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + Console.WriteLine($"Carousel content created: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + Console.WriteLine(); + } + + static void CreateCatalogContent() + { + Console.WriteLine("=== Creating Catalog Content ==="); + + // Create catalog items + var catalogItems = new List(); + + var item1 = new ContentResource.CatalogItem.Builder() + .WithId("laptop_001") + .WithSectionTitle("Electronics") + .WithName("Premium Laptop") + .WithMediaUrl("https://example.com/laptop.jpg") + .WithPrice(1299.99m) + .WithDescription("High-performance laptop with 16GB RAM - $1299.99 USD") + .Build(); + + var item2 = new ContentResource.CatalogItem.Builder() + .WithId("phone_001") + .WithSectionTitle("Electronics") + .WithName("Smartphone Pro") + .WithMediaUrl("https://example.com/phone.jpg") + .WithPrice(899.99m) + .WithDescription("Latest smartphone with advanced camera - $899.99 USD") + .Build(); + + var item3 = new ContentResource.CatalogItem.Builder() + .WithId("headphones_001") + .WithSectionTitle("Audio") + .WithName("Wireless Headphones") + .WithMediaUrl("https://example.com/headphones.jpg") + .WithPrice(299.99m) + .WithDescription("Premium noise-cancelling headphones - $299.99 USD (Sale: $249.99)") + .Build(); + + catalogItems.Add(item1); + catalogItems.Add(item2); + catalogItems.Add(item3); + + // Create catalog content + var catalogContent = new ContentResource.TwilioCatalog.Builder() + .WithTitle("Tech Store Catalog") + .WithBody("Browse our latest technology products") + .WithSubtitle("Free shipping on orders over $50") + .WithId("tech_catalog_2024") + .WithItems(catalogItems) + .Build(); + + // Create content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioCatalog(catalogContent) + .Build(); + + // Create content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Technology Product Catalog") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + Console.WriteLine($"Catalog content created: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + Console.WriteLine(); + } + + // Example of creating dynamic catalog content + static void CreateDynamicCatalogContent() + { + Console.WriteLine("=== Creating Dynamic Catalog Content ==="); + + // Dynamic catalog uses external data source + var catalogContent = new ContentResource.TwilioCatalog.Builder() + .WithTitle("{{catalog_title}}") + .WithBody("{{catalog_description}}") + .WithSubtitle("{{catalog_subtitle}}") + .WithId("dynamic_catalog") + .WithDynamicItems("catalog_endpoint_url") // URL to fetch items dynamically + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioCatalog(catalogContent) + .Build(); + + var variables = new Dictionary + { + {"catalog_title", "{{1}}"}, + {"catalog_description", "{{2}}"}, + {"catalog_subtitle", "{{3}}"} + }; + + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Dynamic Catalog Template") + .WithLanguage("en") + .WithVariables(variables) + .WithTypes(contentTypes) + .Build(); + + var content = ContentResource.Create(contentRequest); + Console.WriteLine($"Dynamic catalog created: {content.Sid}"); + } +} +``` + +## Key Features of Advanced Content Types + +### Carousel Content +- **Multiple Cards**: Display several items in a scrollable format +- **Rich Media**: Each card can have images, titles, and descriptions +- **Interactive Actions**: Multiple action buttons per card +- **Perfect For**: Product showcases, service comparisons, feature highlights + +### Catalog Content +- **Product Listings**: Structured product information with pricing +- **Categories**: Organize items by section titles +- **Sale Pricing**: Support for regular and sale prices +- **Dynamic Content**: Can fetch items from external APIs +- **Perfect For**: E-commerce, product browsing, inventory displays + +### Best Practices for Advanced Content + +1. **Optimize Card Count**: Keep carousel cards to 3-10 items for best UX +2. **Consistent Sizing**: Use similar image dimensions across cards +3. **Clear CTAs**: Make action buttons descriptive and actionable +4. **Price Formatting**: Always include currency codes for international support +5. **Fallback Content**: Provide alternative content for unsupported channels + +### Error Handling for Complex Content + +```csharp +try +{ + var content = ContentResource.Create(contentRequest); + Console.WriteLine($"Success: {content.Sid}"); +} +catch (ApiException ex) when (ex.Code == 20001) +{ + Console.WriteLine("Invalid content structure"); +} +catch (ApiException ex) when (ex.Code == 20429) +{ + Console.WriteLine("Rate limit exceeded"); + // Implement retry logic +} +catch (Exception ex) +{ + Console.WriteLine($"Unexpected error: {ex.Message}"); +} +``` + +These advanced content types enable rich, interactive experiences that can significantly improve customer engagement and conversion rates. \ No newline at end of file diff --git a/examples/ContentApiCRUD.md b/examples/ContentApiCRUD.md new file mode 100644 index 000000000..8541969aa --- /dev/null +++ b/examples/ContentApiCRUD.md @@ -0,0 +1,199 @@ +# Content API - Complete CRUD Operations Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // CREATE: Create new content + Console.WriteLine("=== Creating Content ==="); + var content = CreateTextContent(); + Console.WriteLine($"Created Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + Console.WriteLine(); + + // READ: Fetch the created content + Console.WriteLine("=== Fetching Content ==="); + var fetchedContent = ContentResource.Fetch(content.Sid); + Console.WriteLine($"Fetched Content SID: {fetchedContent.Sid}"); + Console.WriteLine($"Status: {fetchedContent.Status}"); + Console.WriteLine($"Language: {fetchedContent.Language}"); + Console.WriteLine(); + + // READ: List all content + Console.WriteLine("=== Listing All Content ==="); + var contentList = ContentResource.Read(limit: 10); + Console.WriteLine($"Found {contentList.ToList().Count} content items:"); + foreach (var item in contentList) + { + Console.WriteLine($"- {item.FriendlyName} (SID: {item.Sid})"); + } + Console.WriteLine(); + + // DELETE: Delete the content + Console.WriteLine("=== Deleting Content ==="); + var deleteResult = ContentResource.Delete(content.Sid); + Console.WriteLine($"Content deleted: {deleteResult}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error: {ex.Message}"); + } + } + + static ContentResource CreateTextContent() + { + // Create simple text content + var textContent = new ContentResource.TwilioText.Builder() + .WithBody("Welcome to our service! Thank you for signing up.") + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioText(textContent) + .Build(); + + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Welcome Message") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + return ContentResource.Create(contentRequest); + } + + // Example of creating content with multiple types + static ContentResource CreateRichContent() + { + // Create quick reply content + var actions = new List(); + + var yesAction = new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("Yes") + .WithId("yes") + .Build(); + + var noAction = new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("No") + .WithId("no") + .Build(); + + actions.Add(yesAction); + actions.Add(noAction); + + var quickReplyContent = new ContentResource.TwilioQuickReply.Builder() + .WithBody("Are you satisfied with our service?") + .WithActions(actions) + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioQuickReply(quickReplyContent) + .Build(); + + var variables = new Dictionary + { + {"customer_name", "{{1}}"}, + {"service_type", "{{2}}"} + }; + + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Service Satisfaction Survey") + .WithLanguage("en") + .WithVariables(variables) + .WithTypes(contentTypes) + .Build(); + + return ContentResource.Create(contentRequest); + } +} +``` + +## Async Operations Example + +```csharp +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Twilio; +using Twilio.Rest.Content.V1; + +class AsyncContentExample +{ + static async Task Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // CREATE: Create content asynchronously + Console.WriteLine("Creating content asynchronously..."); + var content = await CreateContentAsync(); + Console.WriteLine($"Created Content SID: {content.Sid}"); + + // READ: Fetch content asynchronously + Console.WriteLine("Fetching content asynchronously..."); + var fetchedContent = await ContentResource.FetchAsync(content.Sid); + Console.WriteLine($"Fetched Content: {fetchedContent.FriendlyName}"); + + // READ: List content asynchronously + Console.WriteLine("Listing content asynchronously..."); + var contentList = await ContentResource.ReadAsync(limit: 5); + Console.WriteLine($"Found {contentList.ToList().Count} content items"); + } + catch (Exception ex) + { + Console.WriteLine($"Error: {ex.Message}"); + } + } + + static async Task CreateContentAsync() + { + var mediaUrls = new List { "https://example.com/image.jpg" }; + + var mediaContent = new ContentResource.TwilioMedia.Builder() + .WithBody("Check out our latest product!") + .WithMedia(mediaUrls) + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioMedia(mediaContent) + .Build(); + + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Product Announcement") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + return await ContentResource.CreateAsync(contentRequest); + } +} +``` + +This comprehensive example demonstrates: + +1. **CREATE**: Creating new content with `ContentResource.Create()` +2. **READ**: + - Fetching specific content with `ContentResource.Fetch()` + - Listing all content with `ContentResource.Read()` +3. **DELETE**: Removing content with `ContentResource.Delete()` +4. **Async Operations**: Using async/await for non-blocking operations + +Key points: +- Content API uses JSON payloads for rich content types +- Builder pattern simplifies complex object construction +- All operations support both synchronous and asynchronous execution +- Variables enable content personalization using Twilio's template syntax +- Proper error handling is essential for production applications \ No newline at end of file diff --git a/examples/ContentApiCallToAction.md b/examples/ContentApiCallToAction.md new file mode 100644 index 000000000..055adc7ff --- /dev/null +++ b/examples/ContentApiCallToAction.md @@ -0,0 +1,99 @@ +# Content API - Call To Action Content Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create call to action buttons + var actions = new List(); + + // URL action - link to website + var urlAction = new ContentResource.CallToActionAction.Builder() + .WithType(ContentResource.CallToActionActionType.Url) + .WithTitle("Visit Website") + .WithUrl("https://www.example.com") + .WithId("website_action") + .Build(); + + // Phone number action - call business + var phoneAction = new ContentResource.CallToActionAction.Builder() + .WithType(ContentResource.CallToActionActionType.PhoneNumber) + .WithTitle("Call Us") + .WithPhone("+1234567890") + .WithId("phone_action") + .Build(); + + // Copy code action - promotional code + var codeAction = new ContentResource.CallToActionAction.Builder() + .WithType(ContentResource.CallToActionActionType.CopyCode) + .WithTitle("Copy Promo Code") + .WithCode("SAVE20") + .WithId("promo_action") + .Build(); + + actions.Add(urlAction); + actions.Add(phoneAction); + actions.Add(codeAction); + + // Create call to action content + var callToActionContent = new ContentResource.TwilioCallToAction.Builder() + .WithBody("Get 20% off your next purchase! Click below to visit our website, call for support, or copy your discount code.") + .WithActions(actions) + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioCallToAction(callToActionContent) + .Build(); + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Promotional Call to Action") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Call to action content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating call to action content: {ex.Message}"); + } + } +} +``` + +This example demonstrates how to create call-to-action content with multiple action types: + +1. **URL Action**: Opens a website or deep link + - `Type`: `URL` + - `Title`: Button text + - `Url`: Destination URL + +2. **Phone Action**: Initiates a phone call + - `Type`: `PHONE_NUMBER` + - `Title`: Button text + - `Phone`: Phone number to call + +3. **Copy Code Action**: Copies text to clipboard + - `Type`: `COPY_CODE` + - `Title`: Button text + - `Code`: Text to copy + +Call-to-action content is ideal for driving user engagement with specific actions like visiting websites, making calls, or copying promotional codes. Each action type serves different purposes and can be combined in a single message. \ No newline at end of file diff --git a/examples/ContentApiCard.md b/examples/ContentApiCard.md new file mode 100644 index 000000000..b9b6aaf5a --- /dev/null +++ b/examples/ContentApiCard.md @@ -0,0 +1,97 @@ +# Content API - Card Content Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create media URLs for the card + var mediaUrls = new List + { + "https://example.com/product-image.jpg" + }; + + // Create card actions + var actions = new List(); + + var buyAction = new ContentResource.CardAction.Builder() + .WithType(ContentResource.CardActionType.Url) + .WithTitle("Buy Now") + .WithUrl("https://example.com/buy/product123") + .WithId("buy_action") + .Build(); + + var callAction = new ContentResource.CardAction.Builder() + .WithType(ContentResource.CardActionType.PhoneNumber) + .WithTitle("Call for Info") + .WithPhone("+1234567890") + .WithId("call_action") + .Build(); + + var replyAction = new ContentResource.CardAction.Builder() + .WithType(ContentResource.CardActionType.QuickReply) + .WithTitle("More Details") + .WithId("details_action") + .Build(); + + actions.Add(buyAction); + actions.Add(callAction); + actions.Add(replyAction); + + // Create card content + var cardContent = new ContentResource.TwilioCard.Builder() + .WithTitle("Premium Wireless Headphones") + .WithSubtitle("High-quality sound with noise cancellation. $299.99") + .WithMedia(mediaUrls) + .WithActions(actions) + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioCard(cardContent) + .Build(); + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Product Card - Wireless Headphones") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Card content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating card content: {ex.Message}"); + } + } +} +``` + +This example demonstrates how to create card content that includes: + +1. **Title**: Main heading for the card +2. **Subtitle**: Additional information (price, description, etc.) +3. **Media**: List of image URLs to display +4. **Actions**: Interactive buttons with different action types: + - `URL`: Links to external websites or deep links + - `PHONE_NUMBER`: Initiates phone calls + - `QUICK_REPLY`: Triggers quick reply responses + - `COPY_CODE`: Copies text to clipboard + +Cards are perfect for showcasing products, services, or rich content with a combination of images, text, and interactive buttons. They provide a visually appealing way to present information with clear calls to action. \ No newline at end of file diff --git a/examples/ContentApiListPicker.md b/examples/ContentApiListPicker.md new file mode 100644 index 000000000..0ba2950f2 --- /dev/null +++ b/examples/ContentApiListPicker.md @@ -0,0 +1,86 @@ +# Content API - List Picker Content Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create list items + var items = new List(); + + var item1 = new ContentResource.ListItem.Builder() + .WithId("product_a") + .WithItem("Premium Plan") + .WithDescription("Full access to all features with priority support") + .Build(); + + var item2 = new ContentResource.ListItem.Builder() + .WithId("product_b") + .WithItem("Standard Plan") + .WithDescription("Access to core features with email support") + .Build(); + + var item3 = new ContentResource.ListItem.Builder() + .WithId("product_c") + .WithItem("Basic Plan") + .WithDescription("Limited features with community support") + .Build(); + + items.Add(item1); + items.Add(item2); + items.Add(item3); + + // Create list picker content + var listPickerContent = new ContentResource.TwilioListPicker.Builder() + .WithBody("Choose the plan that best fits your needs:") + .WithButton("Select Plan") + .WithItems(items) + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioListPicker(listPickerContent) + .Build(); + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Subscription Plans List") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"List picker content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating list picker content: {ex.Message}"); + } + } +} +``` + +This example shows how to create a list picker content that includes: + +1. **Message body**: Introduction text explaining the list +2. **Button text**: The text shown on the button that opens the list +3. **List items**: Each item contains: + - `Id`: Unique identifier for the option + - `Item`: The main title/name of the option + - `Description`: Additional details about the option + +List pickers are perfect for presenting multiple options with descriptions, such as product catalogs, service plans, or menu items where users need more context to make informed decisions. \ No newline at end of file diff --git a/examples/ContentApiLocation.md b/examples/ContentApiLocation.md new file mode 100644 index 000000000..4de299184 --- /dev/null +++ b/examples/ContentApiLocation.md @@ -0,0 +1,127 @@ +# Content API - Location Content Example + +```csharp +using System; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create location content + var locationContent = new ContentResource.TwilioLocation.Builder() + .WithLatitude(37.7749m) // San Francisco latitude + .WithLongitude(-122.4194m) // San Francisco longitude + .WithLabel("Twilio HQ") + .WithId("twilio_hq_location") + .WithAddress("375 Beale St, San Francisco, CA 94105, USA") + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioLocation(locationContent) + .Build(); + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Twilio Headquarters Location") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Location content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating location content: {ex.Message}"); + } + } +} +``` + +## Alternative Example - Store Location with Variables + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create location content for a store + var locationContent = new ContentResource.TwilioLocation.Builder() + .WithLatitude(40.7589m) // New York latitude + .WithLongitude(-73.9851m) // New York longitude + .WithLabel("{{store_name}}") // Template variable for store name + .WithId("store_location") + .WithAddress("{{store_address}}") // Template variable for address + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioLocation(locationContent) + .Build(); + + // Create variables for personalization + var variables = new Dictionary + { + {"store_name", "{{1}}"}, + {"store_address", "{{2}}"} + }; + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Store Location Template") + .WithLanguage("en") + .WithVariables(variables) + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Location template created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"This template can be personalized with specific store details when sending."); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating location template: {ex.Message}"); + } + } +} +``` + +These examples show how to create location content that includes: + +1. **Coordinates**: Latitude and longitude for precise positioning +2. **Label**: Display name for the location +3. **Address**: Human-readable address +4. **ID**: Unique identifier for the location + +Location content is perfect for: +- Sharing business locations with customers +- Providing directions to events or meetings +- Creating location-based templates for multiple stores or offices +- Emergency location sharing scenarios + +The second example shows how to use template variables to create reusable location content that can be personalized for different locations. \ No newline at end of file diff --git a/examples/ContentApiMedia.md b/examples/ContentApiMedia.md new file mode 100644 index 000000000..f86e22991 --- /dev/null +++ b/examples/ContentApiMedia.md @@ -0,0 +1,71 @@ +# Content API - Media Content Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create media content with text and image + var mediaUrls = new List + { + "https://example.com/image1.jpg", + "https://example.com/image2.png" + }; + + var mediaContent = new ContentResource.TwilioMedia.Builder() + .WithBody("Check out these amazing images!") + .WithMedia(mediaUrls) + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioMedia(mediaContent) + .Build(); + + // Create the content request with variables for personalization + var variables = new Dictionary + { + {"customer_name", "{{1}}"}, + {"product_name", "{{2}}"} + }; + + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Media Content with Images") + .WithLanguage("en") + .WithVariables(variables) + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Media content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + Console.WriteLine($"Language: {content.Language}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating media content: {ex.Message}"); + } + } +} +``` + +This example shows how to create media content that includes: + +1. **Text body**: A descriptive message accompanying the media +2. **Media URLs**: List of image or video URLs to include +3. **Variables**: Template variables for personalization (using Twilio's variable syntax) + +Media content is perfect for sharing images, videos, or documents alongside explanatory text. The media URLs should point to publicly accessible resources. \ No newline at end of file diff --git a/examples/ContentApiOverview.md b/examples/ContentApiOverview.md new file mode 100644 index 000000000..0a927cc00 --- /dev/null +++ b/examples/ContentApiOverview.md @@ -0,0 +1,287 @@ +# Content API - Overview and Best Practices + +The Twilio Content API allows you to create rich, interactive content templates that can be reused across different messaging channels. This overview demonstrates key concepts and best practices. + +## Key Concepts + +1. **JSON-based API**: Unlike traditional form-encoded APIs, Content API uses JSON payloads +2. **Builder Pattern**: All content types use builders for easy construction +3. **Template Variables**: Support for personalization using `{{variable}}` syntax +4. **Multiple Content Types**: Support for text, media, location, lists, cards, and more +5. **Channel Agnostic**: Content works across WhatsApp, SMS, and other channels + +## Content Types Summary + +| Content Type | Use Case | Key Features | +|-------------|----------|--------------| +| `TwilioText` | Simple messages | Text body only | +| `TwilioMedia` | Rich media | Text + images/videos | +| `TwilioLocation` | Location sharing | Coordinates + address | +| `TwilioQuickReply` | Interactive choices | Text + quick reply buttons | +| `TwilioListPicker` | Option selection | Text + detailed list items | +| `TwilioCallToAction` | Action buttons | Text + action buttons (URL, phone, etc.) | +| `TwilioCard` | Product showcase | Rich cards with media and actions | + +## Complete Example - Multi-Type Content Creation + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class ContentApiDemo +{ + static void Main(string[] args) + { + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + // Create different types of content + CreateTextContent(); + CreateMediaContent(); + CreateInteractiveContent(); + CreateLocationContent(); + CreateRichCardContent(); + + Console.WriteLine("All content examples created successfully!"); + } + + static void CreateTextContent() + { + Console.WriteLine("Creating simple text content..."); + + var textContent = new ContentResource.TwilioText.Builder() + .WithBody("Hello {{customer_name}}, welcome to our service!") + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioText(textContent) + .Build(); + + var variables = new Dictionary + { + {"customer_name", "{{1}}"} + }; + + var content = CreateContent("Welcome Text Template", contentTypes, variables); + Console.WriteLine($"✓ Text content created: {content.Sid}"); + } + + static void CreateMediaContent() + { + Console.WriteLine("Creating media content..."); + + var mediaUrls = new List + { + "https://example.com/product.jpg" + }; + + var mediaContent = new ContentResource.TwilioMedia.Builder() + .WithBody("Check out our new {{product_name}}!") + .WithMedia(mediaUrls) + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioMedia(mediaContent) + .Build(); + + var variables = new Dictionary + { + {"product_name", "{{1}}"} + }; + + var content = CreateContent("Product Media Template", contentTypes, variables); + Console.WriteLine($"✓ Media content created: {content.Sid}"); + } + + static void CreateInteractiveContent() + { + Console.WriteLine("Creating interactive content..."); + + var actions = new List + { + new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("Excellent") + .WithId("rating_5") + .Build(), + new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("Good") + .WithId("rating_4") + .Build(), + new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("Poor") + .WithId("rating_2") + .Build() + }; + + var quickReplyContent = new ContentResource.TwilioQuickReply.Builder() + .WithBody("How would you rate your experience with {{service_name}}?") + .WithActions(actions) + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioQuickReply(quickReplyContent) + .Build(); + + var variables = new Dictionary + { + {"service_name", "{{1}}"} + }; + + var content = CreateContent("Feedback Survey Template", contentTypes, variables); + Console.WriteLine($"✓ Interactive content created: {content.Sid}"); + } + + static void CreateLocationContent() + { + Console.WriteLine("Creating location content..."); + + var locationContent = new ContentResource.TwilioLocation.Builder() + .WithLatitude(37.7749m) + .WithLongitude(-122.4194m) + .WithLabel("{{location_name}}") + .WithAddress("{{location_address}}") + .WithId("business_location") + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioLocation(locationContent) + .Build(); + + var variables = new Dictionary + { + {"location_name", "{{1}}"}, + {"location_address", "{{2}}"} + }; + + var content = CreateContent("Business Location Template", contentTypes, variables); + Console.WriteLine($"✓ Location content created: {content.Sid}"); + } + + static void CreateRichCardContent() + { + Console.WriteLine("Creating rich card content..."); + + var actions = new List + { + new ContentResource.CardAction.Builder() + .WithType(ContentResource.CardActionType.Url) + .WithTitle("Shop Now") + .WithUrl("{{product_url}}") + .WithId("shop_action") + .Build(), + new ContentResource.CardAction.Builder() + .WithType(ContentResource.CardActionType.QuickReply) + .WithTitle("More Info") + .WithId("info_action") + .Build() + }; + + var mediaUrls = new List { "{{product_image_url}}" }; + + var cardContent = new ContentResource.TwilioCard.Builder() + .WithTitle("{{product_name}}") + .WithSubtitle("{{product_description}} - ${{product_price}}") + .WithMedia(mediaUrls) + .WithActions(actions) + .Build(); + + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioCard(cardContent) + .Build(); + + var variables = new Dictionary + { + {"product_name", "{{1}}"}, + {"product_description", "{{2}}"}, + {"product_price", "{{3}}"}, + {"product_url", "{{4}}"}, + {"product_image_url", "{{5}}"} + }; + + var content = CreateContent("Product Card Template", contentTypes, variables); + Console.WriteLine($"✓ Rich card content created: {content.Sid}"); + } + + static ContentResource CreateContent(string friendlyName, ContentResource.Types types, Dictionary variables = null) + { + var requestBuilder = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName(friendlyName) + .WithLanguage("en") + .WithTypes(types); + + if (variables != null) + { + requestBuilder.WithVariables(variables); + } + + var contentRequest = requestBuilder.Build(); + return ContentResource.Create(contentRequest); + } +} +``` + +## Best Practices + +### 1. Use Template Variables for Personalization +```csharp +// Good: Use variables for dynamic content +var variables = new Dictionary +{ + {"customer_name", "{{1}}"}, + {"order_id", "{{2}}"} +}; +``` + +### 2. Handle Errors Gracefully +```csharp +try +{ + var content = ContentResource.Create(contentRequest); + Console.WriteLine($"Success: {content.Sid}"); +} +catch (ApiException ex) +{ + Console.WriteLine($"API Error: {ex.Message}"); + Console.WriteLine($"Error Code: {ex.Code}"); +} +``` + +### 3. Use Async Operations for Better Performance +```csharp +var content = await ContentResource.CreateAsync(contentRequest); +``` + +### 4. Organize Content with Meaningful Names +```csharp +// Good: Descriptive naming +.WithFriendlyName("Welcome Message - New Customer Onboarding") + +// Poor: Generic naming +.WithFriendlyName("Content 1") +``` + +### 5. Validate Template Variables +Always ensure your template variables match what you'll send when using the content: +- `{{1}}` maps to the first variable in your message +- `{{2}}` maps to the second variable, etc. + +## Error Handling + +Common errors and solutions: + +- **400 Bad Request**: Check JSON structure and required fields +- **401 Unauthorized**: Verify Account SID and Auth Token +- **422 Unprocessable Entity**: Validate content type requirements +- **429 Rate Limited**: Implement retry logic with backoff + +## Next Steps + +1. Create content templates for your use cases +2. Test with different variable combinations +3. Integrate with your messaging workflows +4. Monitor usage and performance +5. Optimize based on user engagement \ No newline at end of file diff --git a/examples/ContentApiQuickReply.md b/examples/ContentApiQuickReply.md new file mode 100644 index 000000000..21ef93df4 --- /dev/null +++ b/examples/ContentApiQuickReply.md @@ -0,0 +1,85 @@ +# Content API - Quick Reply Content Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create quick reply actions + var actions = new List(); + + var yesAction = new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("Yes") + .WithId("yes_option") + .Build(); + + var noAction = new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("No") + .WithId("no_option") + .Build(); + + var moreInfoAction = new ContentResource.QuickReplyAction.Builder() + .WithType(ContentResource.QuickReplyActionType.QuickReply) + .WithTitle("More Info") + .WithId("more_info") + .Build(); + + actions.Add(yesAction); + actions.Add(noAction); + actions.Add(moreInfoAction); + + // Create quick reply content + var quickReplyContent = new ContentResource.TwilioQuickReply.Builder() + .WithBody("Would you like to receive updates about our new products?") + .WithActions(actions) + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioQuickReply(quickReplyContent) + .Build(); + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Product Update Quick Reply") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Quick reply content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating quick reply content: {ex.Message}"); + } + } +} +``` + +This example demonstrates how to create interactive quick reply content with: + +1. **Message body**: The main question or prompt +2. **Quick reply actions**: Predefined response options for users +3. **Action properties**: + - `Type`: Always `QUICK_REPLY` for quick reply buttons + - `Title`: The text displayed on the button + - `Id`: Unique identifier for tracking which option was selected + +Quick replies are ideal for surveys, feedback collection, and simple decision trees where you want to provide users with predefined response options. \ No newline at end of file diff --git a/examples/ContentApiText.md b/examples/ContentApiText.md new file mode 100644 index 000000000..459ac2150 --- /dev/null +++ b/examples/ContentApiText.md @@ -0,0 +1,58 @@ +# Content API - Text Content Example + +```csharp +using System; +using System.Collections.Generic; +using Twilio; +using Twilio.Rest.Content.V1; + +class Program +{ + static void Main(string[] args) + { + // Initialize Twilio client + TwilioClient.Init("TWILIO_ACCOUNT_SID", "TWILIO_AUTH_TOKEN"); + + try + { + // Create a simple text content + var textContent = new ContentResource.TwilioText.Builder() + .WithBody("Hello! This is a simple text message from Twilio Content API.") + .Build(); + + // Create the content types object + var contentTypes = new ContentResource.Types.Builder() + .WithTwilioText(textContent) + .Build(); + + // Create the content request + var contentRequest = new ContentResource.ContentCreateRequest.Builder() + .WithFriendlyName("Simple Text Content") + .WithLanguage("en") + .WithTypes(contentTypes) + .Build(); + + // Create the content + var content = ContentResource.Create(contentRequest); + + Console.WriteLine($"Content created successfully!"); + Console.WriteLine($"Content SID: {content.Sid}"); + Console.WriteLine($"Friendly Name: {content.FriendlyName}"); + Console.WriteLine($"Language: {content.Language}"); + } + catch (Exception ex) + { + Console.WriteLine($"Error creating content: {ex.Message}"); + } + } +} +``` + +This example demonstrates how to create a simple text content using the Twilio Content API. The key components are: + +1. **TwilioText**: Contains the message body +2. **Types**: Wrapper for different content types (in this case, text) +3. **ContentCreateRequest**: The main request object containing metadata and content types +4. **ContentResource.Create()**: Method to send the request to Twilio + +The Content API uses JSON payloads and the builder pattern for easy construction of complex content structures. \ No newline at end of file