Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/conversation contact #33

Merged
merged 18 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
- 6039:6039
- 6040:6040
- 6041:6041
- 6042:6042
- 6043:6043
- 6044:6044

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ Sinch client provides access to the following Sinch products:
- Numbers
- SMS
- Verification
- Voice
- Work-in-Progress Conversation

Usage example of the `numbers` product, assuming `sinch` is type of `SinchClient`:
Usage example of the `numbers` product, assuming `sinch` is a type of `ISinchClient`:

```csharp
using Sinch.Numbers.Active.List;
Expand Down
4 changes: 2 additions & 2 deletions src/Sinch/Conversation/Apps/Apps.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace Sinch.Conversation.Apps
/// for each underlying connected channel.
/// The app has a list of conversations between itself and different contacts which share the same project.
/// </summary>
public interface ISinchConversationApp
public interface ISinchConversationApps
{
/// <summary>
/// You can create a new Conversation API app using the API.
Expand Down Expand Up @@ -80,7 +80,7 @@ public interface ISinchConversationApp
Task<App> Update(string appId, UpdateAppRequest request, CancellationToken cancellationToken = default);
}

internal class Apps : ISinchConversationApp
internal class Apps : ISinchConversationApps
{
private readonly Uri _baseAddress;
private readonly IHttp _http;
Expand Down
166 changes: 166 additions & 0 deletions src/Sinch/Conversation/Contacts/Contact.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinch.Conversation.Messages;
using Sinch.Core;

namespace Sinch.Conversation.Contacts
{
public sealed class Contact
{
/// <summary>
/// Tracks the fields which where initialized.
/// </summary>
private readonly ISet<string> _setFields = new HashSet<string>();

private List<ChannelIdentity> _channelIdentities;
private List<ConversationChannel> _channelPriority;
private string _displayName;
private string _email;
private string _externalId;
private string _id;
private string _language;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From specs it is a dedicated schema and a (long) list of predefined values.
Ideally we should provide enums as helper ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, makes sense.
Side comment: did you enjoy working with enums of 20+ values?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No 😞
But from SDK user point of view and because not related to any ISO definition, we can just assuming providing list of supported values will be helpful

private string _metadata;

/// <summary>
/// List of channel identities.
/// </summary>
public List<ChannelIdentity> ChannelIdentities
{
get => _channelIdentities;
set
{
_setFields.Add(nameof(ChannelIdentities));
_channelIdentities = value;
}
}


/// <summary>
/// List of channels defining the channel priority.
/// </summary>
public List<ConversationChannel> ChannelPriority
{
get => _channelPriority;
set
{
_setFields.Add(nameof(ChannelPriority));
_channelPriority = value;
}
}


/// <summary>
/// The display name. A default &#39;Unknown&#39; will be assigned if left empty.
/// </summary>
public string DisplayName
{
get => _displayName;
set
{
_setFields.Add(nameof(DisplayName));
_displayName = value;
}
}


/// <summary>
/// Email of the contact.
/// </summary>
public string Email
{
get => _email;
set
{
_setFields.Add(nameof(Email));
_email = value;
}
}


/// <summary>
/// Contact identifier in an external system.
/// </summary>
public string ExternalId
{
get => _externalId;
set
{
_setFields.Add(nameof(ExternalId));
_externalId = value;
}
}


/// <summary>
/// The ID of the contact.
/// </summary>
public string Id
{
get => _id;
set
{
_setFields.Add(nameof(Id));
_id = value;
}
}


/// <summary>
/// Gets or Sets Language
/// </summary>
public string Language
{
get => _language;
set
{
_setFields.Add(nameof(Language));
_language = value;
}
}


/// <summary>
/// Metadata associated with the contact. Up to 1024 characters long.
/// </summary>
public string Metadata
{
get => _metadata;
set
{
_setFields.Add(nameof(Metadata));
_metadata = value;
}
}

/// <summary>
/// Get the comma separated snake_case list of properties which were directly initialized in this object.
/// If, for example, DisplayName and Metadata were set, will return <example>display_name,metadata</example>
/// </summary>
/// <returns></returns>
internal string GetPropertiesMask()
{
return string.Join(',', _setFields.Select(StringUtils.ToSnakeCase));
Copy link

@JPPortier JPPortier Jan 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally this logic could be dynamic and dependent of OAS description based onto style and explode specs.
This, to avoid hard coded logic here and logic/helper shared across domains

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, why to avoid makes sense but how, you mean add helpers for that?
I had an idea for that but in a other task where i see the pattern

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, okay, I'll refactor in other task

}

/// <summary>
/// Returns the string presentation of the object
/// </summary>
/// <returns>String presentation of the object</returns>
public override string ToString()
{
var sb = new StringBuilder();
sb.Append("class Contact {\n");
sb.Append(" ChannelIdentities: ").Append(ChannelIdentities).Append("\n");
sb.Append(" ChannelPriority: ").Append(ChannelPriority).Append("\n");
sb.Append(" DisplayName: ").Append(DisplayName).Append("\n");
sb.Append(" Email: ").Append(Email).Append("\n");
sb.Append(" ExternalId: ").Append(ExternalId).Append("\n");
sb.Append(" Id: ").Append(Id).Append("\n");
sb.Append(" Language: ").Append(Language).Append("\n");
sb.Append(" Metadata: ").Append(Metadata).Append("\n");
sb.Append("}\n");
return sb.ToString();
}
}
}
Loading