{"id":19519149,"url":"https://github.com/cmdotcom/text-sdk-dotnet","last_synced_at":"2025-04-26T07:31:07.859Z","repository":{"id":33234914,"uuid":"156709399","full_name":"cmdotcom/text-sdk-dotnet","owner":"cmdotcom","description":".NET Standard SDK to send messages with CM.com","archived":false,"fork":false,"pushed_at":"2025-01-31T14:46:15.000Z","size":293,"stargazers_count":13,"open_issues_count":2,"forks_count":18,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-04-04T09:36:07.997Z","etag":null,"topics":["business-messaging","chat","conversational","email","hacktoberfest","messaging","mms","push","rbm","rcs","rich-communication-services","rich-sms","sms","sms-chat","telegram","text","viber","voice","wechat","whatsapp"],"latest_commit_sha":null,"homepage":"https://www.cm.com/communications-platform/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cmdotcom.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-08T13:14:32.000Z","updated_at":"2025-03-10T11:18:44.000Z","dependencies_parsed_at":"2024-01-08T15:01:58.647Z","dependency_job_id":"f43017be-53eb-4875-876b-c3ac3eb7b4c2","html_url":"https://github.com/cmdotcom/text-sdk-dotnet","commit_stats":{"total_commits":141,"total_committers":21,"mean_commits":6.714285714285714,"dds":0.6595744680851063,"last_synced_commit":"10ab519a2b62f7062eb91a74d0cde9c4f633582e"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdotcom%2Ftext-sdk-dotnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdotcom%2Ftext-sdk-dotnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdotcom%2Ftext-sdk-dotnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cmdotcom%2Ftext-sdk-dotnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cmdotcom","download_url":"https://codeload.github.com/cmdotcom/text-sdk-dotnet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250730350,"owners_count":21477752,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["business-messaging","chat","conversational","email","hacktoberfest","messaging","mms","push","rbm","rcs","rich-communication-services","rich-sms","sms","sms-chat","telegram","text","viber","voice","wechat","whatsapp"],"created_at":"2024-11-11T00:16:34.422Z","updated_at":"2025-04-26T07:31:07.581Z","avatar_url":"https://github.com/cmdotcom.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![.NET build \u0026 tests](https://github.com/cmdotcom/text-sdk-dotnet/actions/workflows/main.yml/badge.svg)](https://github.com/cmdotcom/text-sdk-dotnet/actions/workflows/main.yml)\n[![NuGetV](https://img.shields.io/nuget/v/CM.Text.svg \"NuGet Version\")](https://www.nuget.org/packages/CM.Text)\n[![NuGetDownloads](https://img.shields.io/nuget/dt/CM.Text.svg \"NuGet downloads\")](https://www.nuget.org/packages/CM.Text)\n\n# CM Text SDK\nA software development kit to provide ways to interact with CM.com's Text service. API's used:\n- [Messaging](https://developers.cm.com/messaging/docs)\n\n# Usage\n\n## Instantiate the client\nUsing your unique `ApiKey` (or product token) which authorizes you on the CM platform. \nAlways keep this key secret!\n\nThe product token can be found in the [Channels](https://www.cm.com/app/channels) application on the platform, under the `Gateway` section.\n\n```cs\nvar client = new TextClient(new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]));\n```\n\n## Send a message\nBy calling `SendMessageAsync` and providing message text, sender name, recipient phone number(s) and a reference (optional).\n\n```cs\nvar result = await client.SendMessageAsync(\"Message_Text\", \"Sender_Name\", new List\u003cstring\u003e { \"Recipient_PhoneNumber\" }, \"Your_Reference\").ConfigureAwait(false);\n```\n\n## Get the result\n`SendMessageAsync` returns an object of type `TextClientResult`, example:\n\n```cs\n{\n  \"statusMessage\": \"Created 1 message(s)\",\n  \"statusCode\": 201,\n  \"details\": [\n    {\n      \"reference\": \"Example_Reference\",\n      \"status\": \"Accepted\",\n      \"to\": \"Example_PhoneNumber\",\n      \"parts\": 1,\n      \"details\": null\n    },\n    {\n      \"reference\": \"Example_Reference2\",\n      \"status\": \"Rejected\",\n      \"to\": \"Example_PhoneNumber2\",\n      \"parts\": 0,\n      \"details\": \"A body without content was found\"\n    }\n  ]\n}\n```\n\n## Sending a rich message\nBy using the `MessageBuilder` it is possible to create images with media for channels such as WhatsApp and RCS\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\nvar builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\nbuilder\n    .WithAllowedChannels(Channel.WhatsApp)\n    .WithRichMessage(\n        new MediaMessage(\n            \"cm.com\",\n            \"https://avatars3.githubusercontent.com/u/8234794?s=200\u0026v=4\",\n            \"image/png\"\n        )\n    );\nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n\n## Status codes\nFor all possible status codes, please reference the `TextClientStatusCode` enum.\n\n\n## Sending a WhatsApp template message\nBy using the `MessageBuilder` it is possible to create template messages. Please note that this is WhatsApp only and your template needs to be approved before sending.\nFor more info please check our documentation: https://www.cm.com/en-en/app/docs/api/business-messaging-api/1.0/index#whatsapp-template-message\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\nvar builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\nbuilder\n .WithAllowedChannels(Channel.WhatsApp)\n .WithTemplate(new TemplateMessage() {\n  Content = new TemplateMessageContent() {\n   Whatsapp = new WhatsappTemplate() {\n    Name = \"template-name\",\n     Namespace = \"the-namespace-of-template\",\n     Language = new Language() {\n      Code = \"en\",\n       Policy = \"deterministic\"\n     },\n     Components = new TemplateComponents[] {\n      new TemplateComponents() {\n       Type = \"body\",\n        ComponentParameters = new ComponentParameters[] {\n         new ComponentParameters() {\n          Type = \"text\",\n           Text = \"firstname\"\n         }\n        }\n      },\n     }\n   }\n  }\n });\n\nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n## Sending a rich WhatsApp template message\nIt is also possible to send a rich template with an image!\t\t\t\n\t\t\t\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\nvar builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\nbuilder\n .WithAllowedChannels(Channel.WhatsApp)\n .WithTemplate(new TemplateMessage() {\n  Content = new TemplateMessageContent() {\n   Whatsapp = new WhatsappTemplate() {\n    Name = \"template-name\",\n     Namespace = \"the-namespace-of-template\",\n     Language = new Language() {\n      Code = \"en\",\n       Policy = \"deterministic\"\n     },\n     Components = new TemplateComponents[] {\n      new TemplateComponents() {\n        Type = \"header\",\n         ComponentParameters = new ComponentParameters[] {\n          new ComponentParameters() {\n           Type = \"image\",\n            Media = new MediaContent() {\n             MediaName = \"cm.com\",\n              MediaUri = \"https://avatars3.githubusercontent.com/u/8234794?s=200\u0026v=4\"\n            }\n          }\n         }\n       },\n       new TemplateComponents() {\n        Type = \"body\",\n         ComponentParameters = new ComponentParameters[] {\n          new ComponentParameters() {\n           Type = \"text\",\n            Text = \"firstname\"\n          }\n         }\n       },\n     }\n   }\n  }\n });\n\nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n## Sending a WhatsApp template message with date and Currency\nIt is also possible to send a rich template with an currency and an date!\nplease note that the timezone is in UTC format\t\t\n\t\t\t\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\nvar builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\n builder\n .WithAllowedChannels(Channel.WhatsApp)\n .WithTemplate(new TemplateMessage() {\n  Content = new TemplateMessageContent() {\n   Whatsapp = new WhatsappTemplate() {\n                            Name = \"template-name\",\n                            Namespace = \"the-namespace-of-template\",\n                            Language = new Language()\n                            {\n                                Code = \"en\",\n                                Policy = \"deterministic\"\n                            },\n                            Components = new TemplateComponents[] {\n                                new TemplateComponents() {\n                                    Type = \"header\",\n                                    ComponentParameters = new ComponentParameters[] {\n                                        new ComponentParameters() {\n                                            Type = \"image\",\n                                            Media = new MediaContent() {\n                                                MediaName = \"cm.com\",\n                                                MediaUri = \"https://avatars3.githubusercontent.com/u/8234794?s=200\u0026v=4\"\n                                            },\n                                        }\n                                    }\n                                },\n                                new TemplateComponents()\n                                {\n                                    Type = \"body\",\n                                    ComponentParameters = new ComponentParameters[]\n                                    {\n                                        new ComponentParameters()\n                                       {\n                                           Type = \"currency\",\n                                           Currency = new TemplateCurrency()\n                                           {\n                                               FallbackValue = \"$100.99\",\n                                               Amount = 100990,\n                                               CurrencyCode = \"USD\"\n                                           }\n                                       },\n                                       new ComponentParameters()\n                                       {\n                                           Type = \"date_time\",\n                                           DateTime = new TemplateDateTime(DateTime.Now)\n                                       }\n                                    }}\n                            }\n                        }\n                    }\n                });\n\n   var message = builder.Build();\n   var result = await client.SendMessageAsync(message);\n```\n## Sending interactive template messages\nInteractive templates allows you to send templates that include buttons. \nFor more info please visit https://www.cm.com/app/docs/en/api/business-messaging-api/1.0/index#/whatsapp-template-message\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\nvar builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\nbuilder.WithAllowedChannels(Channel.WhatsApp).WithTemplate(new TemplateMessage() {\n\tContent = new TemplateMessageContent() {\n\t\tWhatsapp = new WhatsappTemplate() {\n\t\t\tName = \"Template name\",\n\t\t\tNamespace = \"whatsapp template id\",\n\t\t\tLanguage = new Language() {\n\t\t\t\tCode = \"en\",\n\t\t\t\tPolicy = \"deterministic\"\n\t\t\t},\n\t\t\tComponents = new TemplateComponents[] {\n\t\t\t\tnew TemplateComponents() {\n\t\t\t\t\tType = \"body\",\n\t\t\t\t\tComponentParameters = new ComponentParameters[] {\n\t\t\t\t\t\tnew ComponentParameters() {\n\t\t\t\t\t\t\tType = \"text\",\n\t\t\t\t\t\t\tText = \"your message here\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnew TemplateComponents() {\n\t\t\t\t\tType = \"button\",\n\t\t\t\t\tSubType = \"quick_reply\",\n\t\t\t\t\tIndex = 0,\n\t\t\t\t\tComponentParameters = new ComponentParameters[] {\n\t\t\t\t\t\tnew ComponentParameters() {\n\t\t\t\t\t\t\tType = \"payload\",\n\t\t\t\t\t\t\tPayload = \"developer defined payload\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n## Sending an Apple Pay Request\nIt is now possible to send an apple pay request only possible in Apple Business Chat\n\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\nvar builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\n builder\n        .WithAllowedChannels(Channel.iMessage)\n        .WithApplePay(new ApplePayRequest()\n           {\n             ApplePayConfiguration = new ApplePayConfiguration()\n                 {\n                        Total = 1,\n                        RecipientCountryCode = \"recipient-country-code\",\n                        CurrencyCode = \"currency-code\",\n                        Description = \"product-description\",\n                        RecipientEmail = \"recipient-email\",\n                        languageCountryCode = \"language-country-code\",\n                        OrderReference = \"unique-order-guid\",\n                        MerchantName = \"merchant-name\",\n                        LineItems = new LineItem[]\n                        {\n                            new LineItem()\n                            {\n                                Amount = 1,\n                                Label = \"product-name\",\n                                Type = \"final-or-pending\"\n                            },\n                        }\n                    }\n                });\n            \nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n## Sending WhatsApp interactive messages\nIt is now possible to send list messages and reply buttons without using templates\nonly supported in WhatsApp\n\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\n var builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\n     builder.WithAllowedChannels(Channel.WhatsApp).WithInteractive(new CM.Text.BusinessMessaging.Model.MultiChannel.WhatsAppInteractiveMessage()\n            {\n                whatsAppInteractiveContent = new CM.Text.BusinessMessaging.Model.MultiChannel.WhatsAppInteractiveContent()\n                {\n                    Type = \"list\",\n                    Header = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveHeader()\n                    {\n                        Type = \"text\",\n                        Text = \"List message example\"\n                    },\n                    Body = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveBody()\n                    {\n                        Text = \"checkout our list message demo\"\n                    },\n                    Action = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveAction()\n                    {\n                        Button = \"button text\",\n                        Sections = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveSection[]\n                         {\n                             new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveSection()\n                             {\n                                 Title = \"Select an option\",\n                                 Rows = new CM.Text.BusinessMessaging.Model.MultiChannel.Rows[]\n                                 {\n                                     new CM.Text.BusinessMessaging.Model.MultiChannel.Rows()\n                                     {\n                                         Id = \"unique Id\",\n                                         Title = \"unique title1\",\n                                         Description = \"description text\"\n                                     },\n                                     new CM.Text.BusinessMessaging.Model.MultiChannel.Rows()\n                                     {\n                                         Id = \"unique Id2\",\n                                         Title = \"unique title2\",\n                                         Description = \"description text\"\n                                     },\n                                 }\n                             }\n                         }\n                    },\n                    Footer = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveFooter()\n                    {\n                        Text = \"footer text\"\n                    }\n                }\n        });\n            \nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n\nOnly with Reply buttons you can send media like image,video or document \nsee following example.\n\n```cs\nvar apiKey = new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]);\nvar client = new TextClient(apiKey);\n var builder = new MessageBuilder(\"Message Text\", \"Sender_name\", \"Recipient_PhoneNumber\");\n    builder.WithAllowedChannels(Channel.WhatsApp).WithInteractive(new CM.Text.BusinessMessaging.Model.MultiChannel.WhatsAppInteractiveMessage()\n            {\n                whatsAppInteractiveContent = new CM.Text.BusinessMessaging.Model.MultiChannel.WhatsAppInteractiveContent()\n                {\n                    Type = \"button\",\n                    Header = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveHeader()\n                    {\n                        Type = \"image\",                    \n                        Media = new CM.Text.BusinessMessaging.Model.MultiChannel.MediaContent()\n                         {\n                                MediaUri = \"https://www.cm.com/cdn/web/blog/content/logo-cmcom.png\"\n                          }\n                        \n                    },\n                    Body = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveBody()\n                    {\n                        Text = \"checkout our reply message demo\"\n                    },\n                    Action = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveAction()\n                    {\n                        Buttons = new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveButton[]\n                        {\n                            new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveButton()\n                            {\n                               Type = \"reply\",\n                                Reply = new CM.Text.BusinessMessaging.Model.MultiChannel.ReplyMessage()\n                                {\n                                    Id = \"unique-postback-id1\",\n                                    Title = \"First Button\"\n                                }\n                            },\n                               new CM.Text.BusinessMessaging.Model.MultiChannel.InteractiveButton()\n                            {\n                              Type = \"reply\",\n                                Reply = new CM.Text.BusinessMessaging.Model.MultiChannel.ReplyMessage()\n                                {\n                                    Id = \"unique-postback-id2\",\n                                    Title = \"Second Button \"\n                                }\n                            }\n                        }\n                    }\n                }\n            });\n            \nvar message = builder.Build();\nvar result = await client.SendMessageAsync(message);\n```\n\n## Using the OTP API\nSend a simple OTP code\n```cs\n    var client = new TextClient(new Guid(ConfigurationManager.AppSettings[\"ApiKey\"]));\n    var otpBuilder = new OtpRequestBuilder(\"Sender_name\", \"Recipient_PhoneNumber\");\n    otpBuilder.WithMessage(\"Your otp code is {code}.\");\n    var result = await textClient.SendOtpAsync(otpBuilder.Build());\n```\n\nVerify the response code\n```cs\n    var verifyResult = client.VerifyOtp(\"OTP-ID\", \"code\");\n    bool isValid = verifyResult.Verified;\n```\n\nFor more advanced scenarios see also https://developers.cm.com/identity/docs/one-time-password-create","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmdotcom%2Ftext-sdk-dotnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcmdotcom%2Ftext-sdk-dotnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcmdotcom%2Ftext-sdk-dotnet/lists"}