├── .gitattributes ├── MessageBird ├── Objects │ ├── VoiceMessageList.cs │ ├── GroupList.cs │ ├── ContactList.cs │ ├── Conversations │ │ ├── ConversationList.cs │ │ ├── ConversationWebhookList.cs │ │ ├── ConversationMessageList.cs │ │ ├── MessagesCount.cs │ │ ├── MediaContent.cs │ │ ├── LocationContent.cs │ │ ├── ConversationMessageFallBack.cs │ │ ├── WhatsAppStickerContent.cs │ │ ├── ConversationStartRequest.cs │ │ ├── ConversationMessageSendRequest.cs │ │ ├── Contact.cs │ │ ├── Channel.cs │ │ ├── ConversationWebhook.cs │ │ ├── Content.cs │ │ ├── Conversation.cs │ │ ├── HsmContent.cs │ │ └── ConversationMessage.cs │ ├── MessageList.cs │ ├── ContactGroupReference.cs │ ├── GroupContactReference.cs │ ├── ContactMessageReference.cs │ ├── ContactOptionalArguments.cs │ ├── Formats.cs │ ├── ContactCustomDetails.cs │ ├── Voice │ │ ├── VoiceResponse.cs │ │ ├── Webhook.cs │ │ ├── VoiceBaseList.cs │ │ ├── Recording.cs │ │ ├── Transcription.cs │ │ ├── Call.cs │ │ └── CallFlow.cs │ ├── Links.cs │ ├── IIdentifiable.cs │ ├── Error.cs │ ├── HlrDetails.cs │ ├── LookupHlr.cs │ ├── BaseList.cs │ ├── Recipients.cs │ ├── Balance.cs │ ├── Group.cs │ ├── Recipient.cs │ ├── Hlr.cs │ ├── Common │ │ └── Enums.cs │ └── Lookup.cs ├── Resources │ ├── Hlr.cs │ ├── Balance.cs │ ├── GroupLists.cs │ ├── Messages.cs │ ├── ContactLists.cs │ ├── VoiceMessages.cs │ ├── Voice │ │ ├── CallLists.cs │ │ ├── CallFlowLists.cs │ │ ├── WebhookLists.cs │ │ ├── VoiceBaseResource.cs │ │ ├── RecordingLists.cs │ │ ├── Calls.cs │ │ ├── TranscriptionsLists.cs │ │ ├── CallFlows.cs │ │ ├── VoiceBaseLists.cs │ │ ├── Webhooks.cs │ │ ├── Recordings.cs │ │ └── Transcriptions.cs │ ├── Conversations │ │ ├── ConversationLists.cs │ │ ├── WebhookLists.cs │ │ ├── Contacts.cs │ │ ├── Webhooks.cs │ │ ├── Conversations.cs │ │ ├── MessageLists.cs │ │ ├── Messages.cs │ │ ├── ConversationStart.cs │ │ └── MessageSend.cs │ ├── VoiceMessageList.cs │ ├── Contacts.cs │ ├── Groups.cs │ ├── Lookup.cs │ ├── LookupHlr.cs │ ├── BaseLists.cs │ ├── MessageList.cs │ ├── VerifyAPIObject.cs │ └── Resource.cs ├── Net │ ├── RestClientOptions.cs │ ├── ProxyConfigurationInjector │ │ ├── IProxyConfigurationInjector.cs │ │ ├── InjectDefaultCredentialsForProxiedUris.cs │ │ ├── InjectCredentialsForProxiedUris.cs │ │ └── InjectWebProxy.cs │ ├── IRestClient.cs │ └── HttpStatusCode.cs ├── Exceptions │ ├── RequestValidationException.cs │ └── ErrorException.cs ├── Utilities │ ├── ReflectionUtils.cs │ └── Validation.cs ├── MessageBird.csproj └── Json │ └── Converters │ ├── MessageConverter.cs │ ├── RFC3339DateTimeConverter.cs │ └── RecipientsConverter.cs ├── .nuget └── NuGet.Config ├── Tests └── MessageBird.Tests │ ├── Responses │ ├── WebhookView.json │ ├── WebhooksCreate.json │ ├── WebhooksView.json │ ├── WebhooksUpdate.json │ ├── ConversationMessage.json │ ├── CallView.json │ ├── CallUpdate.json │ ├── CallCreate.json │ ├── CallFlowUpdate.json │ ├── TranscriptionCreate.json │ ├── CallFlowView.json │ ├── RecordingView.json │ ├── WebhooksList.json │ ├── CallFlowList.json │ ├── WebhookList.json │ ├── TranscriptionView.json │ ├── RecordingList.json │ ├── ConversationMessagesList.json │ ├── CallList.json │ ├── ConversationView.json │ ├── ListMessages.json │ ├── TranscriptionList.json │ ├── ListVoiceMessages.json │ └── ConversationList.json │ ├── packages.config │ ├── MessageBird.Tests.csproj │ └── Resources │ └── RFC3339DateTimeConverterTest.cs ├── Examples ├── Examples.csproj ├── Call │ ├── DeleteCall.cs │ ├── ListCalls.cs │ ├── ViewCall.cs │ └── CreateCall.cs ├── Webhooks │ ├── DeleteWebhook.cs │ ├── ListWebhooks.cs │ ├── ViewWebhook.cs │ ├── CreateWebhook.cs │ └── UpdateWebhook.cs ├── CallFlow │ ├── DeleteCallFlow.cs │ ├── ListCallFlow.cs │ ├── ViewCallFlow.cs │ ├── UpdateCallFlow.cs │ └── CreateCallFlow.cs ├── Recording │ ├── DeleteRecording.cs │ ├── DownloadRecording.cs │ ├── ListRecording.cs │ └── ViewRecording.cs ├── VoiceMessage │ ├── ListVoiceMessages.cs │ ├── ViewVoiceMessage.cs │ └── CreateVoiceMessage.cs ├── Transcriptions │ ├── DownloadTranscription.cs │ ├── ListTranscriptions.cs │ ├── CreateTranscription.cs │ └── ViewTranscription.cs ├── Verify │ ├── CreateEmailVerify.cs │ ├── CreateVerify.cs │ └── CreateVoiceVerify.cs ├── Balance │ └── ViewBalance.cs ├── HLR │ ├── RequestHlr.cs │ └── ViewHlr.cs ├── Message │ ├── CreateMessage.cs │ └── ViewMessage.cs └── Lookup │ ├── ViewLookup.cs │ ├── ViewLookupHlr.cs │ └── RequestLookupHlr.cs ├── .github └── workflows │ ├── test.yml │ └── publish.yml ├── LICENSE ├── .travis.yml └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Set the default behavior, in case people edit files on OSX/*nix. 2 | * text eol=crlf 3 | -------------------------------------------------------------------------------- /MessageBird/Objects/VoiceMessageList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects 2 | { 3 | public class VoiceMessageList : BaseList { } 4 | } 5 | -------------------------------------------------------------------------------- /MessageBird/Objects/GroupList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects 2 | { 3 | public class GroupList : BaseList 4 | { 5 | // 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /MessageBird/Objects/ContactList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects 2 | { 3 | public class ContactList : BaseList 4 | { 5 | // 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects.Conversations 2 | { 3 | public class ConversationList : BaseList 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MessageBird/Objects/MessageList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects 2 | { 3 | public class MessageList : BaseList 4 | { 5 | public string Status { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationWebhookList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects.Conversations 2 | { 3 | public class ConversationWebhookList : BaseList 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Hlr.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Resources 2 | { 3 | sealed class Hlr : Resource 4 | { 5 | public Hlr(Objects.Hlr hlr) 6 | : base("hlr", hlr) 7 | { 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MessageBird/Resources/Balance.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Resources 2 | { 3 | class Balance : Resource 4 | { 5 | public Balance() 6 | : base("balance", new Objects.Balance()) 7 | { 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationMessageList.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects.Conversations 2 | { 3 | public class ConversationMessageList : BaseList 4 | 5 | { 6 | public string ConversationId { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /MessageBird/Net/RestClientOptions.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Net 2 | { 3 | /// 4 | /// Holds additional options for RestClient. 5 | /// 6 | public enum UpdateMode 7 | { 8 | Patch, 9 | 10 | Put, 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MessageBird/Resources/GroupLists.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Resources 2 | { 3 | public class GroupLists : BaseLists 4 | { 5 | public GroupLists() 6 | : base("groups", new Objects.GroupList()) 7 | { 8 | // 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MessageBird/Resources/Messages.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects; 2 | 3 | namespace MessageBird.Resources 4 | { 5 | public sealed class Messages : Resource 6 | { 7 | public Messages(Message message) 8 | : base("messages", message) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MessageBird/Resources/ContactLists.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Resources 2 | { 3 | public class ContactLists : BaseLists 4 | { 5 | public ContactLists() 6 | : base("contacts", new Objects.ContactList()) 7 | { 8 | // 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /MessageBird/Net/ProxyConfigurationInjector/IProxyConfigurationInjector.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace MessageBird.Net.ProxyConfigurationInjector 5 | { 6 | public interface IProxyConfigurationInjector 7 | { 8 | IWebProxy InjectProxyConfiguration(IWebProxy webProxy, Uri uri); 9 | } 10 | } -------------------------------------------------------------------------------- /MessageBird/Objects/ContactGroupReference.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class ContactGroupReference 6 | { 7 | [JsonProperty("href")] 8 | public string Href { get; set; } 9 | 10 | [JsonProperty("totalCount")] 11 | public int TotalCount { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageBird/Objects/GroupContactReference.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class GroupContactReference 6 | { 7 | [JsonProperty("href")] 8 | public string Href { get; set; } 9 | 10 | [JsonProperty("totalCount")] 11 | public int TotalCount { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageBird/Objects/ContactMessageReference.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class ContactMessageReference 6 | { 7 | [JsonProperty("href")] 8 | public string Href { get; set; } 9 | 10 | [JsonProperty("totalCount")] 11 | public int TotalCount { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/MessagesCount.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects.Conversations 4 | { 5 | public class MessagesCount 6 | { 7 | [JsonProperty("href")] 8 | public string Href {get;set;} 9 | 10 | [JsonProperty("totalCount")] 11 | public int TotalCount {get;set;} 12 | } 13 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/MediaContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects.Conversations 4 | { 5 | public class MediaContent 6 | { 7 | [JsonProperty("url")] 8 | public string Url { get; set; } 9 | 10 | [JsonProperty("caption")] 11 | public string Caption { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageBird/Resources/VoiceMessages.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects; 2 | 3 | namespace MessageBird.Resources 4 | { 5 | public sealed class VoiceMessages : Resource 6 | { 7 | public VoiceMessages(VoiceMessage voiceMessage) : 8 | base("voicemessages", voiceMessage) 9 | { 10 | Object = voiceMessage; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/LocationContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects.Conversations 4 | { 5 | public class LocationContent 6 | { 7 | [JsonProperty("latitude")] 8 | public float Latitude {get;set;} 9 | 10 | [JsonProperty("longitude")] 11 | public float Longitude {get;set;} 12 | } 13 | } -------------------------------------------------------------------------------- /MessageBird/Exceptions/RequestValidationException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBird.Exceptions 4 | { 5 | public class RequestValidationException : Exception 6 | { 7 | public RequestValidationException(string message) : base(message) { } 8 | public RequestValidationException(string message, Exception inner) : base(message, inner) { } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/WebhookView.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "985ae50937a94c64b392531ea87a0263", 3 | "url": "https://example.com/webhook", 4 | "channelId": "853eeb5348e541a595da93b48c61a1ae", 5 | "events": [ 6 | "message.created", 7 | "message.updated", 8 | ], 9 | "status": "enabled", 10 | "createdDatetime": "2018-08-29T10:04:23Z", 11 | "updatedDatetime": null 12 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationMessageFallBack.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects.Conversations 4 | { 5 | public class ConversationMessageFallBack 6 | { 7 | [JsonProperty("from")] 8 | public string From { get; set; } 9 | 10 | [JsonProperty("after")] 11 | public string After { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/CallLists.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects.Voice; 2 | 3 | namespace MessageBird.Resources.Voice 4 | { 5 | public class CallLists : VoiceBaseLists 6 | { 7 | public CallLists() 8 | : base("calls", new CallList()) 9 | { } 10 | 11 | public CallLists(Objects.Voice.CallList callList) : base("calls", callList) { } 12 | } 13 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/WhatsAppStickerContent.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace MessageBird.Objects.Conversations 8 | { 9 | public class WhatsAppStickerContent 10 | { 11 | [JsonProperty("link")] 12 | public string Link { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Examples/Examples.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /MessageBird/Net/ProxyConfigurationInjector/InjectDefaultCredentialsForProxiedUris.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | 3 | namespace MessageBird.Net.ProxyConfigurationInjector 4 | { 5 | public class InjectDefaultCredentialsForProxiedUris: InjectCredentialsForProxiedUris 6 | { 7 | public InjectDefaultCredentialsForProxiedUris(): base (CredentialCache.DefaultCredentials) 8 | { 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/WebhooksCreate.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "dff95aec-c11f-423c-82f3-1f391d78d716", 5 | "url": "https://testing.com", 6 | "token": "example token", 7 | "createdAt": "2020-01-09T10:10:11Z", 8 | "updatedAt": "2020-01-09T10:10:11Z" 9 | } 10 | ], 11 | "_links": { 12 | "self": "/webhooks/dff95aec-c11f-423c-82f3-1f391d78d716" 13 | } 14 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/WebhooksView.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "dff95aec-c11f-423c-82f3-1f391d78d716", 5 | "url": "https://testing.com", 6 | "token": "example token", 7 | "createdAt": "2020-01-09T10:10:11Z", 8 | "updatedAt": "2020-01-09T10:10:11Z" 9 | } 10 | ], 11 | "_links": { 12 | "self": "/webhooks/dff95aec-c11f-423c-82f3-1f391d78d716" 13 | } 14 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/CallFlowLists.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects.Voice; 2 | 3 | namespace MessageBird.Resources.Voice 4 | { 5 | public class CallFlowLists : VoiceBaseLists 6 | { 7 | public CallFlowLists() 8 | : base("call-flows", new CallFlowList()) 9 | { } 10 | 11 | public CallFlowLists(Objects.Voice.CallFlowList list) : base("call-flows", list) { } 12 | } 13 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/WebhooksUpdate.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "dff95aec-c11f-423c-82f3-1f391d78d716", 5 | "url": "https://example.com/update", 6 | "token": "new token", 7 | "createdAt": "2020-01-09T10:10:11Z", 8 | "updatedAt": "2020-01-09T10:34:48Z" 9 | } 10 | ], 11 | "_links": { 12 | "self": "/webhooks/dff95aec-c11f-423c-82f3-1f391d78d716" 13 | } 14 | } -------------------------------------------------------------------------------- /MessageBird/Objects/ContactOptionalArguments.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects 2 | { 3 | public class ContactOptionalArguments 4 | { 5 | public string FirstName { get; set; } 6 | public string LastName { get; set; } 7 | public string Custom1 { get; set; } 8 | public string Custom2 { get; set; } 9 | public string Custom3 { get; set; } 10 | public string Custom4 { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/WebhookLists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Objects.Voice; 3 | 4 | namespace MessageBird.Resources.Voice 5 | { 6 | public class WebhookLists : VoiceBaseLists 7 | { 8 | public WebhookLists() 9 | : base("webhooks", new WebhookList()) 10 | { } 11 | 12 | public WebhookLists(Objects.Voice.WebhookList webhookList) : base("webhooks", webhookList) { } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/ConversationMessage.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "13a97a5023944648b8e5e61248c40da8", 3 | "conversationId": "2e15efafec384e1c82e9842075e87beb", 4 | "channelId": "a621095fa44947a28b441cfdf85cb802", 5 | "status": "pending", 6 | "type": "text", 7 | "direction": "sent", 8 | "content": { 9 | "text": "Hello!" 10 | }, 11 | "createdDatetime": "2018-08-29T13:53:44.642664784Z", 12 | "updatedDatetime": "2018-08-29T13:53:44.673850825Z" 13 | } -------------------------------------------------------------------------------- /MessageBird/Utilities/ReflectionUtils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBird.Utilities 4 | { 5 | public class ReflectionUtils 6 | { 7 | public static bool IsNullable(Type t) 8 | { 9 | if (t == null) 10 | { 11 | throw new ArgumentNullException("t"); 12 | } 13 | 14 | return (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/ConversationLists.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Resources.Conversations 2 | { 3 | public class ConversationLists : BaseLists 4 | { 5 | public ConversationLists() 6 | : base("conversations", new Objects.Conversations.ConversationList()) 7 | { } 8 | public override string BaseUrl 9 | { 10 | get { return Conversations.ConverstationsBaseUrl; } 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/WebhookLists.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects.Conversations; 2 | 3 | namespace MessageBird.Resources.Conversations 4 | { 5 | public class WebhookLists : BaseLists 6 | { 7 | public WebhookLists() 8 | : base("webhooks", new ConversationWebhookList()) 9 | { } 10 | 11 | public override string BaseUrl 12 | { 13 | get { return ConverstationsBaseUrl; } 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/Contacts.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects; 2 | 3 | namespace MessageBird.Resources.Conversations 4 | { 5 | public class Contacts : Resource 6 | { 7 | public Contacts(Objects.Conversations.Contact contact) : base("contacts", contact) { } 8 | public Contacts() : this(new Objects.Conversations.Contact()) { } 9 | public override string BaseUrl 10 | { 11 | get { return Conversations.ConverstationsBaseUrl; } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallView.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58", 5 | "status": "ended", 6 | "source": "31644556677", 7 | "destination": "31612345678", 8 | "createdAt": "2017-02-16T10:52:00Z", 9 | "updatedAt": "2017-02-16T10:59:04Z", 10 | "endedAt": "2017-02-16T10:59:04Z" 11 | } 12 | ], 13 | "_links": { 14 | "self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58" 15 | } 16 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Formats.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class Formats 6 | { 7 | [JsonProperty("e164")] 8 | public string E164 { get; set; } 9 | 10 | [JsonProperty("international")] 11 | public string International { get; set; } 12 | 13 | [JsonProperty("national")] 14 | public string National { get; set; } 15 | 16 | [JsonProperty("rfc3966")] 17 | public string Rfc3966 { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MessageBird/Objects/ContactCustomDetails.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class ContactCustomDetails 6 | { 7 | [JsonProperty("custom1")] 8 | public string Custom1 { get; set; } 9 | 10 | [JsonProperty("custom2")] 11 | public string Custom2 { get; set; } 12 | 13 | [JsonProperty("custom3")] 14 | public string Custom3 { get; set; } 15 | 16 | [JsonProperty("custom4")] 17 | public string Custom4 { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/Webhooks.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Resources.Conversations 2 | { 3 | public class Webhooks : Resource 4 | { 5 | public Webhooks(Objects.Conversations.ConversationWebhook conversationWebhook) : base("webhooks", conversationWebhook) { } 6 | 7 | public Webhooks() : this(new Objects.Conversations.ConversationWebhook()) { } 8 | 9 | public override string BaseUrl 10 | { 11 | get { return Conversations.ConverstationsBaseUrl; } 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallUpdate.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "21025ed1-cc1d-4554-ac05-043fa6c84e00", 5 | "status": "ongoing", 6 | "source": "31644556677", 7 | "destination": "31612345678", 8 | "createdAt": "2017-08-30T07:35:37Z", 9 | "updatedAt": "2017-08-30T07:35:37Z", 10 | "endedAt": null 11 | } 12 | ], 13 | "_links": { 14 | "legs": "/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00/legs", 15 | "self": "/calls/21025ed1-cc1d-4554-ac05-043fa6c84e00" 16 | } 17 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/VoiceResponse.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageBird.Objects.Voice 5 | { 6 | 7 | public class VoiceResponse : IIdentifiable 8 | { 9 | [JsonProperty("data")] 10 | public List Data { get; set; } 11 | 12 | [JsonProperty("_links")] 13 | public Dictionary Links { get; set; } 14 | 15 | public string Id 16 | { 17 | get 18 | { 19 | return string.Empty; 20 | } 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Links.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | /// 6 | /// Links for paginating through a list response. 7 | /// 8 | public class Links 9 | { 10 | [JsonProperty("first")] 11 | public string First { get; set; } 12 | 13 | [JsonProperty("previous")] 14 | public string Previous { get; set; } 15 | 16 | [JsonProperty("next")] 17 | public string Next { get; set; } 18 | 19 | [JsonProperty("last")] 20 | public string Last { get; set; } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [ master, main ] 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | name: Build and test 12 | steps: 13 | - name: Checkout csharp-rest-api 14 | uses: actions/checkout@v3 15 | 16 | - name: Setup .NET Core SDK 17 | uses: actions/setup-dotnet@v2 18 | with: 19 | dotnet-version: 6.0.x 20 | 21 | - name: Build 22 | run: dotnet build MessageBird -f net6.0 23 | 24 | - name: Test 25 | run: dotnet test Tests/MessageBird.Tests -f net6.0 26 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallCreate.json: -------------------------------------------------------------------------------- 1 | { 2 | "data":[ 3 | { 4 | "id":"cac63a43-ff05-4cc3-b8e3-fca82e97975c", 5 | "source":"31644556677", 6 | "destination":"33766723144", 7 | "createdAt":"2019-12-06T15:56:39Z", 8 | "updatedAt":"2019-12-06T15:56:39Z", 9 | "endedAt":null 10 | } 11 | ], 12 | "_links": { 13 | "self":"/calls/cac63a43-ff05-4cc3-b8e3-fca82e97975c" 14 | }, 15 | "pagination":{ 16 | "totalCount":0, 17 | "pageCount":0, 18 | "currentPage":0, 19 | "perPage":0 20 | } 21 | } -------------------------------------------------------------------------------- /MessageBird/Objects/IIdentifiable.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Objects 2 | { 3 | /// 4 | /// Base for identifiable types with a specifcly typed `Id` field. 5 | /// Contravariant, see `IEnumerable` of `T` at http://msdn.microsoft.com/en-us/library/9eekhta0 6 | /// so you can pass more specified instance (like an `IIdentifiable` of `Balance`) to something 7 | /// that expects a more generic (like `IIdentifiable` of `T`) instance. 8 | /// 9 | /// Type for the `Id` field. 10 | public interface IIdentifiable 11 | { 12 | T Id { get; } 13 | } 14 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationStartRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace MessageBird.Objects.Conversations 5 | { 6 | public class ConversationStartRequest 7 | { 8 | [JsonProperty("to")] 9 | public string To { get; set; } 10 | 11 | [JsonProperty("type"), JsonConverter(typeof(StringEnumConverter))] 12 | public ContentType Type {get; set;} 13 | 14 | [JsonProperty("content")] 15 | public Content Content {get; set;} 16 | 17 | [JsonProperty("channelId")] 18 | public string ChannelId { get; set; } 19 | } 20 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallFlowUpdate.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635", 5 | "title": "Updated call flow", 6 | "record": false, 7 | "steps": [ 8 | { 9 | "id": "3538a6b8-5a2e-4537-8745-f72def6bd393", 10 | "action": "transfer", 11 | "options": { 12 | "destination": "31611223344" 13 | } 14 | } 15 | ], 16 | "createdAt": "2017-03-06T13:34:14Z", 17 | "updatedAt": "2017-03-06T15:02:38Z" 18 | } 19 | ], 20 | "_links": { 21 | "self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635" 22 | } 23 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/Conversations.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Net; 2 | 3 | namespace MessageBird.Resources.Conversations 4 | { 5 | public class Conversations : Resource 6 | { 7 | public Conversations(Objects.Conversations.Conversation conversation) : base("conversations", conversation) { } 8 | public Conversations() : this(new Objects.Conversations.Conversation()) { } 9 | public override string BaseUrl 10 | { 11 | get { return ConverstationsBaseUrl; } 12 | } 13 | 14 | public override UpdateMode UpdateMode 15 | { 16 | get { return UpdateMode.Patch; } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/TranscriptionCreate.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "2ce04c83-ca4f-4d94-8310-02968da41318", 5 | "recordingId": "cfa9ae96-e034-4db7-91cb-e58a8392c7bd", 6 | "status": "transcribing", 7 | "createdAt": "2020-01-08T15:33:59Z", 8 | "updatedAt": "2020-01-08T15:34:00.2625109Z", 9 | "_links": { 10 | "file": "/transcriptions/00000000-0000-0000-0000-000000000000.txt", 11 | "self": "/transcriptions/00000000-0000-0000-0000-000000000000" 12 | }, 13 | "CallId": null, 14 | "LegId": "00000000-0000-0000-0000-000000000000", 15 | "Language": null 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallFlowView.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635", 5 | "title": "Forward call to 31611223344", 6 | "record": false, 7 | "steps": [ 8 | { 9 | "id": "3538a6b8-5a2e-4537-8745-f72def6bd393", 10 | "action": "transfer", 11 | "options": { 12 | "destination": "31611223344" 13 | } 14 | } 15 | ], 16 | "createdAt": "2017-03-06T13:34:14Z", 17 | "updatedAt": "2017-03-06T15:02:38Z", 18 | } 19 | ], 20 | "_links": { 21 | "self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635" 22 | } 23 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/VoiceBaseResource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Net; 3 | using MessageBird.Objects; 4 | using Newtonsoft.Json; 5 | 6 | namespace MessageBird.Resources.Voice 7 | { 8 | public class VoiceBaseResource : Resource 9 | { 10 | public static string baseUrl = "https://voice.messagebird.com"; 11 | 12 | public VoiceBaseResource(string name, IIdentifiable attachedObject) : 13 | base(name, attachedObject) 14 | { 15 | // 16 | } 17 | 18 | public override string BaseUrl 19 | { 20 | get 21 | { 22 | return baseUrl; 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/RecordingView.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "3b4ac358-9467-4f7a-a6c8-6157ad181123", 5 | "format": "wav", 6 | "legId": "cc3bd14d-3eee-4380-b01f-fe7723c69a31", 7 | "status": "done", 8 | "duration": 7, 9 | "createdAt": "2017-05-17T11:42:57Z", 10 | "updatedAt": "2017-05-17T11:43:04Z" 11 | } 12 | ], 13 | "_links": { 14 | "self": "/calls/bb3f0391-4fdc-4e38-9551-e8a01602984f/legs/cc3bd14d-3eee-4380-b01f-fe7723c69a31/recordings/3b4ac358-9467-4f7a-a6c8-6157ad181123", 15 | "file": "/calls/bb3f0391-4fdc-4e38-9551-e8a01602984f/legs/cc3bd14d-3eee-4380-b01f-fe7723c69a31/recordings/3b4ac358-9467-4f7a-a6c8-6157ad181123.wav" 16 | } 17 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Error.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public enum ErrorCode 6 | { 7 | RequestNotAllowed = 2, 8 | MissingParameters = 9, 9 | InvalidParameters = 10, 10 | NotFound = 20, 11 | NotEnoughBalance = 25, 12 | ApiNotFound = 98, 13 | InternalError = 99 14 | } 15 | 16 | public class Error 17 | { 18 | [JsonProperty("code")] 19 | public ErrorCode Code { get; set; } 20 | 21 | [JsonProperty("description")] 22 | public string Description { get; set; } 23 | 24 | [JsonProperty("parameter")] 25 | public string Parameter { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/Webhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace MessageBird.Objects.Voice 5 | { 6 | 7 | public class Webhook : IIdentifiable 8 | { 9 | 10 | [JsonProperty("id")] 11 | public string Id { get; set; } 12 | 13 | [JsonProperty("url")] 14 | public string url { get; set; } 15 | 16 | [JsonProperty("token")] 17 | public string token { get; set; } 18 | 19 | [JsonProperty("createdAt")] 20 | public DateTime? createdAt { get; set; } 21 | 22 | [JsonProperty("updatedAt")] 23 | public DateTime? updatedAt { get; set; } 24 | } 25 | 26 | public class WebhookList : VoiceBaseList 27 | { 28 | } 29 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/WebhooksList.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "25fde85f-5e8f-42ef-9709-92241ae3789d", 5 | "url": "https://newurl.com", 6 | "token": "test title", 7 | "createdAt": "2020-01-08T09:51:44Z", 8 | "updatedAt": "2020-01-08T09:51:44Z" 9 | }, 10 | { 11 | "id": "85d17c71-714d-4261-85b7-df6c34e52455", 12 | "url": "https://test3.com", 13 | "token": "another title", 14 | "createdAt": "2020-01-07T13:41:41Z", 15 | "updatedAt": "2020-01-07T13:41:41Z" 16 | } 17 | ], 18 | "_links": { 19 | "self": "/webhooks?page=1" 20 | }, 21 | "pagination": { 22 | "totalCount": 2, 23 | "pageCount": 1, 24 | "currentPage": 1, 25 | "perPage": 10 26 | } 27 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/RecordingLists.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects.Voice; 2 | using System; 3 | 4 | namespace MessageBird.Resources.Voice 5 | { 6 | public class RecordingLists : VoiceBaseLists 7 | { 8 | public RecordingLists(string callId, string legId) 9 | : base("recordings", new RecordingList { CallId = callId, LegId = legId }) 10 | { } 11 | 12 | public RecordingLists(Objects.Voice.RecordingList list) : base("recordings", list) { } 13 | 14 | public override string Uri 15 | { 16 | get 17 | { 18 | return String.Format("calls/{0}/legs/{1}/{2}", ((RecordingList)Object).CallId, ((RecordingList)Object).LegId, Name); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Remco Vermeulen 2 | 3 | Permission to use, copy, modify, and/or distribute this software for any 4 | purpose with or without fee is hereby granted, provided that the above 5 | copyright notice and this permission notice appear in all copies. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationMessageSendRequest.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | 4 | namespace MessageBird.Objects.Conversations 5 | { 6 | public class ConversationMessageSendRequest 7 | { 8 | [JsonIgnore] 9 | public string ConversationId { get; set; } 10 | 11 | [JsonProperty("type"), JsonConverter(typeof(StringEnumConverter))] 12 | public ContentType Type {get;set;} 13 | 14 | [JsonProperty("content")] 15 | public Content Content {get;set;} 16 | 17 | [JsonProperty("channelId")] 18 | public string ChannelId {get;set;} 19 | 20 | [JsonProperty("fallback")] 21 | public ConversationMessageFallBack FallBack { get; set; } 22 | } 23 | } -------------------------------------------------------------------------------- /MessageBird/MessageBird.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | MessageBird 5 | MessageBird 6 | MessageBird 7 | Copyright © 2022 8 | 9 | enable 10 | enable 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | <_Parameter1>MessageBirdUnitTests 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallFlowList.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "de3ed163-d5fc-45f4-b8c4-7eea7458c635", 5 | "record": false, 6 | "steps": [ 7 | { 8 | "id": "3538a6b8-5a2e-4537-8745-f72def6bd393", 9 | "action": "transfer", 10 | "options": { 11 | "destination": "31612345678" 12 | } 13 | } 14 | ], 15 | "createdAt": "2017-03-06T13:34:14Z", 16 | "updatedAt": "2017-03-06T13:34:14Z", 17 | "_links": { 18 | "self": "/call-flows/de3ed163-d5fc-45f4-b8c4-7eea7458c635" 19 | } 20 | } 21 | ], 22 | "_links": { 23 | "self": "/call-flows?page=1" 24 | }, 25 | "pagination": { 26 | "totalCount": 1, 27 | "pageCount": 1, 28 | "currentPage": 1, 29 | "perPage": 10 30 | } 31 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/MessageLists.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBird.Resources.Conversations 4 | { 5 | public class MessageLists : BaseLists 6 | { 7 | public MessageLists() 8 | : base("messages", new Objects.Conversations.ConversationMessageList()) 9 | { } 10 | 11 | public override string Uri 12 | { 13 | get 14 | { 15 | return String.Format("conversations/{0}/{1}", 16 | ((Objects.Conversations.ConversationMessageList) Object).ConversationId, 17 | Name); 18 | } 19 | } 20 | 21 | public override string BaseUrl 22 | { 23 | get { return Conversations.ConverstationsBaseUrl; } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/Calls.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Objects.Voice; 4 | using Newtonsoft.Json; 5 | 6 | 7 | namespace MessageBird.Resources.Voice 8 | { 9 | public class Calls : VoiceBaseResource 10 | { 11 | public Calls(Objects.Voice.Call call) : base("calls", call) { } 12 | public Calls() : this(new Objects.Voice.Call()) { } 13 | 14 | public override void Deserialize(string resource) 15 | { 16 | try 17 | { 18 | Object = JsonConvert.DeserializeObject>(resource); 19 | } 20 | catch (JsonSerializationException e) 21 | { 22 | throw new ErrorException("Received response in an unexpected format!", e); 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: csharp-rest-client.sln 3 | mono: none 4 | dotnet: 2.1.300 5 | script: 6 | - cd Tests/UnitTests/MessageBirdUnitTests 7 | - dotnet restore 8 | - dotnet test 9 | env: 10 | global: 11 | secure: dW4i1leTDXh38v7756n1XCC/l9FokZDmOlwjSdYD89BcgGsJzHh/g/K/9IISUhNw9ZXqs2GRGsHGUd4BnZ/dkju+9eyR9VvYBB6h9UfFxKk3+lLbIiWnIUpKzlqrmErpyoEr7tGtqk1JR4+rgRy/CP7giS9uCV2SlX+kntGz60bkrX2308n5PMidCjg9o6DeLnmpDO8+joAUBi2+v3/648+6pk9OIiFJqrYjj90fH+YlF+3vPYugS6arbSiRQ5lfn8lHWqfIuCzikHcjA3/MVeVqrXuYINtWz0xF03/n107Wrl00FtrRnXcp2ssixXZ1u6is9zJFvRewoKjxTSN3VjQIev9h+HTSBoua5KQdcbZ6Of2+f8SiC6lXvAz436OxOqyO7z11urHLBk/ZL+1iX5Qkh+9Aq+ZhdHsbufnZMzfgzx3MLRhrsgK0aJk+gnAOSqci7a/bZlkuGUlru4cN0jR/aP2+tIAM+beRwo0e0eTEHxy4wnKDs00sJnY0nOpq/K7zRqRuq/3DXkGq9+/8TzyiCp9mJ+z4lXzZfJWybmcaTnXKJqzcN1GmVV1UaGfEz0SZWRiJ28XTLyZkxpXRUN+n+zYJNGlonzFub92y0Q0v4td2NVuzIi2WNcC1G1MJJUr3DZ16/0D5QU6589O6JoVjhD31Diw7oK0ig+YedgY= 12 | -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/VoiceBaseList.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects.Voice 4 | { 5 | 6 | public class Pagination 7 | { 8 | [JsonProperty("totalCount")] 9 | public int TotalCount { get; set; } 10 | 11 | [JsonProperty("pageCount")] 12 | public int PageCount { get; set; } 13 | 14 | [JsonProperty("currentPage")] 15 | public int CurrentPage { get; set; } 16 | 17 | [JsonProperty("perPage")] 18 | public int PerPage { get; set; } 19 | }; 20 | 21 | public class VoiceBaseList : VoiceResponse 22 | { 23 | [JsonProperty("pagination")] 24 | public Pagination Pagination { get; set; } 25 | 26 | [JsonProperty("limit")] 27 | public int Limit { get; set; } 28 | 29 | [JsonProperty("page")] 30 | public int Page { get; set; } 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /MessageBird/Objects/HlrDetails.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class HlrDetails 6 | { 7 | [JsonProperty("status_desc")] 8 | public string StatusDesc { get; set; } 9 | 10 | [JsonProperty("imsi")] 11 | public string Imsi { get; set; } 12 | 13 | [JsonProperty("country_iso")] 14 | public string CountryIso { get; set; } 15 | 16 | [JsonProperty("country_name")] 17 | public string CountryName { get; set; } 18 | 19 | [JsonProperty("location_msc")] 20 | public string LocationMsc { get; set; } 21 | 22 | [JsonProperty("location_iso")] 23 | public string LocationIso { get; set; } 24 | 25 | [JsonProperty("ported")] 26 | public int Ported { get; set; } 27 | 28 | [JsonProperty("roaming")] 29 | public int Roaming { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/TranscriptionsLists.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects.Voice; 2 | using System; 3 | 4 | namespace MessageBird.Resources.Voice 5 | { 6 | public class TranscriptionsLists : VoiceBaseLists 7 | { 8 | public TranscriptionsLists(string callId, string legId, string recordingId) 9 | : base("transcriptions", new TranscriptionList { CallId = callId, LegId = legId, RecordingId = recordingId }) 10 | { } 11 | 12 | public TranscriptionsLists(Objects.Voice.TranscriptionList list) : base("transcriptions", list) { } 13 | 14 | public override string Uri 15 | { 16 | get 17 | { 18 | return String.Format("calls/{0}/legs/{1}/recordings/{2}/{3}", ((TranscriptionList)Object).CallId, ((TranscriptionList)Object).LegId, ((TranscriptionList)Object).RecordingId, Name); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /MessageBird/Resources/VoiceMessageList.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace MessageBird.Resources 4 | { 5 | public class VoiceMessageLists : BaseLists 6 | { 7 | public VoiceMessageLists() : base("voicemessages", new Objects.VoiceMessageList()) { } 8 | 9 | public VoiceMessageLists(Objects.VoiceMessageList voiceMessageList) : base("voicemessages", voiceMessageList) { } 10 | 11 | public override string QueryString 12 | { 13 | get 14 | { 15 | var baseList = (Objects.VoiceMessageList)Object; 16 | 17 | var builder = new StringBuilder(); 18 | 19 | if (!string.IsNullOrEmpty(base.QueryString)) 20 | { 21 | builder.AppendFormat("{0}", base.QueryString); 22 | } 23 | 24 | return builder.ToString(); 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Contacts.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Net; 2 | using Newtonsoft.Json; 3 | 4 | namespace MessageBird.Resources 5 | { 6 | public class Contacts : Resource 7 | { 8 | public Contacts(Objects.Contact contact) 9 | : base("contacts", contact) 10 | { 11 | } 12 | 13 | public Contacts() 14 | : this(new Objects.Contact()) 15 | { 16 | 17 | } 18 | 19 | public override string Serialize() 20 | { 21 | var requestObject = ((Objects.Contact)Object).ToRequestObject(); 22 | 23 | var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; 24 | return JsonConvert.SerializeObject(requestObject, settings); 25 | } 26 | 27 | public override UpdateMode UpdateMode 28 | { 29 | get { return UpdateMode.Patch; } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /MessageBird/Resources/Groups.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Net; 2 | using Newtonsoft.Json; 3 | 4 | namespace MessageBird.Resources 5 | { 6 | class Groups : Resource 7 | { 8 | public Groups(Objects.Group group) 9 | : base("groups", group) 10 | { 11 | // 12 | } 13 | 14 | public Groups() 15 | : this(new Objects.Group()) 16 | { 17 | // 18 | } 19 | 20 | public override string Serialize() 21 | { 22 | var requestObject = ((Objects.Group)Object).ToRequestObject(); 23 | 24 | var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; 25 | return JsonConvert.SerializeObject(requestObject, settings); 26 | } 27 | 28 | public override UpdateMode UpdateMode 29 | { 30 | get { return UpdateMode.Patch; } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/WebhookList.json: -------------------------------------------------------------------------------- 1 | { 2 | "offset": 0, 3 | "limit": 100, 4 | "count": 2, 5 | "totalCount": 10, 6 | "items": [ 7 | { 8 | "id": "985ae50937a94c64b392531ea87a0263", 9 | "url": "https://example.com/webhook", 10 | "channelId": "853eeb5348e541a595da93b48c61a1ae", 11 | "events": [ 12 | "message.created", 13 | "message.updated", 14 | ], 15 | "status": "enabled", 16 | "createdDatetime": "2018-08-29T10:04:23Z", 17 | "updatedDatetime": null 18 | }, 19 | { 20 | "id": "885ae50937a94c64b392531ea87a0263", 21 | "url": "https://example.com/webhook", 22 | "channelId": "853eeb5348e541a595da93b48c61a1ae", 23 | "events": [ 24 | "message.created", 25 | "message.updated", 26 | ], 27 | "status": "enabled", 28 | "createdDatetime": "2018-08-29T10:04:23Z", 29 | "updatedDatetime": null 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish dotnet package to nuget 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | publish: 9 | runs-on: ubuntu-latest 10 | permissions: 11 | packages: write 12 | contents: read 13 | steps: 14 | - name: Checkout csharp-rest-api 15 | uses: actions/checkout@v3 16 | 17 | - name: Setup .NET Core SDK 18 | uses: actions/setup-dotnet@v2 19 | with: 20 | dotnet-version: 6.0.x 21 | 22 | - name: Build release 23 | run: dotnet build --configuration Release MessageBird -f net6.0 24 | 25 | - name: Create the package 26 | run: dotnet pack --configuration Release /p:Version=${{github.event.release.tag_name}} MessageBird 27 | 28 | - name: Publish the package to GPR 29 | run: dotnet nuget push MessageBird/bin/Release/*.nupkg --api-key ${{secrets.NUGET_AUTH_TOKEN}} --source https://api.nuget.org/v3/index.json 30 | -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/CallFlows.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Exceptions; 2 | using MessageBird.Net; 3 | using MessageBird.Objects.Voice; 4 | using Newtonsoft.Json; 5 | 6 | namespace MessageBird.Resources.Voice 7 | { 8 | public class CallFlows : VoiceBaseResource 9 | { 10 | public CallFlows(CallFlow callFlow) : base("call-flows", callFlow) { } 11 | public CallFlows() : this(new CallFlow()) { } 12 | 13 | public override UpdateMode UpdateMode 14 | { 15 | get { return UpdateMode.Put; } 16 | } 17 | 18 | public override void Deserialize(string resource) 19 | { 20 | try 21 | { 22 | Object = JsonConvert.DeserializeObject>(resource); 23 | } 24 | catch (JsonSerializationException e) 25 | { 26 | throw new ErrorException("Received response in an unexpected format!", e); 27 | } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/TranscriptionView.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "2ce04c83-ca4f-4d94-8310-02968da41318", 5 | "recordingId": "cfa9ae96-e034-4db7-91cb-e58a8392c7bd", 6 | "status": "done", 7 | "createdAt": "2020-01-08T14:37:46Z", 8 | "updatedAt": "2020-01-08T14:37:53Z", 9 | "legId": "8dd347a4-11ee-44f2-bee3-7fbda300b2cd", 10 | "_links": { 11 | "file": "/transcriptions/2ce04c83-ca4f-4d94-8310-02968da41318.txt", 12 | "self": "/transcriptions/2ce04c83-ca4f-4d94-8310-02968da41318" 13 | } 14 | } 15 | ], 16 | "_links": { 17 | "file": "/calls/373395cc-382b-4a33-b372-cc31f0fdf242/legs/8dd347a4-11ee-44f2-bee3-7fbda300b2cd/recordings/cfa9ae96-e034-4db7-91cb-e58a8392c7bd/transcriptions/2ce04c83-ca4f-4d94-8310-02968da41318.txt", 18 | "self": "/calls/373395cc-382b-4a33-b372-cc31f0fdf242/legs/8dd347a4-11ee-44f2-bee3-7fbda300b2cd/recordings/cfa9ae96-e034-4db7-91cb-e58a8392c7bd/transcriptions/2ce04c83-ca4f-4d94-8310-02968da41318" 19 | } 20 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/Messages.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBird.Resources.Conversations 4 | { 5 | public class Messages : Resource 6 | { 7 | public Messages(Objects.Conversations.ConversationMessage conversationMessage) : base("messages", conversationMessage) { } 8 | public Messages() : this(new Objects.Conversations.ConversationMessage()) { } 9 | 10 | private string BaseName 11 | { 12 | get 13 | { 14 | return String.Format("conversations/{0}/{1}", 15 | ((Objects.Conversations.ConversationMessageList) Object).ConversationId, 16 | Name); 17 | } 18 | } 19 | 20 | public override string Uri 21 | { 22 | get { return HasId ? string.Format("{0}/{1}", Name, Id) : BaseName; } 23 | } 24 | 25 | public override string BaseUrl 26 | { 27 | get { return ConverstationsBaseUrl; } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /MessageBird/Net/ProxyConfigurationInjector/InjectCredentialsForProxiedUris.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace MessageBird.Net.ProxyConfigurationInjector 5 | { 6 | public class InjectCredentialsForProxiedUris : IProxyConfigurationInjector 7 | { 8 | private readonly ICredentials credentials; 9 | 10 | public InjectCredentialsForProxiedUris(ICredentials credentials) 11 | { 12 | this.credentials = credentials; 13 | } 14 | 15 | public IWebProxy InjectProxyConfiguration(IWebProxy webProxy, Uri uri) 16 | { 17 | Uri proxy = WebRequest.DefaultWebProxy.GetProxy(uri); 18 | if (uri != proxy) // request goes through proxy 19 | { 20 | // webProxy.UseDefaultCredentials = true; // not accessible through IWebProxy 21 | webProxy.Credentials = credentials; // same as setting `webProxy.UseDefaultCredentials = true` 22 | } 23 | return webProxy; 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Lookup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBird.Resources 4 | { 5 | class Lookup : Resource 6 | { 7 | public Lookup(Objects.Lookup lookup) 8 | : base("lookup", lookup) 9 | { 10 | } 11 | 12 | protected bool HasCountryCode 13 | { 14 | get 15 | { 16 | return (Object != null) && !String.IsNullOrEmpty(((Objects.Lookup)Object).CountryCode); 17 | } 18 | } 19 | 20 | public override string Uri 21 | { 22 | get 23 | { 24 | return String.Format("{0}/{1}", Name, ((Objects.Lookup)Object).PhoneNumber); 25 | } 26 | } 27 | 28 | public override string QueryString 29 | { 30 | get 31 | { 32 | return HasCountryCode ? "countryCode=" + System.Uri.EscapeDataString(((Objects.Lookup)Object).CountryCode) : String.Empty; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MessageBird/Net/ProxyConfigurationInjector/InjectWebProxy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | 4 | namespace MessageBird.Net.ProxyConfigurationInjector 5 | { 6 | /// 7 | /// Completely overwrites the web proxy so you can hard configure it. Example: 8 | /// 9 | /// ICredentials credentials = new NetworkCredential("xxxx", "xxxx"); 10 | /// IWebProxy webProxy = new WebProxy (new Uri("http://xx.xx.xx.xxx:xxxx")); 11 | /// webProxy.Credentials = credentials; 12 | /// new InjectWebProxy(webProxy); 13 | /// 14 | /// 15 | public class InjectWebProxy: IProxyConfigurationInjector 16 | { 17 | private readonly IWebProxy webProxyToInject; 18 | 19 | public InjectWebProxy(IWebProxy webProxyToInject) 20 | { 21 | this.webProxyToInject = webProxyToInject; 22 | } 23 | 24 | public IWebProxy InjectProxyConfiguration(IWebProxy webProxy, Uri uri) 25 | { 26 | return webProxyToInject; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /MessageBird/Resources/LookupHlr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MessageBird.Resources 4 | { 5 | class LookupHlr : Resource 6 | { 7 | public LookupHlr(Objects.LookupHlr lookupHlr) 8 | : base("lookup", lookupHlr) 9 | { 10 | } 11 | 12 | protected bool HasCountryCode 13 | { 14 | get 15 | { 16 | return (Object != null) && !String.IsNullOrEmpty(((Objects.LookupHlr)Object).CountryCode); 17 | } 18 | } 19 | 20 | public override string Uri 21 | { 22 | get 23 | { 24 | return String.Format("{0}/{1}/hlr", Name, ((Objects.LookupHlr)Object).Msisdn); 25 | } 26 | } 27 | 28 | public override string QueryString 29 | { 30 | get 31 | { 32 | return HasCountryCode ? "countryCode=" + System.Uri.EscapeDataString(((Objects.LookupHlr)Object).CountryCode) : String.Empty; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/RecordingList.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "4c2ac358-b467-4f7a-a6c8-6157ad181142", 5 | "format": "wav", 6 | "type": "ivr", 7 | "legId": "317bd14d-3eee-4380-b01f-fe7723c6913a", 8 | "status": "done", 9 | "duration": 42, 10 | "createdAt": "2017-05-17T11:42:57Z", 11 | "updatedAt": "2017-05-17T11:43:04Z", 12 | "_links": { 13 | "self": "/calls/fdcf0391-4fdc-4e38-9551-e8a01602984f/legs/317bd14d-3eee-4380-b01f-fe7723c6913a/recordings/4c2ac358-b467-4f7a-a6c8-6157ad181142", 14 | "file": "/calls/fdcf0391-4fdc-4e38-9551-e8a01602984f/legs/317bd14d-3eee-4380-b01f-fe7723c6913a/recordings/4c2ac358-b467-4f7a-a6c8-6157ad181142.wav" 15 | } 16 | } 17 | ], 18 | "_links": { 19 | "self": "/calls/fdcf0391-4fdc-4e38-9551-e8a01602984f/legs/317bd14d-3eee-4380-b01f-fe7723c6913a/recordings/4c2ac358-b467-4f7a-a6c8-6157ad181142?page=1" 20 | }, 21 | "pagination": { 22 | "totalCount": 1, 23 | "pageCount": 1, 24 | "currentPage": 1, 25 | "perPage": 10 26 | } 27 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/Contact.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace MessageBird.Objects.Conversations 6 | { 7 | public class Contact : IIdentifiable 8 | { 9 | [JsonProperty("id")] 10 | public string Id {get; set;} 11 | 12 | [JsonProperty("href")] 13 | public string Href {get; set;} 14 | 15 | [JsonProperty("msisdn")] 16 | public string Msisdn {get; set;} 17 | 18 | [JsonProperty("firstName")] 19 | public string FirstName {get; set;} 20 | 21 | [JsonProperty("lastName")] 22 | public string LastName {get; set;} 23 | 24 | [JsonProperty("customDetails")] 25 | public Dictionary CustomDetails {get; set;} 26 | 27 | [JsonProperty("createdDatetime")] 28 | public DateTime? CreatedDatetime {get; set;} 29 | 30 | [JsonProperty("updatedDatetime")] 31 | public DateTime? UpdatedDatetime {get; set;} 32 | } 33 | } -------------------------------------------------------------------------------- /MessageBird/Resources/BaseLists.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects; 2 | using System.Text; 3 | 4 | namespace MessageBird.Resources 5 | { 6 | public abstract class BaseLists : Resource 7 | { 8 | public BaseLists(string name, BaseList attachedObject) 9 | : base(name, attachedObject) 10 | { 11 | // 12 | } 13 | 14 | public override string QueryString 15 | { 16 | get 17 | { 18 | var baseList = (BaseList)Object; 19 | 20 | var builder = new StringBuilder(); 21 | 22 | if (!string.IsNullOrEmpty(base.QueryString)) 23 | { 24 | builder.AppendFormat("{0}&", base.QueryString); 25 | } 26 | 27 | builder.AppendFormat("limit={0}", baseList.Limit); 28 | builder.AppendFormat("&"); 29 | builder.AppendFormat("offset={0}", baseList.Offset); 30 | 31 | return builder.ToString(); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/ConversationStart.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Objects.Conversations; 3 | using Newtonsoft.Json; 4 | 5 | namespace MessageBird.Resources.Conversations 6 | { 7 | public class ConversationStart : Resource 8 | { 9 | public ConversationStartRequest Request { get; protected set; } 10 | 11 | public ConversationStart(ConversationStartRequest request) 12 | : base("conversations", new Conversation()) 13 | { 14 | Request = request; 15 | } 16 | 17 | public override string Uri 18 | { 19 | get { return string.Format("{0}/start", Name); } 20 | } 21 | 22 | public override string Serialize() 23 | { 24 | var settings = new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}; 25 | return JsonConvert.SerializeObject(Request, settings); 26 | } 27 | public override string BaseUrl 28 | { 29 | get { return Conversations.ConverstationsBaseUrl; } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/VoiceBaseLists.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using MessageBird.Objects.Voice; 3 | 4 | namespace MessageBird.Resources.Voice 5 | { 6 | public class VoiceBaseLists : VoiceBaseResource 7 | { 8 | public VoiceBaseLists(string name, VoiceBaseList attachedObject) 9 | : base(name, attachedObject) 10 | { 11 | } 12 | 13 | public override string QueryString 14 | { 15 | get 16 | { 17 | var baseList = (VoiceBaseList)Object; 18 | 19 | var builder = new StringBuilder(); 20 | 21 | if (!string.IsNullOrEmpty(base.QueryString)) 22 | { 23 | builder.AppendFormat("{0}&", base.QueryString); 24 | } 25 | 26 | builder.AppendFormat("limit={0}", baseList.Limit); 27 | builder.AppendFormat("&"); 28 | builder.AppendFormat("page={0}", baseList.Page); 29 | 30 | return builder.ToString(); 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /MessageBird/Resources/MessageList.cs: -------------------------------------------------------------------------------- 1 | 2 | using System.Text; 3 | 4 | namespace MessageBird.Resources 5 | { 6 | public class MessageLists : BaseLists 7 | { 8 | public MessageLists() 9 | : base("messages", new Objects.MessageList()) 10 | { 11 | } 12 | 13 | public MessageLists(Objects.MessageList messageList) : base("messages", messageList) { } 14 | 15 | public override string QueryString 16 | { 17 | get 18 | { 19 | var baseList = (Objects.MessageList)Object; 20 | 21 | var builder = new StringBuilder(); 22 | 23 | if (!string.IsNullOrEmpty(base.QueryString)) 24 | { 25 | builder.AppendFormat("{0}", base.QueryString); 26 | } 27 | 28 | if (baseList.Status != "") { 29 | builder.AppendFormat("&status={0}", baseList.Status); 30 | } 31 | 32 | return builder.ToString(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MessageBird/Resources/Conversations/MessageSend.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Objects.Conversations; 3 | using Newtonsoft.Json; 4 | 5 | namespace MessageBird.Resources.Conversations 6 | { 7 | public class MessageSend : Resource 8 | { 9 | public ConversationMessageSendRequest Request { get; protected set; } 10 | 11 | public MessageSend(ConversationMessageSendRequest request) 12 | : base("messages", new ConversationMessage()) 13 | { 14 | Request = request; 15 | } 16 | 17 | public override string Serialize() 18 | { 19 | var settings = new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}; 20 | return JsonConvert.SerializeObject(Request, settings); 21 | } 22 | 23 | public override string Uri 24 | { 25 | get { return String.Format("conversations/{0}/{1}", Request.ConversationId, Name); } 26 | } 27 | 28 | public override string BaseUrl 29 | { 30 | get { return Conversations.ConverstationsBaseUrl; } 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/ConversationMessagesList.json: -------------------------------------------------------------------------------- 1 | { 2 | "count": 2, 3 | "items": [ 4 | { 5 | "id": "eb34fb1fc73f47a58ad644de0e2de254", 6 | "conversationId": "2e15efafec384e1c82e9842075e87beb", 7 | "channelId": "619747f69cf940a98fb443140ce9aed2", 8 | "status": "received", 9 | "direction": "received", 10 | "type": "text", 11 | "content": { 12 | "text": "This is a test WhatsApp message" 13 | }, 14 | "createdDatetime": "2018-08-29T08:07:15Z", 15 | "updatedDatetime": "2018-08-29T08:07:33Z" 16 | }, 17 | { 18 | "id": "5f3437fdb8444583aea093a047ac014b", 19 | "conversationId": "2e15efafec384e1c82e9842075e87beb", 20 | "channelId": "853eeb5348e541a595da93b48c61a1ae", 21 | "status": "delivered", 22 | "direction": "sent", 23 | "type": "text", 24 | "content": { 25 | "text": "This is a test SMS message" 26 | }, 27 | "createdDatetime": "2018-08-28T15:52:41Z", 28 | "updatedDatetime": "2018-08-28T15:52:58Z" 29 | } 30 | ], 31 | "limit": 20, 32 | "offset": 0, 33 | "totalCount": 24 34 | } -------------------------------------------------------------------------------- /MessageBird/Objects/LookupHlr.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | 3 | namespace MessageBird.Objects 4 | { 5 | public class LookupHlrOptionalArguments 6 | { 7 | public string CountryCode { get; set; } 8 | } 9 | 10 | public class LookupHlr : Hlr 11 | { 12 | [JsonProperty("countryCode")] 13 | public string CountryCode { get; private set; } 14 | 15 | public LookupHlr() 16 | { 17 | } 18 | 19 | public LookupHlr(long phonenumber, LookupHlrOptionalArguments optionalArguments = null) 20 | { 21 | Msisdn = phonenumber; 22 | 23 | optionalArguments = optionalArguments ?? new LookupHlrOptionalArguments(); 24 | 25 | CountryCode = optionalArguments.CountryCode; 26 | } 27 | 28 | public LookupHlr(long phonenumber, string reference, LookupHlrOptionalArguments optionalArguments = null) 29 | : base(phonenumber, reference) 30 | { 31 | optionalArguments = optionalArguments ?? new LookupHlrOptionalArguments(); 32 | 33 | CountryCode = optionalArguments.CountryCode; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/CallList.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58", 5 | "status": "ended", 6 | "source": "31644556677", 7 | "destination": "31612345678", 8 | "createdAt": "2017-02-16T10:52:00Z", 9 | "updatedAt": "2017-02-16T10:59:04Z", 10 | "endedAt": "2017-02-16T10:59:04Z", 11 | "_links": { 12 | "self": "/calls/f1aa71c0-8f2a-4fe8-b5ef-9a330454ef58" 13 | } 14 | }, 15 | { 16 | "id": "ac07a602-dbc1-11e6-bf26-cec0c932ce01", 17 | "status": "ended", 18 | "source": "31644556677", 19 | "destination": "31612345678", 20 | "createdAt": "2017-01-16T07:51:56Z", 21 | "updatedAt": "2017-01-16T07:55:56Z", 22 | "endedAt": "2017-01-16T07:55:56Z", 23 | "_links": { 24 | "self": "/calls/ac07a602-dbc1-11e6-bf26-cec0c932ce01" 25 | } 26 | } 27 | ], 28 | "_links": { 29 | "self": "/calls?page=1" 30 | }, 31 | "pagination": { 32 | "totalCount": 2, 33 | "pageCount": 1, 34 | "currentPage": 1, 35 | "perPage": 10 36 | } 37 | } -------------------------------------------------------------------------------- /MessageBird/Json/Converters/MessageConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using Newtonsoft.Json; 5 | 6 | using MessageBird.Objects; 7 | 8 | namespace MessageBird.Json.Converters 9 | { 10 | class MessageConverter : JsonConverter 11 | { 12 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 13 | { 14 | var message = value as Message; 15 | var toSerialize = new Dictionary(); 16 | 17 | if (message == null) { 18 | toSerialize.Add("href", null); 19 | } else { 20 | toSerialize.Add("href", message.Href); 21 | } 22 | serializer.Serialize(writer, toSerialize); 23 | } 24 | 25 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 26 | { 27 | return serializer.Deserialize(reader); 28 | } 29 | 30 | public override bool CanConvert(Type objectType) 31 | { 32 | return typeof(Message).IsAssignableFrom(objectType); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /MessageBird/Objects/BaseList.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System.Collections.Generic; 3 | 4 | namespace MessageBird.Objects 5 | { 6 | /// 7 | /// A standard list as returned by most APIs/endpoints. 8 | /// 9 | /// Type of this list's objects. 10 | public abstract class BaseList : IIdentifiable 11 | { 12 | [JsonProperty("limit")] 13 | public int Limit { get; set; } 14 | 15 | [JsonProperty("offset")] 16 | public int Offset { get; set; } 17 | 18 | [JsonProperty("count")] 19 | public int Count { get; set; } 20 | 21 | [JsonProperty("totalCount")] 22 | public int TotalCount { get; set; } 23 | 24 | [JsonProperty("links")] 25 | public Links Links { get; set; } 26 | 27 | [JsonProperty("items")] 28 | public IList Items { get; set; } 29 | 30 | public virtual string Id 31 | { 32 | get 33 | { 34 | // We're only defining this as we need to implement 35 | // IIdentifiable. Should not be invoked typically. Concrete 36 | // lists are free to override this behavior. 37 | return string.Empty; 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/Recording.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace MessageBird.Objects.Voice 6 | { 7 | public class Recording : IIdentifiable 8 | { 9 | [JsonProperty("id")] 10 | public string Id { get; set; } 11 | 12 | [JsonProperty("format")] 13 | public string Format { get; set; } 14 | 15 | [JsonProperty("type")] 16 | public string Type { get; set; } 17 | 18 | [JsonProperty("legId")] 19 | public string LegId { get; set; } 20 | 21 | [JsonProperty("status")] 22 | public string Status { get; set; } 23 | 24 | [JsonProperty("duration")] 25 | public int? Duration { get; set; } 26 | 27 | [JsonProperty("createdAt")] 28 | public DateTime? CreatedAt { get; set; } 29 | 30 | [JsonProperty("updatedAt")] 31 | public DateTime? UpdatedAt { get; set; } 32 | 33 | [JsonProperty("_links")] 34 | public Dictionary Links { get; set; } 35 | 36 | public string CallId { get; set; } 37 | } 38 | 39 | public class RecordingList : VoiceBaseList 40 | { 41 | public string LegId { get; set; } 42 | 43 | public string CallId { get; set; } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /MessageBird/Net/IRestClient.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using MessageBird.Net.ProxyConfigurationInjector; 3 | using MessageBird.Resources; 4 | 5 | namespace MessageBird.Net 6 | { 7 | // immutable, so no read/write properties 8 | public interface IRestClient 9 | { 10 | string AccessKey { get; } 11 | string Endpoint { get; } 12 | IProxyConfigurationInjector ProxyConfigurationInjector { get; } 13 | 14 | string ApiVersion { get; } 15 | string ClientVersion { get; } 16 | string UserAgent { get; } 17 | 18 | T Create (T resource) where T : Resource; 19 | T Retrieve(T resource) where T : Resource; 20 | T Update(T resource) where T : Resource; 21 | void Delete(Resource resource); 22 | 23 | string PerformHttpRequest(string method, string uri, string body, HttpStatusCode expectedStatusCode); 24 | string PerformHttpRequest(string method, string uri, HttpStatusCode expectedStatusCode); 25 | string PerformHttpRequest(string method, string uri, string body, HttpStatusCode expectedStatusCode, string baseUrl); 26 | string PerformHttpRequest(string method, string uri, HttpStatusCode expectedStatusCode, string baseUrl); 27 | Stream PerformHttpRequest(string uri, HttpStatusCode expectedStatusCode, string baseUrl); 28 | } 29 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/Webhooks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Objects.Voice; 4 | using Newtonsoft.Json; 5 | 6 | namespace MessageBird.Resources.Voice 7 | { 8 | public class Webhooks : VoiceBaseResource 9 | { 10 | public Webhooks(Objects.Voice.Webhook webhook) : base("webhooks", webhook) { } 11 | public Webhooks() : this(new Objects.Voice.Webhook()) { } 12 | 13 | public override void Deserialize(string resource) 14 | { 15 | try 16 | { 17 | Object = JsonConvert.DeserializeObject>(resource); 18 | } 19 | catch (JsonSerializationException e) 20 | { 21 | throw new ErrorException("Received response in an unexpected format!", e); 22 | } 23 | } 24 | 25 | /// 26 | /// Override the serialize function to remove the ID from the body of an update message (PUT) 27 | /// 28 | public override string Serialize() 29 | { 30 | var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; 31 | return JsonConvert.SerializeObject(new { ((Webhook)Object).url, ((Webhook)Object).token }, settings); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/Transcription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace MessageBird.Objects.Voice 6 | { 7 | public class Transcription : IIdentifiable 8 | { 9 | [JsonProperty("id")] 10 | public string Id { get; set; } 11 | 12 | [JsonProperty("recordingId")] 13 | public string RecordingId { get; set; } 14 | 15 | [JsonProperty("status")] 16 | public string Status { get; set; } 17 | 18 | [JsonProperty("createdAt")] 19 | public DateTime? CreatedAt { get; set; } 20 | 21 | [JsonProperty("updatedAt")] 22 | public DateTime? UpdatedAt { get; set; } 23 | 24 | [JsonProperty("_links")] 25 | public Dictionary Links { get; set; } 26 | 27 | public string CallId { get; set; } 28 | 29 | public string LegId { get; set; } 30 | 31 | public string Language { get; set; } 32 | 33 | public override string ToString() 34 | { 35 | return JsonConvert.SerializeObject(this, Formatting.Indented); 36 | } 37 | } 38 | 39 | public class TranscriptionList : VoiceBaseList 40 | { 41 | public string CallId { get; set; } 42 | 43 | public string LegId { get; set; } 44 | 45 | public string RecordingId { get; set; } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/Channel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Converters; 5 | 6 | namespace MessageBird.Objects.Conversations 7 | { 8 | public enum ChannelStatus 9 | { 10 | [EnumMember(Value = "activating")] 11 | Activating, 12 | [EnumMember(Value = "activation_code_required")] 13 | ActivationCodeRequired, 14 | [EnumMember(Value = "activation_required")] 15 | ActivationRequired, 16 | [EnumMember(Value = "active")] 17 | Active, 18 | [EnumMember(Value = "deleted")] 19 | Deleted, 20 | [EnumMember(Value = "inactive")] 21 | Inactive, 22 | [EnumMember(Value = "pending")] 23 | Pending, 24 | } 25 | public class Channel : IIdentifiable 26 | { 27 | [JsonProperty("id")] 28 | public string Id {get; set;} 29 | 30 | [JsonProperty("name")] 31 | public string Name {get; set;} 32 | 33 | [JsonProperty("status"), JsonConverter(typeof(StringEnumConverter))] 34 | public ChannelStatus Status {get; set;} 35 | 36 | [JsonProperty("createdDatetime")] 37 | public DateTime? CreatedDatetime {get; set;} 38 | 39 | [JsonProperty("updatedDatetime")] 40 | public DateTime? UpdatedDatetime {get; set;} 41 | } 42 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/Recordings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Objects.Voice; 4 | using Newtonsoft.Json; 5 | 6 | namespace MessageBird.Resources.Voice 7 | { 8 | public class Recordings : VoiceBaseResource 9 | { 10 | public Recordings(Recording recording) 11 | : base("calls", recording) 12 | { 13 | } 14 | 15 | public override string Uri 16 | { 17 | get 18 | { 19 | return String.Format("{0}/{1}/legs/{2}/recordings/{3}", Name, ((Recording)Object).CallId, ((Recording)Object).LegId, Object.Id); 20 | } 21 | } 22 | 23 | public string DownloadUri 24 | { 25 | get 26 | { 27 | return String.Format("{0}/{1}/legs/{2}/recordings/{3}.wav", Name, ((Recording)Object).CallId, ((Recording)Object).LegId, Object.Id); 28 | } 29 | } 30 | 31 | public override void Deserialize(string resource) 32 | { 33 | try 34 | { 35 | Object = JsonConvert.DeserializeObject>(resource); 36 | } 37 | catch (JsonSerializationException e) 38 | { 39 | throw new ErrorException("Received response in an unexpected format!", e); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/MessageBird.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | false 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Examples/Call/DeleteCall.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.Call 6 | { 7 | internal class DeleteCall 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | try 16 | { 17 | client.DeleteCall("CALL ID"); 18 | Console.WriteLine("The Call was deleted successfully."); 19 | } 20 | catch (ErrorException e) 21 | { 22 | // Either the request fails with error descriptions from the endpoint. 23 | if (e.HasErrors) 24 | { 25 | foreach (var error in e.Errors) 26 | { 27 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 28 | } 29 | } 30 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 31 | if (e.HasReason) 32 | { 33 | Console.WriteLine(e.Reason); 34 | } 35 | } 36 | Console.WriteLine("Press any key to continue..."); 37 | Console.ReadKey(); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationWebhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | using Newtonsoft.Json.Serialization; 7 | 8 | namespace MessageBird.Objects.Conversations 9 | { 10 | public enum ConversationWebhookEvent 11 | { 12 | [EnumMember(Value = "conversation.created")] 13 | ConversationCreated, 14 | [EnumMember(Value = "conversation.updated")] 15 | ConversationUpdated, 16 | [EnumMember(Value = "message.created")] 17 | MessageCreated, 18 | [EnumMember(Value = "message.updated")] 19 | MessageUpdated, 20 | } 21 | 22 | public class ConversationWebhook : IIdentifiable 23 | { 24 | [JsonProperty("id")] 25 | public string Id {get;set;} 26 | 27 | [JsonProperty("channelId")] 28 | public string ChannelId {get;set;} 29 | 30 | [JsonProperty("url")] 31 | public string Url {get;set;} 32 | 33 | [JsonProperty("events", ItemConverterType = typeof(StringEnumConverter))] 34 | public List Events {get;set;} 35 | 36 | [JsonProperty("createdDatetime")] 37 | public DateTime? CreatedDatetime {get;set;} 38 | 39 | [JsonProperty("updatedDatetime")] 40 | public DateTime? UpdatedDatetime {get;set;} 41 | } 42 | } -------------------------------------------------------------------------------- /Examples/Webhooks/DeleteWebhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | 5 | namespace Examples.Webhooks 6 | { 7 | internal class DeleteWebhook 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | try 16 | { 17 | client.DeleteWebhook("WEBHOOK ID"); 18 | Console.WriteLine("The Webhook was deleted successfully."); 19 | } 20 | catch (ErrorException e) 21 | { 22 | // Either the request fails with error descriptions from the endpoint. 23 | if (e.HasErrors) 24 | { 25 | foreach (var error in e.Errors) 26 | { 27 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 28 | } 29 | } 30 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 31 | if (e.HasReason) 32 | { 33 | Console.WriteLine(e.Reason); 34 | } 35 | } 36 | Console.WriteLine("Press any key to continue..."); 37 | Console.ReadKey(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Examples/CallFlow/DeleteCallFlow.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.CallFlow 6 | { 7 | internal class DeleteCallFlow 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | try 16 | { 17 | client.DeleteCallFlow("PUT YOUR REQUEST ID HERE"); 18 | Console.WriteLine("The Voice Call Flow deleted successfully."); 19 | } 20 | catch (ErrorException e) 21 | { 22 | // Either the request fails with error descriptions from the endpoint. 23 | if (e.HasErrors) 24 | { 25 | foreach (var error in e.Errors) 26 | { 27 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 28 | } 29 | } 30 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 31 | if (e.HasReason) 32 | { 33 | Console.WriteLine(e.Reason); 34 | } 35 | } 36 | Console.WriteLine("Press any key to continue..."); 37 | Console.ReadKey(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/Content.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Newtonsoft.Json; 3 | 4 | namespace MessageBird.Objects.Conversations 5 | { 6 | public enum ContentType 7 | { 8 | [EnumMember(Value = "audio")] Audio, 9 | [EnumMember(Value = "file")] File, 10 | [EnumMember(Value = "hsm")] Hsm, 11 | [EnumMember(Value = "image")] Image, 12 | [EnumMember(Value = "location")] Location, 13 | [EnumMember(Value = "text")] Text, 14 | [EnumMember(Value = "video")] Video, 15 | [EnumMember(Value = "event")] Event, 16 | [EnumMember(Value = "whatsappSticker")] WhatsAppSticker, 17 | } 18 | 19 | public class Content 20 | { 21 | [JsonProperty("audio")] 22 | public MediaContent Audio {get;set;} 23 | 24 | [JsonProperty("file")] 25 | public MediaContent File {get;set;} 26 | 27 | [JsonProperty("hsm")] 28 | public HsmContent Hsm {get;set;} 29 | 30 | [JsonProperty("image")] 31 | public MediaContent Image {get;set;} 32 | 33 | [JsonProperty("location")] 34 | public LocationContent Location {get;set;} 35 | 36 | [JsonProperty("text")] 37 | public string Text {get;set;} 38 | 39 | [JsonProperty("video")] 40 | public MediaContent Video {get;set;} 41 | 42 | [JsonProperty("whatsappSticker")] 43 | public WhatsAppStickerContent WhatsAppSticker { get; set; } 44 | } 45 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Recipients.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Newtonsoft.Json; 3 | 4 | namespace MessageBird.Objects 5 | { 6 | public class Recipients 7 | { 8 | [JsonIgnore] 9 | public bool SerializeMsisdnsOnly { get; set; } 10 | 11 | [JsonProperty("totalCount")] 12 | public int TotalCount { get; private set; } 13 | 14 | [JsonProperty("totalSentCount")] 15 | public int TotalSentCount { get; private set; } 16 | 17 | [JsonProperty("totalDeliveredCount")] 18 | public int TotalDeliveredCount { get; private set; } 19 | 20 | [JsonProperty("totalDeliveryFailedCount")] 21 | public int TotalDeliveryFailedCount { get; private set; } 22 | 23 | [JsonProperty("items")] 24 | public List Items { get; set; } 25 | 26 | public Recipients() 27 | { 28 | Items = new List(); 29 | SerializeMsisdnsOnly = true; 30 | } 31 | 32 | public Recipients(IEnumerable msisdns) : this() 33 | { 34 | foreach (long msisdn in msisdns) 35 | { 36 | AddRecipient(msisdn); 37 | } 38 | } 39 | 40 | public void AddRecipient(long msisdn) 41 | { 42 | Items.Add(new Recipient(msisdn)); 43 | } 44 | 45 | public override string ToString() 46 | { 47 | return JsonConvert.SerializeObject(this, Formatting.Indented); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Examples/Recording/DeleteRecording.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.Recording 6 | { 7 | internal class DeleteRecording 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | try 16 | { 17 | client.DeleteRecording("CALL ID", "LEG ID", "RECORDING ID"); 18 | Console.WriteLine("The Recording was deleted successfully."); 19 | } 20 | catch (ErrorException e) 21 | { 22 | // Either the request fails with error descriptions from the endpoint. 23 | if (e.HasErrors) 24 | { 25 | foreach (var error in e.Errors) 26 | { 27 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 28 | } 29 | } 30 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 31 | if (e.HasReason) 32 | { 33 | Console.WriteLine(e.Reason); 34 | } 35 | } 36 | Console.WriteLine("Press any key to continue..."); 37 | Console.ReadKey(); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /MessageBird/Objects/Balance.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Converters; 5 | 6 | namespace MessageBird.Objects 7 | { 8 | public enum PaymentMethod 9 | { 10 | [EnumMember(Value = "prepaid")] 11 | Prepaid, 12 | [EnumMember(Value = "postpaid")] 13 | Postpaid 14 | } 15 | 16 | public class Balance : IIdentifiable 17 | { 18 | /// 19 | /// To uniformly treat objects, we implement the IIdentifiable interface even though 20 | /// a Balance object doesn't have an id! 21 | /// By returning null, the Balance object signals the user of a balance object 22 | /// (currently always the balance resource) to ignore the id property. 23 | /// 24 | /// Throwing an exception will interfer with serialization of a balance object. 25 | public string Id 26 | { 27 | get 28 | { 29 | return null; 30 | } 31 | } 32 | 33 | [JsonProperty("payment"), JsonConverter(typeof(StringEnumConverter))] 34 | public PaymentMethod Payment { get; set; } 35 | 36 | [JsonProperty("type")] 37 | public string Type { get; set; } 38 | 39 | [JsonProperty("amount")] 40 | public string Amount { get; set; } 41 | 42 | public override string ToString() 43 | { 44 | return JsonConvert.SerializeObject(this, Formatting.Indented); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Examples/CallFlow/ListCallFlow.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.CallFlow 6 | { 7 | internal class ListCallFlow 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | var callFlowList = client.ListCallFlows(); 16 | try 17 | { 18 | foreach (var item in callFlowList.Data) 19 | { 20 | Console.WriteLine("The Voice Call Flow Id is: {0}", item.Id); 21 | } 22 | } 23 | catch (ErrorException e) 24 | { 25 | // Either the request fails with error descriptions from the endpoint. 26 | if (e.HasErrors) 27 | { 28 | foreach (var error in e.Errors) 29 | { 30 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 31 | } 32 | } 33 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 34 | if (e.HasReason) 35 | { 36 | Console.WriteLine(e.Reason); 37 | } 38 | } 39 | Console.WriteLine("Press any key to continue..."); 40 | Console.ReadKey(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/ConversationView.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "2e15efafec384e1c82e9842075e87beb", 3 | "contactId": "a621095fa44947a28b441cfdf85cb802", 4 | "contact": { 5 | "id": "a621095fa44947a28b441cfdf85cb802", 6 | "href": "https://rest.messagebird.com/1/contacts/a621095fa44947a28b441cfdf85cb802", 7 | "msisdn": 31612345678, 8 | "firstName": "Jen", 9 | "lastName": "Smith", 10 | "customDetails": { 11 | "custom1": null, 12 | "custom2": null, 13 | "custom3": null, 14 | "custom4": null 15 | }, 16 | "createdDatetime": "2018-06-03T20:06:03Z", 17 | "updatedDatetime": null 18 | }, 19 | "channels": [ 20 | { 21 | "id": "853eeb5348e541a595da93b48c61a1ae", 22 | "name": "SMS", 23 | "platformId": "sms", 24 | "status": "active", 25 | "createdDatetime": "2018-08-28T11:56:57Z", 26 | "updatedDatetime": "2018-08-29T08:16:33Z" 27 | }, 28 | { 29 | "id": "619747f69cf940a98fb443140ce9aed2", 30 | "name": "My WhatsApp", 31 | "platformId": "whatsapp", 32 | "status": "active", 33 | "createdDatetime": "2018-08-28T11:56:57Z", 34 | "updatedDatetime": "2018-08-29T08:16:33Z" 35 | } 36 | ], 37 | "status": "archived", 38 | "createdDatetime": "2018-08-13T09:17:22Z", 39 | "updatedDatetime": "2018-08-29T07:35:48Z", 40 | "lastReceivedDatetime": "2018-08-29T07:35:48Z", 41 | "lastUsedChannelId": "619747f69cf940a98fb443140ce9aed2", 42 | "messages": { 43 | "totalCount": 24, 44 | "href": "https://conversations.messagebird.com/v1/conversations/2e15efafec384e1c82e9842075e87beb/messages" 45 | } 46 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/Conversation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | 7 | namespace MessageBird.Objects.Conversations 8 | { 9 | public enum ConversationStatus 10 | { 11 | [EnumMember(Value = "active")] 12 | Active, 13 | [EnumMember(Value = "archived")] 14 | Archived, 15 | } 16 | public class Conversation : IIdentifiable 17 | { 18 | [JsonProperty("id")] 19 | public string Id {get;set;} 20 | 21 | [JsonProperty("contactId")] 22 | public string ContactId {get;set;} 23 | 24 | [JsonProperty("contact")] 25 | public Contact Contact {get;set;} 26 | 27 | [JsonProperty("channels")] 28 | public List Channels {get;set;} 29 | 30 | [JsonProperty("messages")] 31 | public MessagesCount Messages {get;set;} 32 | 33 | [JsonProperty("status"), JsonConverter(typeof(StringEnumConverter))] 34 | public ConversationStatus Status {get;set;} 35 | 36 | [JsonProperty("createdDatetime")] 37 | public DateTime? CreatedDatetime {get;set;} 38 | 39 | [JsonProperty("updatedDatetime")] 40 | public DateTime? UpdatedDatetime {get;set;} 41 | 42 | [JsonProperty("lastReceivedDatetime")] 43 | public DateTime? LastReceivedDatetime {get;set;} 44 | 45 | [JsonProperty("lastUsedChannelId")] 46 | public string LastUsedChannelId {get;set;} 47 | } 48 | } -------------------------------------------------------------------------------- /Examples/CallFlow/ViewCallFlow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | 6 | namespace Examples.CallFlow 7 | { 8 | internal class ViewCallFlow 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | var callFlowResponse = client.ViewCallFlow("PUT YOUR REQUEST ID HERE"); 19 | var callFlow = callFlowResponse.Data.FirstOrDefault(); 20 | 21 | Console.WriteLine("The Voice Call Flow Id is: {0}", callFlow.Id); 22 | } 23 | catch (ErrorException e) 24 | { 25 | // Either the request fails with error descriptions from the endpoint. 26 | if (e.HasErrors) 27 | { 28 | foreach (var error in e.Errors) 29 | { 30 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 31 | } 32 | } 33 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 34 | if (e.HasReason) 35 | { 36 | Console.WriteLine(e.Reason); 37 | } 38 | } 39 | Console.WriteLine("Press any key to continue..."); 40 | Console.ReadKey(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/ListMessages.json: -------------------------------------------------------------------------------- 1 | { 2 | "offset": 0, 3 | "limit": 20, 4 | "count": 1, 5 | "totalCount": 1, 6 | "links": { 7 | "first": "https://rest.messagebird.com/messages/?offset=0", 8 | "previous": null, 9 | "next": null, 10 | "last": "https://rest.messagebird.com/messages/?offset=0" 11 | }, 12 | "items": [ 13 | { 14 | "id": "436d780b854749b4beca51623d9e2674", 15 | "href": "https://rest.messagebird.com/messages/436d780b854749b4beca51623d9e2674", 16 | "direction": "mt", 17 | "type": "sms", 18 | "originator": "YourName", 19 | "body": "This is a test message", 20 | "reference": null, 21 | "validity": null, 22 | "gateway": 10, 23 | "typeDetails": {}, 24 | "datacoding": "plain", 25 | "mclass": 1, 26 | "scheduledDatetime": null, 27 | "createdDatetime": "2020-02-04T19:01:12+00:00", 28 | "recipients": { 29 | "totalCount": 1, 30 | "totalSentCount": 1, 31 | "totalDeliveredCount": 0, 32 | "totalDeliveryFailedCount": 1, 33 | "items": [ 34 | { 35 | "recipient": 31612345678, 36 | "originator": null, 37 | "status": "delivery_failed", 38 | "statusDatetime": "2020-02-04T19:01:12+00:00", 39 | "messagePartCount": 1 40 | } 41 | ] 42 | } 43 | } 44 | ] 45 | } -------------------------------------------------------------------------------- /Examples/Call/ListCalls.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.Call 6 | { 7 | internal class ListCalls 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | var calls = client.ListCalls(); 16 | try 17 | { 18 | foreach (var item in calls.Data) 19 | { 20 | Console.WriteLine("The Call Id is: {0}", item.Id); 21 | Console.WriteLine("The Call source is: {0}", item.Source); 22 | Console.WriteLine("The Call destination is: {0}", item.Destination); 23 | Console.WriteLine("The Call ended at: {0}", item.EndedAt); 24 | } 25 | } 26 | catch (ErrorException e) 27 | { 28 | // Either the request fails with error descriptions from the endpoint. 29 | if (e.HasErrors) 30 | { 31 | foreach (var error in e.Errors) 32 | { 33 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 34 | } 35 | } 36 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 37 | if (e.HasReason) 38 | { 39 | Console.WriteLine(e.Reason); 40 | } 41 | } 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /Examples/Recording/DownloadRecording.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | using System.IO; 5 | 6 | namespace Examples.Recording 7 | { 8 | internal class DownloadRecording 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | using (var recordingDataStream = client.DownloadRecording("CALL ID", "LEG ID", "RECORDING ID")) 19 | { 20 | using (var fileStream = File.OpenWrite(@"PATH TO FILE ON YOUR LOCAL MACHINE")) 21 | { 22 | recordingDataStream.CopyTo(fileStream); 23 | } 24 | } 25 | } 26 | catch (ErrorException e) 27 | { 28 | // Either the request fails with error descriptions from the endpoint. 29 | if (e.HasErrors) 30 | { 31 | foreach (var error in e.Errors) 32 | { 33 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 34 | } 35 | } 36 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 37 | if (e.HasReason) 38 | { 39 | Console.WriteLine(e.Reason); 40 | } 41 | } 42 | Console.WriteLine("Press any key to continue..."); 43 | Console.ReadKey(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Examples/Call/ViewCall.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | 6 | namespace Examples.Call 7 | { 8 | internal class ViewCall 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | var callResponse = client.ViewCall("CALL ID"); 19 | var call = callResponse.Data.FirstOrDefault(); 20 | 21 | Console.WriteLine("The Call Id is: {0}", call.Id); 22 | Console.WriteLine("The Call source is: {0}", call.Source); 23 | Console.WriteLine("The Call destination is: {0}", call.Destination); 24 | Console.WriteLine("The Call ended at: {0}", call.EndedAt); 25 | } 26 | catch (ErrorException e) 27 | { 28 | // Either the request fails with error descriptions from the endpoint. 29 | if (e.HasErrors) 30 | { 31 | foreach (var error in e.Errors) 32 | { 33 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 34 | } 35 | } 36 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 37 | if (e.HasReason) 38 | { 39 | Console.WriteLine(e.Reason); 40 | } 41 | } 42 | Console.WriteLine("Press any key to continue..."); 43 | Console.ReadKey(); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /Examples/Recording/ListRecording.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.Recording 6 | { 7 | internal class ListRecording 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | var recordings = client.ListRecordings(callId: "CALL ID", legId: "LEG ID"); 16 | try 17 | { 18 | foreach (var item in recordings.Data) 19 | { 20 | Console.WriteLine("The Recording Id is: {0}", item.Id); 21 | Console.WriteLine("The Recording Format is: {0}", item.Format); 22 | Console.WriteLine("The Recording Duration is: {0}", item.Duration); 23 | } 24 | } 25 | catch (ErrorException e) 26 | { 27 | // Either the request fails with error descriptions from the endpoint. 28 | if (e.HasErrors) 29 | { 30 | foreach (var error in e.Errors) 31 | { 32 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 33 | } 34 | } 35 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 36 | if (e.HasReason) 37 | { 38 | Console.WriteLine(e.Reason); 39 | } 40 | } 41 | Console.WriteLine("Press any key to continue..."); 42 | Console.ReadKey(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Examples/VoiceMessage/ListVoiceMessages.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.VoiceMessage 8 | { 9 | class ListVoiceMessages 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | 13 | static void Main(string[] args) 14 | { 15 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 16 | 17 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 18 | 19 | try 20 | { 21 | MessageBird.Objects.VoiceMessageList voiceMessageList = client.ListVoiceMessages(); 22 | Console.WriteLine("{0}", voiceMessageList); 23 | } 24 | catch (ErrorException e) 25 | { 26 | // Either the request fails with error descriptions from the endpoint. 27 | if (e.HasErrors) 28 | { 29 | foreach (Error error in e.Errors) 30 | { 31 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 32 | } 33 | } 34 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 35 | if (e.HasReason) 36 | { 37 | Console.WriteLine(e.Reason); 38 | } 39 | } 40 | Console.WriteLine("Press any key to continue..."); 41 | Console.ReadKey(); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Examples/Transcriptions/DownloadTranscription.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | using System.IO; 5 | 6 | namespace Examples.Transcription 7 | { 8 | internal class DownloadTranscription 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | using (var transcriptionDataStream = client.DownloadTranscription("CALL ID", "LEG ID", "RECORDING ID", "TRANSCRIPTION ID")) 19 | { 20 | using (var fileStream = File.OpenWrite(@"PATH TO FILE ON YOUR LOCAL MACHINE")) 21 | { 22 | transcriptionDataStream.CopyTo(fileStream); 23 | } 24 | } 25 | } 26 | catch (ErrorException e) 27 | { 28 | // Either the request fails with error descriptions from the endpoint. 29 | if (e.HasErrors) 30 | { 31 | foreach (var error in e.Errors) 32 | { 33 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 34 | } 35 | } 36 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 37 | if (e.HasReason) 38 | { 39 | Console.WriteLine(e.Reason); 40 | } 41 | } 42 | Console.WriteLine("Press any key to continue..."); 43 | Console.ReadKey(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Examples/Recording/ViewRecording.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | 6 | namespace Examples.Recording 7 | { 8 | internal class ViewRecording 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | var recordingResponse = client.ViewRecording("CALL ID", "LEG ID", "RECORDING ID"); 19 | var recording = recordingResponse.Data.FirstOrDefault(); 20 | 21 | Console.WriteLine("The Recording Id is: {0}", recording.Id); 22 | Console.WriteLine("The Recording Format is: {0}", recording.Format); 23 | Console.WriteLine("The Recording Duration is: {0}", recording.Duration); 24 | } 25 | catch (ErrorException e) 26 | { 27 | // Either the request fails with error descriptions from the endpoint. 28 | if (e.HasErrors) 29 | { 30 | foreach (var error in e.Errors) 31 | { 32 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 33 | } 34 | } 35 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 36 | if (e.HasReason) 37 | { 38 | Console.WriteLine(e.Reason); 39 | } 40 | } 41 | Console.WriteLine("Press any key to continue..."); 42 | Console.ReadKey(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Examples/Webhooks/ListWebhooks.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using System.Linq; 5 | using MessageBird.Objects.Voice; 6 | 7 | namespace Examples.Webhooks 8 | { 9 | internal class ListWebhooks 10 | { 11 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 12 | 13 | internal static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 16 | 17 | try 18 | { 19 | var webhookResponse = client.ListWebhooks(); 20 | 21 | foreach (var item in webhookResponse.Data) 22 | { 23 | Console.WriteLine("The Webhook Id is: {0}", item.Id); 24 | Console.WriteLine("The Webhook URL is: {0}", item.url); 25 | Console.WriteLine("The Webhook Token is: {0}", item.token); 26 | } 27 | } 28 | catch (ErrorException e) 29 | { 30 | // Either the request fails with error descriptions from the endpoint. 31 | if (e.HasErrors) 32 | { 33 | foreach (var error in e.Errors) 34 | { 35 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 36 | } 37 | } 38 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 39 | if (e.HasReason) 40 | { 41 | Console.WriteLine(e.Reason); 42 | } 43 | } 44 | Console.WriteLine("Press any key to continue..."); 45 | Console.ReadKey(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Examples/Webhooks/ViewWebhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using System.Linq; 5 | using MessageBird.Objects.Voice; 6 | 7 | namespace Examples.Webhooks 8 | { 9 | internal class ViewWebhook 10 | { 11 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 12 | 13 | internal static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 16 | 17 | try 18 | { 19 | string webhookId = "WEBHOOK ID"; 20 | var webhookResponse = client.ViewWebhook(webhookId); 21 | 22 | var webhook = webhookResponse.Data.FirstOrDefault(); 23 | Console.WriteLine("The Webhook Id is: {0}", webhook.Id); 24 | Console.WriteLine("The Webhook URL is: {0}", webhook.url); 25 | Console.WriteLine("The Webhook Token is: {0}", webhook.token); 26 | } 27 | catch (ErrorException e) 28 | { 29 | // Either the request fails with error descriptions from the endpoint. 30 | if (e.HasErrors) 31 | { 32 | foreach (var error in e.Errors) 33 | { 34 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 35 | } 36 | } 37 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 38 | if (e.HasReason) 39 | { 40 | Console.WriteLine(e.Reason); 41 | } 42 | } 43 | Console.WriteLine("Press any key to continue..."); 44 | Console.ReadKey(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/Call.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Runtime.Serialization; 6 | 7 | namespace MessageBird.Objects.Voice 8 | { 9 | 10 | public enum CallStatus 11 | { 12 | [EnumMember(Value = "queued")] 13 | Queued, 14 | [EnumMember(Value = "starting")] 15 | Starting, 16 | [EnumMember(Value = "ongoing")] 17 | Ongoing, 18 | [EnumMember(Value = "ended")] 19 | Ended 20 | }; 21 | 22 | public class Call : IIdentifiable 23 | { 24 | 25 | [JsonProperty("id")] 26 | public string Id { get; set; } 27 | 28 | [JsonProperty("status")] 29 | [JsonConverter(typeof(StringEnumConverter))] 30 | public CallStatus? Status { get; set; } 31 | 32 | [JsonProperty("source")] 33 | public string Source { get; set; } 34 | 35 | [JsonProperty("destination")] 36 | public string Destination { get; set; } 37 | 38 | [JsonProperty("webhook")] 39 | public Webhook Webhook { get; set; } 40 | 41 | [JsonProperty("callFlow")] 42 | public CallFlow CallFlow { get; set; } 43 | 44 | [JsonProperty("duration")] 45 | public int Duration { get; set; } 46 | 47 | [JsonProperty("createdAt")] 48 | public DateTime? CreatedAt { get; set; } 49 | 50 | [JsonProperty("updatedAt")] 51 | public DateTime? UpdatedAt { get; set; } 52 | 53 | [JsonProperty("endedAt")] 54 | public DateTime? EndedAt { get; set; } 55 | 56 | [JsonProperty("_links")] 57 | public Dictionary Links { get; set; } 58 | } 59 | 60 | public class CallList : VoiceBaseList 61 | { 62 | } 63 | } -------------------------------------------------------------------------------- /MessageBird/Resources/Voice/Transcriptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Objects.Voice; 4 | using Newtonsoft.Json; 5 | 6 | namespace MessageBird.Resources.Voice 7 | { 8 | public class Transcriptions : VoiceBaseResource 9 | { 10 | public Transcriptions(Transcription transcription) 11 | : base("calls", transcription) 12 | { 13 | } 14 | 15 | public override string Uri 16 | { 17 | get 18 | { 19 | return String.Format("{0}/{1}/legs/{2}/recordings/{3}/transcriptions/{4}", Name, ((Transcription)Object).CallId, ((Transcription)Object).LegId, ((Transcription)Object).RecordingId, Object.Id); 20 | } 21 | } 22 | 23 | public string DownloadUri 24 | { 25 | get 26 | { 27 | return String.Format("{0}/{1}/legs/{2}/recordings/{3}/transcriptions/{4}.txt", Name, ((Transcription)Object).CallId, ((Transcription)Object).LegId, ((Transcription)Object).RecordingId, Object.Id); 28 | } 29 | } 30 | 31 | public override string Serialize() 32 | { 33 | var settings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; 34 | return JsonConvert.SerializeObject(new { ((Transcription)Object).Language }, settings); 35 | } 36 | 37 | public override void Deserialize(string resource) 38 | { 39 | try 40 | { 41 | Object = JsonConvert.DeserializeObject>(resource); 42 | } 43 | catch (JsonSerializationException e) 44 | { 45 | throw new ErrorException("Received response in an unexpected format!", e); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Examples/Transcriptions/ListTranscriptions.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using System; 4 | 5 | namespace Examples.Transcription 6 | { 7 | internal class ListTranscriptions 8 | { 9 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 10 | 11 | internal static void Main(string[] args) 12 | { 13 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 14 | 15 | var transcriptions = client.ListTranscriptions("CALL ID", "LEG ID", "RECORDING ID"); 16 | try 17 | { 18 | foreach (var item in transcriptions.Data) 19 | { 20 | Console.WriteLine("The Transcription Id is: {0}", item.Id); 21 | Console.WriteLine("The Transcription Recording Id is: {0}", item.RecordingId); 22 | Console.WriteLine("The Transcription Status is: {0}", item.Status); 23 | } 24 | } 25 | catch (ErrorException e) 26 | { 27 | // Either the request fails with error descriptions from the endpoint. 28 | if (e.HasErrors) 29 | { 30 | foreach (var error in e.Errors) 31 | { 32 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 33 | } 34 | } 35 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 36 | if (e.HasReason) 37 | { 38 | Console.WriteLine(e.Reason); 39 | } 40 | } 41 | Console.WriteLine("Press any key to continue..."); 42 | Console.ReadKey(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Examples/Transcriptions/CreateTranscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | 6 | namespace Examples.Transcription 7 | { 8 | internal class CreateTranscription 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | var transcriptionResponse = client.CreateTranscription("CALL ID", "LEG ID", "RECORDING ID", "LANGUAGE"); 19 | var transcription = transcriptionResponse.Data.FirstOrDefault(); 20 | 21 | Console.WriteLine("The Transcription Id is: {0}", transcription.Id); 22 | Console.WriteLine("The Transcription Recording Id is: {0}", transcription.RecordingId); 23 | Console.WriteLine("The Transcription Status is: {0}", transcription.Status); 24 | } 25 | catch (ErrorException e) 26 | { 27 | // Either the request fails with error descriptions from the endpoint. 28 | if (e.HasErrors) 29 | { 30 | foreach (var error in e.Errors) 31 | { 32 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 33 | } 34 | } 35 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 36 | if (e.HasReason) 37 | { 38 | Console.WriteLine(e.Reason); 39 | } 40 | } 41 | Console.WriteLine("Press any key to continue..."); 42 | Console.ReadKey(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Examples/Transcriptions/ViewTranscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | 6 | namespace Examples.Transcription 7 | { 8 | internal class ViewTranscription 9 | { 10 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 11 | 12 | internal static void Main(string[] args) 13 | { 14 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 15 | 16 | try 17 | { 18 | var transcriptionResponse = client.ViewTranscription("CALL ID", "LEG ID", "RECORDING ID", "TRANSCRIPTION ID"); 19 | var transcription = transcriptionResponse.Data.FirstOrDefault(); 20 | 21 | Console.WriteLine("The Transcription Id is: {0}", transcription.Id); 22 | Console.WriteLine("The Transcription Recording Id is: {0}", transcription.RecordingId); 23 | Console.WriteLine("The Transcription Status is: {0}", transcription.Status); 24 | } 25 | catch (ErrorException e) 26 | { 27 | // Either the request fails with error descriptions from the endpoint. 28 | if (e.HasErrors) 29 | { 30 | foreach (var error in e.Errors) 31 | { 32 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 33 | } 34 | } 35 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 36 | if (e.HasReason) 37 | { 38 | Console.WriteLine(e.Reason); 39 | } 40 | } 41 | Console.WriteLine("Press any key to continue..."); 42 | Console.ReadKey(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Examples/Webhooks/CreateWebhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using System.Linq; 5 | using MessageBird.Objects.Voice; 6 | 7 | namespace Examples.Webhooks 8 | { 9 | internal class CreateWebhook 10 | { 11 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 12 | 13 | internal static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 16 | 17 | try 18 | { 19 | // Create webhook object 20 | var newWebhook = new Webhook 21 | { 22 | url = "WEBHOOK URL", 23 | token = "WEBHOOK TOKEN" 24 | }; 25 | 26 | var webhookResponse = client.CreateWebhook(newWebhook); 27 | var webhook = webhookResponse.Data.FirstOrDefault(); 28 | Console.WriteLine("The Webhook was created successfully with Id = {0}.", webhook.Id); 29 | } 30 | catch (ErrorException e) 31 | { 32 | // Either the request fails with error descriptions from the endpoint. 33 | if (e.HasErrors) 34 | { 35 | foreach (var error in e.Errors) 36 | { 37 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 38 | } 39 | } 40 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 41 | if (e.HasReason) 42 | { 43 | Console.WriteLine(e.Reason); 44 | } 45 | } 46 | Console.WriteLine("Press any key to continue..."); 47 | Console.ReadKey(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Examples/Verify/CreateEmailVerify.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Objects; 5 | 6 | namespace Examples.Verify 7 | { 8 | internal static class CreateEmailVerify 9 | { 10 | private const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 11 | private const string RecipientEmail = "example@messagebird.com"; // your email address here. 12 | 13 | private static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YourAccessKey); 16 | 17 | try 18 | { 19 | var optionalArguments = new VerifyOptionalArguments 20 | { 21 | Type = MessageType.Email, 22 | Originator = "verify@yourdomain.com" 23 | }; 24 | 25 | var verify = client.CreateVerify(RecipientEmail, optionalArguments); 26 | Console.WriteLine("{0}", verify); 27 | 28 | } 29 | catch (ErrorException e) 30 | { 31 | // Either the request fails with error descriptions from the endpoint. 32 | if (e.HasErrors) 33 | { 34 | foreach (var error in e.Errors) 35 | { 36 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 37 | } 38 | } 39 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 40 | if (e.HasReason) 41 | { 42 | Console.WriteLine(e.Reason); 43 | } 44 | } 45 | Console.WriteLine("Press any key to continue..."); 46 | Console.ReadKey(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Examples/Verify/CreateVerify.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Objects; 4 | using System; 5 | 6 | namespace Examples.Verify 7 | { 8 | class CreateVerify 9 | { 10 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 11 | const long PhoneNumber = 31612345678; // your phone number here. 12 | 13 | static void Main(string[] args) 14 | { 15 | Client client = Client.CreateDefault(YourAccessKey); 16 | 17 | try 18 | { 19 | VerifyOptionalArguments optionalArguments = new VerifyOptionalArguments(); 20 | // optionalArguments.Originator = "MessageBird"; 21 | // optionalArguments.TokenLength = 8; 22 | // optionalArguments.Timeout = 60; 23 | 24 | MessageBird.Objects.Verify verify = client.CreateVerify(PhoneNumber, optionalArguments); 25 | Console.WriteLine("{0}", verify); 26 | 27 | } 28 | catch (ErrorException e) 29 | { 30 | // Either the request fails with error descriptions from the endpoint. 31 | if (e.HasErrors) 32 | { 33 | foreach (Error error in e.Errors) 34 | { 35 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 36 | } 37 | } 38 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 39 | if (e.HasReason) 40 | { 41 | Console.WriteLine(e.Reason); 42 | } 43 | } 44 | Console.WriteLine("Press any key to continue..."); 45 | Console.ReadKey(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /MessageBird/Exceptions/ErrorException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | using MessageBird.Objects; 5 | using Newtonsoft.Json; 6 | 7 | namespace MessageBird.Exceptions 8 | { 9 | public class ErrorException : Exception 10 | { 11 | private readonly ICollection errors; 12 | 13 | // IEnumerable to be immitable. 14 | // TODO: should these really be based on the JSON Errors class, and not a resource translation of it? 15 | public IEnumerable Errors 16 | { 17 | get { return errors; } 18 | } 19 | 20 | public string Reason { get; private set; } 21 | 22 | public bool HasErrors 23 | { 24 | get { return (Errors != null) && (errors.Count > 0); } 25 | } 26 | 27 | public bool HasReason 28 | { 29 | get { return !String.IsNullOrEmpty(Reason); } 30 | } 31 | 32 | public ErrorException(string reason, Exception? innerException = null) : base(reason, innerException) 33 | { 34 | Reason = reason; 35 | } 36 | 37 | public ErrorException(ICollection errors, Exception innerException) 38 | : base("multiple errors", innerException) 39 | { 40 | this.errors = errors; 41 | } 42 | 43 | // XXX: Solve explicit use of json deserialation, needs to be more generic! 44 | public static ErrorException FromResponse(string response, Exception innerException) 45 | { 46 | try 47 | { 48 | var errors = JsonConvert.DeserializeObject>>(response); 49 | return new ErrorException(errors["errors"], innerException); 50 | } 51 | catch (JsonSerializationException) 52 | { 53 | return null; 54 | } 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/HsmContent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Runtime.Serialization; 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | using Newtonsoft.Json.Serialization; 7 | 8 | namespace MessageBird.Objects.Conversations 9 | { 10 | public enum HsmLanguagePolicy 11 | { 12 | [EnumMember(Value = "deterministic")] 13 | Deterministic, 14 | [EnumMember(Value = "fallback")] 15 | Fallback, 16 | } 17 | public class HsmLanguage 18 | { 19 | [JsonProperty("code")] 20 | public string Code {get;set;} 21 | 22 | [JsonProperty("policy"), JsonConverter(typeof(StringEnumConverter))] 23 | public HsmLanguagePolicy Policy {get;set;} 24 | } 25 | 26 | public class HsmLocalizableParameter 27 | { 28 | [JsonProperty("default")] 29 | public string Default {get; set;} 30 | 31 | [JsonProperty("currency")] 32 | public HsmLocalizableParameterCurrency Currency {get; set;} 33 | 34 | [JsonProperty("dateTime")] 35 | public DateTime? DateTime {get; set;} 36 | } 37 | 38 | public class HsmLocalizableParameterCurrency 39 | { 40 | [JsonProperty("currencyCode")] 41 | public string CurrencyCode {get;set;} 42 | 43 | [JsonProperty("amount")] 44 | public int Amount {get;set;} 45 | } 46 | 47 | public class HsmContent 48 | { 49 | [JsonProperty("namespace")] 50 | public string Namespace {get; set;} 51 | 52 | [JsonProperty("templateName")] 53 | public string TemplateName {get; set;} 54 | 55 | [JsonProperty("language")] 56 | public HsmLanguage Language {get; set;} 57 | 58 | [JsonProperty("params")] 59 | public List Params {get; set;} 60 | } 61 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/TranscriptionList.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [ 3 | { 4 | "id": "1ce04c83-ca4f-4d94-8310-02968da41317", 5 | "recordingId": "cfa9ae96-e034-4db7-91cb-e58a8392c7bd", 6 | "status": "done", 7 | "createdAt": "2020-01-08T14:37:46Z", 8 | "updatedAt": "2020-01-08T14:37:53Z", 9 | "legId": "00000000-0000-0000-0000-000000000000", 10 | "_links": { 11 | "file": "/transcriptions/1ce04c83-ca4f-4d94-8310-02968da41317.txt", 12 | "self": "/transcriptions/1ce04c83-ca4f-4d94-8310-02968da41317" 13 | } 14 | }, 15 | { 16 | "id": "2ce04c83-ca4f-4d94-8310-02968da41318", 17 | "recordingId": "cfa9ae96-e034-4db7-91cb-e58a8392c7bd", 18 | "status": "done", 19 | "createdAt": "2020-01-07T14:37:46Z", 20 | "updatedAt": "2020-01-07T14:37:53Z", 21 | "legId": "00000000-0000-0000-0000-000000000000", 22 | "_links": { 23 | "file": "/transcriptions/2ce04c83-ca4f-4d94-8310-02968da41318.txt", 24 | "self": "/transcriptions/2ce04c83-ca4f-4d94-8310-02968da41318" 25 | } 26 | }, 27 | { 28 | "id": "3ce04c83-ca4f-4d94-8310-02968da41319", 29 | "recordingId": "cfa9ae96-e034-4db7-91cb-e58a8392c7bd", 30 | "status": "done", 31 | "createdAt": "2020-01-06T14:37:46Z", 32 | "updatedAt": "2020-01-06T14:37:53Z", 33 | "legId": "00000000-0000-0000-0000-000000000000", 34 | "_links": { 35 | "file": "/transcriptions/3ce04c83-ca4f-4d94-8310-02968da41319.txt", 36 | "self": "/transcriptions/3ce04c83-ca4f-4d94-8310-02968da41319" 37 | } 38 | } 39 | ], 40 | "_links": { 41 | "self": "/calls/373395cc-382b-4a33-b372-cc31f0fdf242/legs/8dd347a4-11ee-44f2-bee3-7fbda300b2cd/recordings/cfa9ae96-e034-4db7-91cb-e58a8392c7bd/transcriptions" 42 | }, 43 | "pagination": { 44 | "totalCount": 3, 45 | "pageCount": 1, 46 | "currentPage": 1, 47 | "perPage": 10 48 | } 49 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Group.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Json.Converters; 2 | using Newtonsoft.Json; 3 | using System; 4 | 5 | namespace MessageBird.Objects 6 | { 7 | public class Group : IIdentifiable 8 | { 9 | [JsonProperty("id")] 10 | public string Id { get; set; } 11 | 12 | [JsonProperty("href")] 13 | public string Href { get; set; } 14 | 15 | [JsonProperty("name")] 16 | public string Name { get; set; } 17 | 18 | [JsonProperty("contacts")] 19 | public GroupContactReference Contacts { get; set; } 20 | 21 | [JsonProperty("createdDatetime"), JsonConverter(typeof(RFC3339DateTimeConverter))] 22 | public DateTime? CreatedDatetime; 23 | 24 | [JsonProperty("updatedDatetime"), JsonConverter(typeof(RFC3339DateTimeConverter))] 25 | public DateTime? UpdatedDatetime; 26 | 27 | /// 28 | /// Don't serialize the ID, e.g. when updating. 29 | /// 30 | /// 31 | /// A request object that can be used for serializing. 32 | /// 33 | public RequestObject ToRequestObject() 34 | { 35 | return new RequestObject(this); 36 | } 37 | 38 | public override string ToString() 39 | { 40 | RequestObject requestObject = ToRequestObject(); 41 | 42 | return JsonConvert.SerializeObject(requestObject, Formatting.Indented); 43 | } 44 | 45 | /// 46 | /// Object that can be used for serializing to JSON when making 47 | /// requests. 48 | /// 49 | public class RequestObject 50 | { 51 | [JsonProperty("name")] 52 | public string Name { get; set; } 53 | 54 | public RequestObject(Group group) 55 | { 56 | Name = group.Name; 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Examples/CallFlow/UpdateCallFlow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | using MessageBird.Objects.Voice; 6 | 7 | namespace Examples.CallFlow 8 | { 9 | internal class UpdateCallFlow 10 | { 11 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 12 | 13 | internal static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 16 | var callFlow = new MessageBird.Objects.Voice.CallFlow 17 | { 18 | Record = true 19 | }; 20 | callFlow.Steps.Add(new Step { Action = "transfer", Options = new Options { Destination = "1234567890" } }); 21 | 22 | try 23 | { 24 | var callFlowResponse = client.UpdateCallFlow("ID", callFlow); 25 | var updatedCallFlow = callFlowResponse.Data.FirstOrDefault(); 26 | 27 | Console.WriteLine("The Voice Call Flow with Id = {0} has been updated", updatedCallFlow.Id); 28 | } 29 | catch (ErrorException e) 30 | { 31 | // Either the request fails with error descriptions from the endpoint. 32 | if (e.HasErrors) 33 | { 34 | foreach (var error in e.Errors) 35 | { 36 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 37 | } 38 | } 39 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 40 | if (e.HasReason) 41 | { 42 | Console.WriteLine(e.Reason); 43 | } 44 | } 45 | Console.WriteLine("Press any key to continue..."); 46 | Console.ReadKey(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Examples/CallFlow/CreateCallFlow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MessageBird; 4 | using MessageBird.Exceptions; 5 | using MessageBird.Objects.Voice; 6 | 7 | namespace Examples.CallFlow 8 | { 9 | internal class CreateCallFlow 10 | { 11 | private const string YourAccessKey = "YOUR_ACCESS_KEY"; 12 | 13 | internal static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YourAccessKey); 16 | var newCallFlow = new MessageBird.Objects.Voice.CallFlow 17 | { 18 | Record = true 19 | }; 20 | newCallFlow.Steps.Add(new Step { Action = "transfer", Options = new Options { Destination = "1234567890" } }); 21 | 22 | try 23 | { 24 | var callFlowResponse = client.CreateCallFlow(newCallFlow); 25 | var callFlow = callFlowResponse.Data.FirstOrDefault(); 26 | 27 | Console.WriteLine("The Voice Call Flow with Id = {0} has been created", callFlow.Id); 28 | } 29 | catch (ErrorException e) 30 | { 31 | // Either the request fails with error descriptions from the endpoint. 32 | if (e.HasErrors) 33 | { 34 | foreach (var error in e.Errors) 35 | { 36 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 37 | } 38 | } 39 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 40 | if (e.HasReason) 41 | { 42 | Console.WriteLine(e.Reason); 43 | } 44 | } 45 | Console.WriteLine("Press any key to continue..."); 46 | Console.ReadKey(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Examples/Webhooks/UpdateWebhook.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using System.Linq; 5 | using MessageBird.Objects.Voice; 6 | 7 | namespace Examples.Webhooks 8 | { 9 | internal class UpdateWebhook 10 | { 11 | const string YOUR_ACCESS_KEY = "YOUR_ACCESS_KEY"; 12 | 13 | internal static void Main(string[] args) 14 | { 15 | var client = Client.CreateDefault(YOUR_ACCESS_KEY); 16 | 17 | try 18 | { 19 | string webhookId = "WEBHOOK ID"; 20 | 21 | // Create webhook object 22 | var updateWebhook = new Webhook 23 | { 24 | url = "WEBHOOK URL", 25 | token = "WEBHOOK TOKEN" 26 | }; 27 | 28 | var webhookResponse = client.UpdateWebhook(webhookId, updateWebhook); 29 | var webhook = webhookResponse.Data.FirstOrDefault(); 30 | Console.WriteLine("The Webhook was successfully updated with Id = {0}.", webhook.Id); 31 | } 32 | catch (ErrorException e) 33 | { 34 | // Either the request fails with error descriptions from the endpoint. 35 | if (e.HasErrors) 36 | { 37 | foreach (var error in e.Errors) 38 | { 39 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 40 | } 41 | } 42 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 43 | if (e.HasReason) 44 | { 45 | Console.WriteLine(e.Reason); 46 | } 47 | } 48 | Console.WriteLine("Press any key to continue..."); 49 | Console.ReadKey(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MessageBird/Objects/Recipient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | 7 | 8 | namespace MessageBird.Objects 9 | { 10 | public class Recipient 11 | { 12 | public enum RecipientStatus 13 | { 14 | // Message status 15 | [EnumMember(Value = "scheduled")] 16 | Scheduled, 17 | [EnumMember(Value = "sent")] 18 | Sent, 19 | [EnumMember(Value = "buffered")] 20 | Buffered, 21 | [EnumMember(Value = "delivered")] 22 | Delivered, 23 | [EnumMember(Value = "delivery_failed")] 24 | DeliveryFailed, 25 | [EnumMember(Value = "expired")] 26 | Expired, 27 | // Voice message status 28 | [EnumMember(Value = "calling")] 29 | Calling, 30 | [EnumMember(Value = "answered")] 31 | Answered, 32 | [EnumMember(Value = "failed")] 33 | Failed, 34 | // reserved for future use 35 | [EnumMember(Value = "busy")] 36 | Busy, 37 | [EnumMember(Value = "machine")] 38 | Machine 39 | }; 40 | 41 | [JsonProperty("recipient")] 42 | public long Msisdn { get; set; } 43 | 44 | [JsonProperty("status")] 45 | [JsonConverter(typeof(StringEnumConverter))] 46 | public RecipientStatus? Status { get; set; } 47 | 48 | [JsonProperty("statusDatetime")] 49 | public DateTime? StatusDatetime { get; set; } 50 | 51 | [JsonProperty("messagePartCount")] 52 | public int MessagePartCount { get; set; } 53 | 54 | public Recipient(long msisdn) 55 | { 56 | Msisdn = msisdn; 57 | } 58 | 59 | public override string ToString() 60 | { 61 | return JsonConvert.SerializeObject(this, Formatting.Indented); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MessageBird/Objects/Hlr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | using Newtonsoft.Json; 5 | using Newtonsoft.Json.Converters; 6 | 7 | namespace MessageBird.Objects 8 | { 9 | public enum HlrStatus 10 | { 11 | [EnumMember(Value = "sent")] 12 | Sent, 13 | [EnumMember(Value = "absent")] 14 | Absent, 15 | [EnumMember(Value = "active")] 16 | Active, 17 | [EnumMember(Value = "unknown")] 18 | Unknown, 19 | [EnumMember(Value = "failed")] 20 | Failed, 21 | } 22 | 23 | public class Hlr : IIdentifiable 24 | { 25 | [JsonProperty("id")] 26 | public string Id { get; set; } 27 | 28 | [JsonProperty("href")] 29 | public string Href { get; set; } 30 | 31 | [JsonProperty("msisdn")] 32 | public long Msisdn { get; set; } 33 | 34 | [JsonProperty("network")] 35 | public int? Network { get; set; } 36 | 37 | [JsonProperty("details")] 38 | public HlrDetails Details { get; set; } 39 | 40 | [JsonProperty("reference")] 41 | public string Reference { get; set; } 42 | 43 | [JsonProperty("status"), JsonConverter(typeof(StringEnumConverter))] 44 | public HlrStatus? Status { get; set; } 45 | 46 | [JsonProperty("createdDatetime")] 47 | public DateTime? Created { get; set; } 48 | 49 | [JsonProperty("statusDatetime")] 50 | public DateTime? LastStatus { get; set; } 51 | 52 | public Hlr() 53 | { 54 | } 55 | 56 | public Hlr(string id) 57 | { 58 | Id = id; 59 | } 60 | 61 | public Hlr(long msisdn, string reference) 62 | { 63 | Msisdn = msisdn; 64 | Reference = reference; 65 | } 66 | 67 | public override string ToString() 68 | { 69 | return JsonConvert.SerializeObject(this, Formatting.Indented); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Examples/Balance/ViewBalance.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.Balance 8 | { 9 | class ViewBalance 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | 13 | static void Main(string[] args) 14 | { 15 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 16 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 17 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 18 | 19 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 20 | 21 | try 22 | { 23 | MessageBird.Objects.Balance balance = client.Balance(); 24 | Console.WriteLine("{0}", balance); 25 | } 26 | catch (ErrorException e) 27 | { 28 | // Either the request fails with error descriptions from the endpoint. 29 | if (e.HasErrors) 30 | { 31 | foreach (Error error in e.Errors) 32 | { 33 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 34 | } 35 | } 36 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 37 | if (e.HasReason) 38 | { 39 | Console.WriteLine(e.Reason); 40 | } 41 | } 42 | Console.WriteLine("Press any key to continue..."); 43 | Console.ReadKey(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Examples/HLR/RequestHlr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.HLR 8 | { 9 | class RequestHlr 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const long Msisdn = 31612345678; // your phone number here. 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | Hlr hlr = client.RequestHlr(Msisdn, "Custom reference"); 25 | Console.WriteLine("{0}", hlr); 26 | 27 | } 28 | catch (ErrorException e) 29 | { 30 | // Either the request fails with error descriptions from the endpoint. 31 | if (e.HasErrors) 32 | { 33 | foreach (Error error in e.Errors) 34 | { 35 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 36 | } 37 | } 38 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 39 | if (e.HasReason) 40 | { 41 | Console.WriteLine(e.Reason); 42 | } 43 | } 44 | Console.WriteLine("Press any key to continue..."); 45 | Console.ReadKey(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Examples/Verify/CreateVoiceVerify.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Objects; 5 | using MessageBird.Objects.Common; 6 | 7 | namespace Examples.Verify 8 | { 9 | class CreateVoiceVerify 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const long PhoneNumber = 31612345678; // your phone number here. 13 | 14 | static void Main(string[] args) 15 | { 16 | Client client = Client.CreateDefault(YourAccessKey); 17 | 18 | try 19 | { 20 | VerifyOptionalArguments optionalArguments = new VerifyOptionalArguments(); 21 | optionalArguments.Type = MessageType.Tts; 22 | optionalArguments.Voice = Voice.Female; 23 | optionalArguments.Language = Language.Dutch; 24 | // optionalArguments.Originator = "MessageBird"; 25 | // optionalArguments.TokenLength = 8; 26 | // optionalArguments.Timeout = 60; 27 | 28 | MessageBird.Objects.Verify verify = client.CreateVerify(PhoneNumber, optionalArguments); 29 | Console.WriteLine("{0}", verify); 30 | 31 | } 32 | catch (ErrorException e) 33 | { 34 | // Either the request fails with error descriptions from the endpoint. 35 | if (e.HasErrors) 36 | { 37 | foreach (Error error in e.Errors) 38 | { 39 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 40 | } 41 | } 42 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 43 | if (e.HasReason) 44 | { 45 | Console.WriteLine(e.Reason); 46 | } 47 | } 48 | Console.WriteLine("Press any key to continue..."); 49 | Console.ReadKey(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Examples/Message/CreateMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.Message 8 | { 9 | class CreateMessage 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const long Msisdn = 31612345678; // your phone number here. 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | MessageBird.Objects.Message message = client.SendMessage("MessageBird", "Tjirp tjirp", new[] { Msisdn }); 25 | Console.WriteLine("{0}", message); 26 | } 27 | catch (ErrorException e) 28 | { 29 | // Either the request fails with error descriptions from the endpoint. 30 | if (e.HasErrors) 31 | { 32 | foreach (Error error in e.Errors) 33 | { 34 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 35 | } 36 | } 37 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 38 | if (e.HasReason) 39 | { 40 | Console.WriteLine(e.Reason); 41 | } 42 | } 43 | Console.WriteLine("Press any key to continue..."); 44 | Console.ReadKey(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Examples/Call/CreateCall.cs: -------------------------------------------------------------------------------- 1 | using MessageBird; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Objects.Voice; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | 8 | namespace Examples.Call 9 | { 10 | internal class CreateCall 11 | { 12 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 13 | 14 | internal static void Main(string[] args) 15 | { 16 | 17 | var client = Client.CreateDefault(YourAccessKey); 18 | var newCallFlow = new MessageBird.Objects.Voice.CallFlow 19 | { 20 | Record = true, 21 | Steps = new List { new Step { Action = "transfer", Options = new Options { Destination = "31612345678" } } } 22 | }; 23 | 24 | var newCall = new MessageBird.Objects.Voice.Call 25 | { 26 | Source = "31644556677", 27 | Destination = "33766723144", 28 | CallFlow = newCallFlow 29 | 30 | }; 31 | try 32 | { 33 | var callResponse = client.CreateCall(newCall); 34 | var call = callResponse.Data.FirstOrDefault(); 35 | Console.WriteLine("The Call Flow Created with Id = {0}", call.Id); 36 | } 37 | catch (ErrorException e) 38 | { 39 | // Either the request fails with error descriptions from the endpoint. 40 | if (e.HasErrors) 41 | { 42 | foreach (var error in e.Errors) 43 | { 44 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 45 | } 46 | } 47 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 48 | if (e.HasReason) 49 | { 50 | Console.WriteLine(e.Reason); 51 | } 52 | } 53 | Console.WriteLine("Press any key to continue..."); 54 | Console.ReadKey(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Resources/RFC3339DateTimeConverterTest.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Exceptions; 2 | using MessageBird.Objects; 3 | using MessageBird.Resources; 4 | using Microsoft.VisualStudio.TestTools.UnitTesting; 5 | using Newtonsoft.Json; 6 | 7 | namespace MessageBird.Tests.Resources 8 | { 9 | [TestClass] 10 | public class RFC3339DateTimeConverterTest 11 | { 12 | [TestMethod] 13 | public void InvalidRFC3339DateTime() 14 | { 15 | // The following message has an invalid createDateTime format. 16 | const string JsonResultFromCreateMessage = @"{ 17 | 'id':'e7028180453e8a69d318686b17179500', 18 | 'href':'https:\/\/rest.messagebird.com\/messages\/e7028180453e8a69d318686b17179500', 19 | 'direction':'mt', 20 | 'type':'sms', 21 | 'originator':'MsgBirdSms', 22 | 'body':'Welcome to MessageBird', 23 | 'reference':null, 24 | 'validity':null, 25 | 'gateway':56, 26 | 'typeDetails':{ 27 | 28 | }, 29 | 'datacoding':'plain', 30 | 'mclass':1, 31 | 'scheduledDatetime':null, 32 | 'createdDatetime':'2014-08-11T11:18:53', 33 | 'recipients':{ 34 | 'totalCount':1, 35 | 'totalSentCount':1, 36 | 'totalDeliveredCount':0, 37 | 'totalDeliveryFailedCount':0, 38 | 'items':[ 39 | { 40 | 'recipient':31612345678, 41 | 'status':'sent', 42 | 'statusDatetime':'2014-08-11T11:18:53+00:00' 43 | } 44 | ] 45 | } 46 | }"; 47 | var recipients = new Recipients(); 48 | var message = new Message("", "", recipients); 49 | var messages = new Messages(message); 50 | try 51 | { 52 | messages.Deserialize(JsonResultFromCreateMessage); 53 | Assert.Fail("Expected an error exception, because there is an invalid rfc3339 datetime."); 54 | } 55 | catch (ErrorException e) 56 | { 57 | // The exception is thrown by the RFC3339DateTimeConverter, so the inner exception 58 | // must be of type JsonSerializationException. 59 | Assert.IsInstanceOfType(e.InnerException, typeof(JsonSerializationException)); 60 | } 61 | 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /MessageBird/Json/Converters/RFC3339DateTimeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | using MessageBird.Utilities; 4 | using Newtonsoft.Json; 5 | 6 | namespace MessageBird.Json.Converters 7 | { 8 | class RFC3339DateTimeConverter : JsonConverter 9 | { 10 | private const string Format = "yyyy-MM-dd'T'HH:mm:ssK"; 11 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 12 | { 13 | if (value is DateTime) 14 | { 15 | var dateTime = (DateTime)value; 16 | if (dateTime.Kind == DateTimeKind.Unspecified) 17 | { 18 | throw new JsonSerializationException("Cannot convert date time with an unspecified kind"); 19 | } 20 | string convertedDateTime = dateTime.ToString(Format); 21 | writer.WriteValue(convertedDateTime); 22 | } 23 | else 24 | { 25 | throw new JsonSerializationException("Expected value of type 'DateTime'."); 26 | } 27 | } 28 | 29 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 30 | { 31 | if (reader.TokenType == JsonToken.Null) 32 | { 33 | return null; 34 | } 35 | 36 | if (reader.TokenType == JsonToken.Date) 37 | { 38 | var dateTime = (DateTime)reader.Value; 39 | if (dateTime.Kind == DateTimeKind.Unspecified) 40 | { 41 | throw new JsonSerializationException("Parsed date time is not in the expected RFC3339 format"); 42 | } 43 | return dateTime; 44 | } 45 | throw new JsonSerializationException(String.Format("Unexpected token '{0}' when parsing date.", reader.TokenType)); 46 | } 47 | 48 | public override bool CanConvert(Type objectType) 49 | { 50 | Type t = (ReflectionUtils.IsNullable(objectType)) 51 | ? Nullable.GetUnderlyingType(objectType) 52 | : objectType; 53 | 54 | return t == typeof(DateTime); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Examples/VoiceMessage/ViewVoiceMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.VoiceMessage 8 | { 9 | class ViewVoiceMessage 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const string MessageId = "ca0a8220453bc36ddeb3115a37400870"; // ID of message that you sent before (otherwise you get http statuscode 404: not found) 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | MessageBird.Objects.VoiceMessage voiceMessage = client.ViewVoiceMessage(MessageId); 25 | Console.WriteLine("{0}", voiceMessage); 26 | } 27 | catch (ErrorException e) 28 | { 29 | // Either the request fails with error descriptions from the endpoint. 30 | if (e.HasErrors) 31 | { 32 | foreach (Error error in e.Errors) 33 | { 34 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 35 | } 36 | } 37 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 38 | if (e.HasReason) 39 | { 40 | Console.WriteLine(e.Reason); 41 | } 42 | } 43 | Console.WriteLine("Press any key to continue..."); 44 | Console.ReadKey(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Examples/HLR/ViewHlr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.HLR 8 | { 9 | class ViewHlr 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const string HlrId = "c8143db0152a58755c80492h61377581"; // ID of HLR you obtained before (seems to require also "in the same session"). When not found, you will not get a http StatusCode 404, but an exception `code: 20 description: 'hlr not found' parameter: ''` 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | Hlr hlr = client.ViewHlr(HlrId); 25 | Console.WriteLine("{0}", hlr); 26 | 27 | } 28 | catch (ErrorException e) 29 | { 30 | // Either the request fails with error descriptions from the endpoint. 31 | if (e.HasErrors) 32 | { 33 | foreach (Error error in e.Errors) 34 | { 35 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 36 | } 37 | } 38 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 39 | if (e.HasReason) 40 | { 41 | Console.WriteLine(e.Reason); 42 | } 43 | } 44 | Console.WriteLine("Press any key to continue..."); 45 | Console.ReadKey(); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Examples/Message/ViewMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.Message 8 | { 9 | class ViewMessage 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const string MessageId = "ad86c8c0153a194a59a17e2b71578856"; // ID of message you sent before. When not found, you will not get a http StatusCode 404, but an exception `code: 20 description: 'message not found' parameter: ''` 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | MessageBird.Objects.Message message = client.ViewMessage(MessageId); 25 | Console.WriteLine("{0}", message); 26 | } 27 | catch (ErrorException e) 28 | { 29 | // Either the request fails with error descriptions from the endpoint. 30 | if (e.HasErrors) 31 | { 32 | foreach (Error error in e.Errors) 33 | { 34 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 35 | } 36 | } 37 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 38 | if (e.HasReason) 39 | { 40 | Console.WriteLine(e.Reason); 41 | } 42 | } 43 | Console.WriteLine("Press any key to continue..."); 44 | Console.ReadKey(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /MessageBird/Resources/VerifyAPIObject.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using MessageBird.Json.Converters; 4 | using MessageBird.Objects; 5 | using Newtonsoft.Json; 6 | using Newtonsoft.Json.Converters; 7 | 8 | namespace MessageBird.Resources 9 | { 10 | internal class VerifyAPIObject : IIdentifiable 11 | { 12 | [JsonProperty("id")] 13 | public string Id { get; set; } 14 | 15 | [JsonProperty("href")] 16 | public string Href { get; set; } 17 | 18 | [JsonProperty("recipient")] 19 | public string Recipient { get; set; } 20 | 21 | [JsonProperty("reference")] 22 | public string Reference { get; set; } 23 | 24 | [JsonProperty("messages"), JsonConverter(typeof(MessageConverter))] 25 | public Message Message { get; set; } 26 | 27 | [JsonProperty("status"), JsonConverter(typeof(StringEnumConverter))] 28 | public VerifyStatus? Status { get; set; } 29 | 30 | [JsonProperty("createdDatetime")] 31 | public DateTime? Created { get; set; } 32 | 33 | [JsonProperty("validUntilDatetime")] 34 | public DateTime? ValidUntil { get; set; } 35 | 36 | [JsonProperty("originator")] 37 | public string Originator { get; set; } 38 | 39 | [JsonProperty("template")] 40 | public string Template { get; set; } 41 | 42 | [JsonProperty("datacoding"), DefaultValue(DataEncoding.Plain), JsonConverter(typeof(StringEnumConverter))] 43 | public DataEncoding Encoding { get; set; } 44 | 45 | [JsonProperty("tokenLength"), DefaultValue(6)] 46 | public int TokenLength { get; set; } 47 | 48 | [JsonProperty("type"), DefaultValue(MessageType.Sms), JsonConverter(typeof(StringEnumConverter))] 49 | public MessageType Type { get; set; } 50 | 51 | [JsonProperty("timeout"), DefaultValue(30)] 52 | public int Timeout { get; set; } 53 | 54 | [JsonProperty("voice"), JsonConverter(typeof(StringEnumConverter))] 55 | public Objects.Common.Voice Voice { get; set; } 56 | 57 | [JsonProperty("language"), JsonConverter(typeof(StringEnumConverter))] 58 | public Objects.Common.Language Language { get; set; } 59 | 60 | [JsonProperty("Token")] 61 | public string Token { get; set; } 62 | } 63 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/ListVoiceMessages.json: -------------------------------------------------------------------------------- 1 | { 2 | "offset": 0, 3 | "limit": 10, 4 | "count": 2, 5 | "totalCount": 2, 6 | "links": { 7 | "first": "https://rest.messagebird.com/voicemessages/?offset=0&limit=30", 8 | "previous": null, 9 | "next": null, 10 | "last": "https://rest.messagebird.com/voicemessages/?offset=0&limit=30" 11 | }, 12 | "items": [ 13 | { 14 | "id": "12345678-9012-3456-7890-123456789012", 15 | "href": "https://rest.messagebird.com/voicemessages/12345678-9012-3456-7890-123456789012", 16 | "originator": null, 17 | "body": "This is a test message.", 18 | "reference": null, 19 | "language": "en-gb", 20 | "voice": "male", 21 | "repeat": 1, 22 | "ifMachine": "continue", 23 | "machineTimeout": 7000, 24 | "scheduledDatetime": null, 25 | "createdDatetime": "2020-02-04T15:15:30+00:00", 26 | "recipients": { 27 | "totalCount": 1, 28 | "totalSentCount": 1, 29 | "totalDeliveredCount": 1, 30 | "totalDeliveryFailedCount": 0, 31 | "items": [ 32 | { 33 | "recipient": 31612345678, 34 | "originator": null, 35 | "status": "answered", 36 | "statusDatetime": "2020-02-04T15:15:57+00:00" 37 | } 38 | ] 39 | } 40 | }, 41 | { 42 | "id": "12345678-9012-3456-7890-123456789013", 43 | "href": "https://rest.messagebird.com/voicemessages/12345678-9012-3456-7890-123456789013", 44 | "originator": null, 45 | "body": "The voice message to be sent", 46 | "reference": null, 47 | "language": "en-gb", 48 | "voice": "female", 49 | "repeat": 1, 50 | "ifMachine": "delay", 51 | "machineTimeout": 7000, 52 | "scheduledDatetime": null, 53 | "createdDatetime": "2020-02-04T12:26:44+00:00", 54 | "recipients": { 55 | "totalCount": 1, 56 | "totalSentCount": 1, 57 | "totalDeliveredCount": 1, 58 | "totalDeliveryFailedCount": 0, 59 | "items": [ 60 | { 61 | "recipient": 31612345678, 62 | "originator": null, 63 | "status": "answered", 64 | "statusDatetime": "2020-02-04T12:27:32+00:00" 65 | } 66 | ] 67 | } 68 | } 69 | ] 70 | } 71 | -------------------------------------------------------------------------------- /Examples/Lookup/ViewLookup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.Lookup 8 | { 9 | class ViewLookup 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const long PhoneNumber = 31612345678; // your phone number here. 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | LookupOptionalArguments optionalArguments = new LookupOptionalArguments(); 25 | //optionalArguments.CountryCode = "NL"; // When using a national format, make sure a country code is also sent 26 | 27 | MessageBird.Objects.Lookup lookup = client.ViewLookup(PhoneNumber, optionalArguments); 28 | Console.WriteLine("{0}", lookup); 29 | 30 | } 31 | catch (ErrorException e) 32 | { 33 | // Either the request fails with error descriptions from the endpoint. 34 | if (e.HasErrors) 35 | { 36 | foreach (Error error in e.Errors) 37 | { 38 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 39 | } 40 | } 41 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 42 | if (e.HasReason) 43 | { 44 | Console.WriteLine(e.Reason); 45 | } 46 | } 47 | Console.WriteLine("Press any key to continue..."); 48 | Console.ReadKey(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Examples/Lookup/ViewLookupHlr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.Lookup 8 | { 9 | class ViewLookupHlr 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const long PhoneNumber = 31612345678; // your phone number here. 13 | 14 | static void Main(string[] args) 15 | { 16 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 17 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 18 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 19 | 20 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 21 | 22 | try 23 | { 24 | LookupHlrOptionalArguments optionalArguments = new LookupHlrOptionalArguments(); 25 | //optionalArguments.CountryCode = "NL"; // When using a national format, make sure a country code is also sent 26 | 27 | LookupHlr LookupHlr = client.ViewLookupHlr(PhoneNumber, optionalArguments); 28 | Console.WriteLine("{0}", LookupHlr); 29 | 30 | } 31 | catch (ErrorException e) 32 | { 33 | // Either the request fails with error descriptions from the endpoint. 34 | if (e.HasErrors) 35 | { 36 | foreach (Error error in e.Errors) 37 | { 38 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 39 | } 40 | } 41 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 42 | if (e.HasReason) 43 | { 44 | Console.WriteLine(e.Reason); 45 | } 46 | } 47 | Console.WriteLine("Press any key to continue..."); 48 | Console.ReadKey(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Examples/Lookup/RequestLookupHlr.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | 7 | namespace Examples.Lookup 8 | { 9 | class RequestLookupHlr 10 | { 11 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 12 | const string Reference = "SampleReference"; 13 | const long PhoneNumber = 31612345678; // your phone number here. 14 | 15 | static void Main(string[] args) 16 | { 17 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 18 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 19 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 20 | 21 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 22 | 23 | try 24 | { 25 | LookupHlrOptionalArguments optionalArguments = new LookupHlrOptionalArguments(); 26 | //optionalArguments.CountryCode = "NL"; // When using a national format, make sure a country code is also sent 27 | 28 | LookupHlr lookupHlr = client.RequestLookupHlr(PhoneNumber, Reference, optionalArguments); 29 | Console.WriteLine("{0}", lookupHlr); 30 | 31 | } 32 | catch (ErrorException e) 33 | { 34 | // Either the request fails with error descriptions from the endpoint. 35 | if (e.HasErrors) 36 | { 37 | foreach (Error error in e.Errors) 38 | { 39 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 40 | } 41 | } 42 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 43 | if (e.HasReason) 44 | { 45 | Console.WriteLine(e.Reason); 46 | } 47 | } 48 | Console.WriteLine("Press any key to continue..."); 49 | Console.ReadKey(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /MessageBird/Objects/Common/Enums.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | 3 | namespace MessageBird.Objects.Common 4 | { 5 | public enum Language 6 | { 7 | [EnumMember(Value = "nl-nl")] 8 | Dutch, 9 | [EnumMember(Value = "de-de")] 10 | German, 11 | [EnumMember(Value = "en-gb")] 12 | English, 13 | [EnumMember(Value = "en-us")] 14 | AmericanEnglish, 15 | [EnumMember(Value = "en-au")] 16 | AustralianEnglish, 17 | [EnumMember(Value = "fr-fr")] 18 | French, 19 | [EnumMember(Value = "fr-ca")] 20 | CanadianFrench, 21 | [EnumMember(Value = "es-es")] 22 | Spanish, 23 | [EnumMember(Value = "es-mx")] 24 | MexicanSpanish, 25 | [EnumMember(Value = "es-us")] 26 | AmericanSpanish, 27 | [EnumMember(Value = "ru-ru")] 28 | Russian, 29 | [EnumMember(Value = "zh-cn")] 30 | Chinese, 31 | [EnumMember(Value = "is-is")] 32 | Icelandic, 33 | [EnumMember(Value = "it-it")] 34 | Italian, 35 | [EnumMember(Value = "ja-jp")] 36 | Japanese, 37 | [EnumMember(Value = "ko-kr")] 38 | Korean, 39 | [EnumMember(Value = "pl-pl")] 40 | Polish, 41 | [EnumMember(Value = "pt-br")] 42 | BrazilianPortuguese, 43 | [EnumMember(Value = "ro-ro")] 44 | Romanian, 45 | [EnumMember(Value = "da-dk")] 46 | Danish, 47 | [EnumMember(Value = "en-in")] 48 | IndianEnglish, 49 | [EnumMember(Value = "cy-gb")] 50 | Welsh, 51 | [EnumMember(Value = "nb-no")] 52 | Norwegian, 53 | [EnumMember(Value = "pt-pt")] 54 | Portuguese, 55 | [EnumMember(Value = "sv-se")] 56 | Swedish, 57 | [EnumMember(Value = "tr-tr")] 58 | Turkish, 59 | [EnumMember(Value = "el-gr")] 60 | Greek, 61 | [EnumMember(Value = "zh-hk")] 62 | HongKongChinese, 63 | [EnumMember(Value = "id-id")] 64 | Indonesian, 65 | [EnumMember(Value = "vi-vn")] 66 | Vietnamese, 67 | [EnumMember(Value = "th-th")] 68 | Thai, 69 | [EnumMember(Value = "ta-in")] 70 | TamilIndian, 71 | [EnumMember(Value = "ms-my")] 72 | Malay 73 | } 74 | 75 | public enum Voice 76 | { 77 | [EnumMember(Value = "male")] 78 | Male, 79 | [EnumMember(Value = "female")] 80 | Female, 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MessageBird's REST API for C# 2 | =============================== 3 | This repository contains the open source C# client for MessageBird's REST API. Documentation can be found at: https://developers.messagebird.com. 4 | 5 | ![build status](https://github.com/messagebird/csharp-rest-api/actions/workflows/test.yml/badge.svg?branch=master) 6 | [![NuGet version (MessageBird)](https://img.shields.io/nuget/v/MessageBird.svg?style=flat-square)](https://www.nuget.org/packages/MessageBird/) 7 | 8 | Requirements 9 | ----- 10 | 11 | - [Sign up](https://www.messagebird.com/en/signup) for a free MessageBird account 12 | - Create a new access_key in the developers sections 13 | 14 | Installation 15 | ----- 16 | 17 | #### JSON.NET 18 | 19 | The *MessageBird* project depends on JSON.NET, which can be installed using the *NuGet* package manager. 20 | For more information on how to achieve this, see ['Managing NuGet packages using the dialog'](http://docs.nuget.org/docs/start-here/managing-nuget-packages-using-the-dialog). 21 | 22 | Usage 23 | ----- 24 | 25 | We have put some self-explanatory examples in the *Examples* project, but here is a quick breakdown on how it works. First, you need to set up a **MessageBird.Client**. Be sure to replace **YOUR_ACCESS_KEY** with something real. 26 | 27 | ```csharp 28 | using System; 29 | using MessageBird; 30 | using MessageBird.Objects; 31 | 32 | class Example 33 | { 34 | static void Main(string[] args) 35 | { 36 | Client client = Client.CreateDefault("YOUR_ACCESS_KEY"); 37 | } 38 | } 39 | ``` 40 | 41 | That's easy enough. Now we can query the server for information. Lets use getting your balance overview as an example: 42 | 43 | ```csharp 44 | // Get your balance 45 | Balance balance = client.Balance(); 46 | ``` 47 | 48 | #### Error handling 49 | In case of an error the *client* throws an *ErrorException*. 50 | The *ErrorException* objects contains either: 51 | - an array of *Error* objects that encapsulates the errors in the response (see [errors](https://developers.messagebird.com/docs/errors) for more info), 52 | - a *best effort* description when no error information from the endpoint is available. 53 | 54 | See the provided examples on how to access error information from the *ErrorException*. 55 | 56 | Documentation 57 | ---- 58 | Complete documentation, instructions, and examples are available at: 59 | [https://developers.messagebird.com](https://developers.messagebird.com) 60 | 61 | 62 | License 63 | ---- 64 | The MessageBird REST Client for C# is licensed under [The ISC License](http://choosealicense.com/licenses/isc/). Copyright (c) 2014, Remco Vermeulen 65 | -------------------------------------------------------------------------------- /Examples/VoiceMessage/CreateVoiceMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird; 3 | using MessageBird.Exceptions; 4 | using MessageBird.Net.ProxyConfigurationInjector; 5 | using MessageBird.Objects; 6 | using MessageBird.Objects.Common; 7 | 8 | namespace Examples.VoiceMessage 9 | { 10 | class CreateVoiceMessage 11 | { 12 | const string YourAccessKey = "YOUR_ACCESS_KEY"; // your access key here. 13 | const long Msisdn = 31612345678; // your phone number here. 14 | 15 | static void Main(string[] args) 16 | { 17 | IProxyConfigurationInjector proxyConfigurationInjector = null; // for no web proxies, or web proxies not requiring authentication 18 | //proxyConfigurationInjector = new InjectDefaultCredentialsForProxiedUris(); // for NTLM based web proxies 19 | //proxyConfigurationInjector = new InjectCredentialsForProxiedUris(new NetworkCredential("domain\\user", "password")); // for username/password based web proxies 20 | 21 | Client client = Client.CreateDefault(YourAccessKey, proxyConfigurationInjector); 22 | 23 | try 24 | { 25 | var optionalArguments = new VoiceMessageOptionalArguments 26 | { 27 | Language = Language.English, 28 | Voice = Voice.Female, 29 | IfMachine = IfMachineOptions.Continue 30 | 31 | }; 32 | MessageBird.Objects.VoiceMessage voiceMessage = client.SendVoiceMessage("This is a test message. The message is converted to speech and the recipient is called on his mobile.", new[] { Msisdn }, optionalArguments); 33 | Console.WriteLine("{0}", voiceMessage); 34 | } 35 | catch (ErrorException e) 36 | { 37 | // Either the request fails with error descriptions from the endpoint. 38 | if (e.HasErrors) 39 | { 40 | foreach (Error error in e.Errors) 41 | { 42 | Console.WriteLine("code: {0} description: '{1}' parameter: '{2}'", error.Code, error.Description, error.Parameter); 43 | } 44 | } 45 | // or fails without error information from the endpoint, in which case the reason contains a 'best effort' description. 46 | if (e.HasReason) 47 | { 48 | Console.WriteLine(e.Reason); 49 | } 50 | } 51 | Console.WriteLine("Press any key to continue..."); 52 | Console.ReadKey(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /MessageBird/Objects/Conversations/ConversationMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Converters; 5 | 6 | namespace MessageBird.Objects.Conversations 7 | { 8 | public enum ConversationMessageDirection 9 | { 10 | [EnumMember(Value = "received")] 11 | Received, 12 | [EnumMember(Value = "sent")] 13 | Sent, 14 | } 15 | 16 | public enum ConversationMessageStatus 17 | { 18 | 19 | [EnumMember(Value = "deleted")] 20 | Deleted, 21 | [EnumMember(Value = "delivered")] 22 | Delivered, 23 | [EnumMember(Value = "failed")] 24 | Failed, 25 | [EnumMember(Value = "pending")] 26 | Pending, 27 | [EnumMember(Value = "read")] 28 | Read, 29 | [EnumMember(Value = "received")] 30 | Received, 31 | [EnumMember(Value = "sent")] 32 | Sent, 33 | [EnumMember(Value = "unsupported")] 34 | Unsupported, 35 | [EnumMember(Value = "rejected")] 36 | Rejected, 37 | } 38 | 39 | public class ConversationMessageError 40 | { 41 | [JsonProperty("code")] 42 | public int Code { get; set; } 43 | [JsonProperty("description")] 44 | public string Description { get; set; } 45 | } 46 | 47 | public class ConversationMessage : IIdentifiable 48 | { 49 | [JsonProperty("id")] 50 | public string Id { get; set; } 51 | 52 | [JsonProperty("conversationId")] 53 | public string ConversationId { get; set; } 54 | 55 | [JsonProperty("channelId")] 56 | public string ChannelId { get; set; } 57 | 58 | [JsonProperty("direction"), JsonConverter(typeof(StringEnumConverter))] 59 | public ConversationMessageDirection Direction {get; set;} 60 | 61 | [JsonProperty("status"), JsonConverter(typeof(StringEnumConverter))] 62 | public ConversationMessageStatus Status {get; set;} 63 | 64 | [JsonProperty("type"), JsonConverter(typeof(StringEnumConverter))] 65 | public ContentType Type {get; set;} 66 | 67 | [JsonProperty("content")] 68 | public Content Content {get; set;} 69 | 70 | [JsonProperty("error")] 71 | public ConversationMessageError Error { get; set; } 72 | 73 | [JsonProperty("createdDatetime")] 74 | public DateTime? CreatedDatetime {get; set;} 75 | 76 | [JsonProperty("updatedDatetime")] 77 | public DateTime? UpdatedDatetime {get; set;} 78 | } 79 | } -------------------------------------------------------------------------------- /MessageBird/Json/Converters/RecipientsConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | using MessageBird.Objects; 5 | 6 | namespace MessageBird.Json.Converters 7 | { 8 | class RecipientsConverter : JsonConverter 9 | { 10 | /* 11 | * When serializing, the recipients list, by default, will be serialized as an array msisdns. 12 | * However, in some use cases we want to pass the recipients object as is in json. 13 | * To choose how we serialize the recipients, we check the SerializeMsisdnsOnly property of the 14 | * recipients object. 15 | */ 16 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 17 | { 18 | var recipients = value as Recipients; 19 | 20 | if (recipients == null) 21 | { 22 | writer.WriteNull(); 23 | return; 24 | } 25 | 26 | if (recipients.SerializeMsisdnsOnly) 27 | { 28 | writer.WriteStartArray(); 29 | foreach (Recipient recipient in recipients.Items) 30 | { 31 | serializer.Serialize(writer, recipient.Msisdn); 32 | } 33 | writer.WriteEndArray(); 34 | } 35 | else 36 | { 37 | serializer.Serialize(writer, recipients); 38 | } 39 | } 40 | 41 | 42 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 43 | { 44 | // The MessageBird endpoint will always send a recipients object. 45 | // However, when deserializing a serialized object with recipients we have to take into consideration 46 | // the two ways a recipients object can serialize. 47 | // See the WriteJson method for more information. 48 | if (reader.TokenType == JsonToken.StartArray) 49 | { 50 | var msisdns = serializer.Deserialize>(reader); 51 | return new Recipients(msisdns); 52 | } 53 | if (reader.TokenType == JsonToken.StartObject) 54 | { 55 | return serializer.Deserialize(reader); 56 | } 57 | throw new JsonSerializationException(String.Format("Unexpected token '{0}' when parsing recipients.", reader.TokenType)); 58 | } 59 | 60 | 61 | public override bool CanConvert(Type objectType) 62 | { 63 | return typeof(Recipients).IsAssignableFrom(objectType); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MessageBird/Net/HttpStatusCode.cs: -------------------------------------------------------------------------------- 1 | namespace MessageBird.Net 2 | { 3 | // A more complete list of http status codes from http://httpstatus.es/ 4 | public enum HttpStatusCode 5 | { 6 | // 1xx informational 7 | Continue = 100, 8 | SwitchingProtocols = 101, 9 | Processing = 102, 10 | Checkpoint = 103, 11 | MaximumRequestUri = 122, 12 | 13 | // 2xx success 14 | OK = 200, 15 | Created = 201, 16 | Accepted = 202, 17 | NonAuthoritativeInformation = 203, 18 | NoContent = 204, 19 | ResetContent = 205, 20 | PartialContent = 206, 21 | MultiStatus = 207, 22 | AlreadyReported = 208, 23 | IMUsed = 226, 24 | 25 | // 3xx redirection 26 | MultipleChoices = 300, 27 | MovedPermanently = 301, 28 | Found = 302, 29 | SeeOther = 303, 30 | NotModified = 304, 31 | UseProxy = 305, 32 | SwitchProxy = 306, 33 | TemporaryRedirect = 307, 34 | PermanentRedirect = 308, 35 | 36 | // 4xx client error 37 | BadRequest = 400, 38 | Unauthorized = 401, 39 | PaymentRequired = 402, 40 | Forbidden = 403, 41 | NotFound = 404, 42 | MethodNotAllowed = 405, 43 | NotAcceptable = 406, 44 | ProxyAuthenticationRequired = 407, 45 | RequestTimeout = 408, 46 | Conflict = 409, 47 | Gone = 410, 48 | LengthRequired = 411, 49 | PreconditionFailed = 412, 50 | RequestEntityTooLarge = 413, 51 | RequestUriTooLong = 414, 52 | UnsupportedMediaType = 415, 53 | RequestRangeNotSatisfiable = 416, 54 | ExpectationFailed = 417, 55 | IamATeapot = 418, 56 | EnhanceYourCalm = 420, 57 | UnprocessableEntity = 422, 58 | Locked = 423, 59 | FailedDependency = 424, 60 | UpgradeRequired = 426, 61 | PreconditionRequired = 428, 62 | TooManyRequests = 429, 63 | RequestHeaderFieldsTooLarge = 431, 64 | NoResponse = 444, 65 | RetryWith = 449, 66 | BlockedByWindowsParentalControls = 450, 67 | WrongExchangeServer = 451, 68 | ClientClosedRequest = 499, 69 | 70 | // 5xx server errror 71 | InternalServerError = 500, 72 | NotImplemented = 501, 73 | BadGateway = 502, 74 | ServiceUnavailable = 503, 75 | GatewayTimeout = 504, 76 | HttpVersionNotSupported = 505, 77 | VariantAlsoNegotiates = 506, 78 | InsufficientStorage = 507, 79 | LoopDetected = 508, 80 | BandwidthLimitExceeded = 509, 81 | NotExtended = 510, 82 | NetworkAuthenticationRequired = 511, 83 | NetworkReadTimeoutError = 598, 84 | NetworkConnectTimeoutError = 599 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /MessageBird/Resources/Resource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using MessageBird.Exceptions; 3 | using MessageBird.Net; 4 | using MessageBird.Objects; 5 | using Newtonsoft.Json; 6 | 7 | namespace MessageBird.Resources 8 | { 9 | public abstract class Resource 10 | { 11 | public static string ConverstationsBaseUrl = "https://conversations.messagebird.com/v1"; 12 | public static string DefaultBaseUrl = "https://rest.messagebird.com"; 13 | 14 | public string Id 15 | { 16 | get 17 | { 18 | if (HasId) 19 | { 20 | return Object.Id; 21 | } 22 | throw new ErrorException(String.Format("Resource {0} has no id", Name)); 23 | } 24 | } 25 | 26 | public IIdentifiable Object { get; protected set; } 27 | 28 | public bool HasId 29 | { 30 | get { return (Object != null) && !String.IsNullOrEmpty(Object.Id); } 31 | } 32 | 33 | public string Name { get; private set; } 34 | 35 | public virtual void Deserialize(string resource) 36 | { 37 | if (Object == null) 38 | { 39 | throw new ErrorException("Invalid resource, has no attached object", new NullReferenceException()); 40 | } 41 | 42 | try 43 | { 44 | JsonConvert.PopulateObject(resource, Object); 45 | } 46 | catch (JsonSerializationException e) 47 | { 48 | throw new ErrorException("Received response in an unexpected format!", e); 49 | } 50 | } 51 | 52 | public virtual string Serialize() 53 | { 54 | var settings = new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore}; 55 | return JsonConvert.SerializeObject(Object, settings); 56 | } 57 | 58 | protected Resource(string name, IIdentifiable attachedObject) 59 | { 60 | Name = name; 61 | Object = attachedObject; 62 | } 63 | 64 | public virtual string Uri 65 | { 66 | get 67 | { 68 | return HasId ? String.Format("{0}/{1}", Name, Id) : Name; 69 | } 70 | } 71 | 72 | public virtual string QueryString 73 | { 74 | get 75 | { 76 | return String.Empty; 77 | } 78 | } 79 | 80 | public bool HasQueryString 81 | { 82 | get 83 | { 84 | return QueryString.Length > 0; 85 | } 86 | } 87 | 88 | public virtual string BaseUrl 89 | { 90 | get { return DefaultBaseUrl; } 91 | } 92 | 93 | public virtual UpdateMode UpdateMode 94 | { 95 | get { return UpdateMode.Put; } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /MessageBird/Utilities/Validation.cs: -------------------------------------------------------------------------------- 1 | using MessageBird.Objects; 2 | using System; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace MessageBird.Utilities 6 | { 7 | public class ParameterValidator 8 | { 9 | public static void IsNotNullOrWhiteSpace(string param, string paramName) 10 | { 11 | if (String.IsNullOrWhiteSpace(param)) 12 | { 13 | throw new ArgumentException("Invalid string parameter, cannot be null, empty, or contain only whitespace", paramName); 14 | } 15 | } 16 | 17 | public static void IsNotNull(object param, string paramName) 18 | { 19 | if (param == null) 20 | { 21 | throw new ArgumentNullException(paramName); 22 | } 23 | } 24 | 25 | public static void ContainsAtLeast(T [] param, int n, string paramName) 26 | { 27 | if (n < 0) 28 | { 29 | throw new ArgumentOutOfRangeException("n"); 30 | } 31 | 32 | if (param == null) 33 | { 34 | throw new ArgumentNullException(paramName); 35 | } 36 | 37 | if (param.Length < n) 38 | { 39 | throw new ArgumentException(String.Format("The array contains {0} elements, but at least {1} were expected", param.Length, n), paramName); 40 | } 41 | } 42 | 43 | public static void IsValidMessageType(MessageType messagetype) 44 | { 45 | if(messagetype == MessageType.Tts) 46 | { 47 | throw new ArgumentException(String.Format("Messagetype not supported : {0}", messagetype)); 48 | } 49 | 50 | } 51 | 52 | public static void IsValidOriginator(string originator) 53 | { 54 | const int ORIGINATOR_ALPHANUMERIC_MAXLENGTH = 11; 55 | 56 | //https://developers.messagebird.com/docs/messaging 57 | //ORIGINATOR The sender of the message.This can be a telephone number (including country code) or an alphanumeric string. 58 | //In case of an alphanumeric string, the maximum length is 11 characters. 59 | 60 | if (!string.IsNullOrEmpty(originator)) 61 | { 62 | var numeric = new Regex("^\\+?[0-9]+$"); 63 | var alphanumericWithWhitespace = new Regex("^[A-Za-z0-9]+(?:\\s[A-Za-z0-9]+)*$"); 64 | var isNumeric = numeric.IsMatch(originator); 65 | var isAlphanumericWithWhitespace = alphanumericWithWhitespace.IsMatch(originator); 66 | var email = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"); 67 | var isEmail = email.IsMatch(originator); 68 | 69 | if (!isNumeric && !isAlphanumericWithWhitespace && !isEmail) 70 | { 71 | throw new ArgumentException("Originator can only contain numeric or whitespace separated alphanumeric characters."); 72 | } 73 | 74 | if (!isNumeric && isAlphanumericWithWhitespace && originator.Length > ORIGINATOR_ALPHANUMERIC_MAXLENGTH) 75 | { 76 | throw new ArgumentException(string.Format("Alphanumeric originator is limited to {0} characters.", ORIGINATOR_ALPHANUMERIC_MAXLENGTH)); 77 | } 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /Tests/MessageBird.Tests/Responses/ConversationList.json: -------------------------------------------------------------------------------- 1 | { 2 | "offset": 0, 3 | "limit": 20, 4 | "count": 2, 5 | "totalCount": 2, 6 | "items": [ 7 | { 8 | "id": "fbbdde79129f45e3a179458a91e2ead6", 9 | "contactId": "03dfc27855c3475b953d6200a1b7eaf7", 10 | "contact": { 11 | "id": "03dfc27855c3475b953d6200a1b7eaf7", 12 | "href": "https://rest.messagebird.com/contacts/03dfc27855c3475b953d6200a1b7eaf7", 13 | "msisdn": 31612345678, 14 | "firstName": "John", 15 | "lastName": "Doe", 16 | "customDetails": { 17 | "custom1": null, 18 | "custom2": null, 19 | "custom3": null, 20 | "custom4": null 21 | }, 22 | "createdDatetime": "2018-08-01T09:45:52Z", 23 | "updatedDatetime": "2018-08-28T12:37:35Z" 24 | }, 25 | "channels": [ 26 | { 27 | "id": "619747f69cf940a98fb443140ce9aed2", 28 | "name": "My WhatsApp", 29 | "platformId": "whatsapp", 30 | "status": "active", 31 | "createdDatetime": "2018-08-28T11:56:57Z", 32 | "updatedDatetime": "2018-08-29T08:16:33Z" 33 | }, 34 | ], 35 | "status": "active", 36 | "createdDatetime": "2018-08-29T08:52:54Z", 37 | "updatedDatetime": "2018-08-29T08:52:54Z", 38 | "lastReceivedDatetime": "2018-08-29T08:52:54Z", 39 | "lastUsedChannelId": "619747f69cf940a98fb443140ce9aed2", 40 | "messages": { 41 | "totalCount": 10, 42 | "href": "https://conversations.messagebird.com/v1/conversations/fbbdde79129f45e3a179458a91e2ead6/messages" 43 | } 44 | }, 45 | { 46 | "id": "2e15efafec384e1c82e9842075e87beb", 47 | "contactId": "a621095fa44947a28b441cfdf85cb802", 48 | "contact": { 49 | "id": "a621095fa44947a28b441cfdf85cb802", 50 | "href": "https://rest.messagebird.com/1/contacts/a621095fa44947a28b441cfdf85cb802", 51 | "msisdn": 316123456789, 52 | "firstName": "Jen", 53 | "lastName": "Smith", 54 | "customDetails": { 55 | "custom1": null, 56 | "custom2": null, 57 | "custom3": null, 58 | "custom4": null 59 | }, 60 | "createdDatetime": "2018-06-03T20:06:03Z", 61 | "updatedDatetime": null 62 | }, 63 | "channels": [ 64 | { 65 | "id": "853eeb5348e541a595da93b48c61a1ae", 66 | "name": "SMS", 67 | "platformId": "sms", 68 | "status": "active", 69 | "createdDatetime": "2018-08-28T11:56:57Z", 70 | "updatedDatetime": "2018-08-29T08:16:33Z" 71 | }, 72 | { 73 | "id": "619747f69cf940a98fb443140ce9aed2", 74 | "name": "My WhatsApp", 75 | "platformId": "whatsapp", 76 | "status": "active", 77 | "createdDatetime": "2018-08-28T11:56:57Z", 78 | "updatedDatetime": "2018-08-29T08:16:33Z" 79 | } 80 | ], 81 | "status": "active", 82 | "createdDatetime": "2018-08-13T09:17:22Z", 83 | "updatedDatetime": "2018-08-29T07:35:48Z", 84 | "lastReceivedDatetime": "2018-08-29T07:35:48Z", 85 | "lastUsedChannelId": "853eeb5348e541a595da93b48c61a1ae", 86 | "messages": { 87 | "totalCount": 23, 88 | "href": "https://conversations.messagebird.com/v1/conversations/2e15efafec384e1c82e9842075e87beb/messages" 89 | } 90 | }, 91 | ] 92 | } -------------------------------------------------------------------------------- /MessageBird/Objects/Lookup.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using Newtonsoft.Json.Converters; 3 | using System.Runtime.Serialization; 4 | using System; 5 | 6 | namespace MessageBird.Objects 7 | { 8 | public enum PhoneNumberType 9 | { 10 | [EnumMember(Value = "fixed line")] 11 | FixedLine, 12 | [EnumMember(Value = "mobile")] 13 | Mobile, 14 | [EnumMember(Value = "fixed line or mobile")] 15 | FixedLineOrMobile, 16 | [EnumMember(Value = "toll free")] 17 | TollFree, 18 | [EnumMember(Value = "premium rate")] 19 | PremiumRate, 20 | [EnumMember(Value = "shared cost")] 21 | SharedCost, 22 | [EnumMember(Value = "voip")] 23 | Voip, 24 | [EnumMember(Value = "personal number")] 25 | PersonalNumber, 26 | [EnumMember(Value = "pager")] 27 | Pager, 28 | [EnumMember(Value = "universal access number")] 29 | UniversalAccessNumber, 30 | [EnumMember(Value = "voice mail")] 31 | VoiceMail, 32 | [EnumMember(Value = "unknown")] 33 | Unknown 34 | }; 35 | 36 | public class LookupOptionalArguments 37 | { 38 | public string CountryCode { get; set; } 39 | } 40 | 41 | public class Lookup : IIdentifiable 42 | { 43 | /// 44 | /// To uniformly treat objects, we implement the IIdentifiable interface even though 45 | /// a Lookup object doesn't have an id! 46 | /// By returning null, the Lookup object signals the user of a Lookup object 47 | /// (currently always the Lookup resource) to ignore the id property. 48 | /// 49 | /// Throwing an exception will interfere with serialization of a Lookup object. 50 | public string Id 51 | { 52 | get 53 | { 54 | return null; 55 | } 56 | } 57 | 58 | [JsonProperty("href")] 59 | public string Href { get; set; } 60 | 61 | [JsonProperty("countryCode")] 62 | public string CountryCode { get; private set; } 63 | 64 | [JsonProperty("countryPrefix")] 65 | public int CountryPrefix { get; set; } 66 | 67 | [JsonProperty("phoneNumber")] 68 | public long PhoneNumber { get; set; } 69 | 70 | [JsonProperty("type"), JsonConverter(typeof(StringEnumConverter))] 71 | public PhoneNumberType Type { get; set; } 72 | 73 | [JsonProperty("formats")] 74 | public Formats Formats { get; set; } 75 | 76 | [JsonProperty("hlr")] 77 | public Hlr Hlr { get; set; } 78 | 79 | public Lookup() 80 | { 81 | } 82 | 83 | public Lookup(long phoneNumber) 84 | { 85 | PhoneNumber = phoneNumber; 86 | } 87 | 88 | public Lookup(long phoneNumber, LookupOptionalArguments optionalArguments = null) 89 | { 90 | PhoneNumber = phoneNumber; 91 | 92 | optionalArguments = optionalArguments ?? new LookupOptionalArguments(); 93 | 94 | CountryCode = optionalArguments.CountryCode; 95 | } 96 | 97 | public override string ToString() 98 | { 99 | return JsonConvert.SerializeObject(this, Formatting.Indented); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /MessageBird/Objects/Voice/CallFlow.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | 5 | namespace MessageBird.Objects.Voice 6 | { 7 | public class CallFlow : IIdentifiable 8 | { 9 | public CallFlow() 10 | { 11 | Steps = new List(); 12 | Record = null; 13 | } 14 | 15 | [JsonProperty("id")] 16 | public string Id { get; set; } 17 | 18 | [JsonProperty("title")] 19 | public string Title { get; set; } 20 | 21 | [JsonProperty("record")] 22 | public bool? Record { get; set; } 23 | 24 | [JsonProperty("steps")] 25 | public List Steps { get; set; } 26 | 27 | [JsonProperty("createdAt")] 28 | public DateTime? CreatedAt { get; set; } 29 | 30 | [JsonProperty("updatedAt")] 31 | public DateTime? UpdatedAt { get; set; } 32 | 33 | [JsonProperty("_links")] 34 | public Dictionary Links { get; set; } 35 | 36 | /// 37 | /// Requests to the Contacts API use a different format than responses. 38 | /// ToRequestObject gets a request object in the proper format. 39 | /// 40 | /// 41 | /// A request object that can be used for serializing. 42 | /// 43 | public RequestObject ToRequestObject() 44 | { 45 | return new RequestObject(this); 46 | } 47 | 48 | public override string ToString() 49 | { 50 | var requestObject = ToRequestObject(); 51 | 52 | return JsonConvert.SerializeObject(requestObject, Formatting.Indented); 53 | } 54 | 55 | /// 56 | /// Object that can be used for serializing to JSON when making 57 | /// requests. That requires having the custom details on the top-level 58 | /// object rather than nested, and Json.Net does not offer "flattened" 59 | /// objects out of the box. 60 | /// 61 | public class RequestObject 62 | { 63 | public RequestObject() 64 | { 65 | Steps=new List(); 66 | } 67 | 68 | [JsonProperty("id")] 69 | public string Id { get; set; } 70 | 71 | [JsonProperty("title")] 72 | public string Title { get; set; } 73 | 74 | [JsonProperty("record")] 75 | public bool? Record { get; set; } 76 | 77 | [JsonProperty("steps")] 78 | public List Steps { get; set; } 79 | 80 | [JsonProperty("_links")] 81 | public Dictionary Links { get; set; } 82 | 83 | public RequestObject(CallFlow callFlow) 84 | { 85 | Title = callFlow.Title; 86 | Record = callFlow.Record; 87 | Steps = callFlow.Steps; 88 | } 89 | } 90 | } 91 | 92 | public class CallFlowList : VoiceBaseList 93 | { 94 | } 95 | 96 | public class Options 97 | { 98 | [JsonProperty("destination")] 99 | public string Destination { get; set; } 100 | } 101 | 102 | public class Step 103 | { 104 | [JsonProperty("id")] 105 | public string Id { get; set; } 106 | 107 | [JsonProperty("action")] 108 | public string Action { get; set; } 109 | 110 | [JsonProperty("options")] 111 | public Options Options { get; set; } 112 | } 113 | } --------------------------------------------------------------------------------