diff --git a/SlackAPI.sln b/SlackAPI.sln index f3b012b..f3f74ac 100644 --- a/SlackAPI.sln +++ b/SlackAPI.sln @@ -1,20 +1,20 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26228.4 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30320.27 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlackAPI", "SlackAPI\SlackAPI.csproj", "{7EED3D9B-9B7A-49A4-AFBF-599153A47DDA}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SlackAPI.Tests", "SlackAPI.Tests\SlackAPI.Tests.csproj", "{DEFA9559-0F8F-4C38-9644-67A080EDC46D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution items", "Solution items", "{532C9828-A2CC-4281-950A-248B06D42E9C}" -ProjectSection(SolutionItems) = preProject - appveyor.yml = appveyor.yml - build.cake = build.cake - Directory.Build.props = Directory.Build.props - GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs - README.md = README.md -EndProjectSection + ProjectSection(SolutionItems) = preProject + appveyor.yml = appveyor.yml + build.cake = build.cake + Directory.Build.props = Directory.Build.props + GlobalAssemblyInfo.cs = GlobalAssemblyInfo.cs + README.md = README.md + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/SlackAPI/Conversation.cs b/SlackAPI/Conversation.cs index def8d1a..c95281e 100644 --- a/SlackAPI/Conversation.cs +++ b/SlackAPI/Conversation.cs @@ -6,14 +6,46 @@ namespace SlackAPI { - public class Conversation - { - public string id; - public DateTime created; - public DateTime last_read; - public bool is_open; - public bool is_starred; - public int unread_count; - public Message latest; - } + public class Conversation + { + public string id; + public DateTime created; + public DateTime last_read; + public bool is_open; + public bool is_starred; + public int unread_count; + public Message latest; + + public static string ConversationTypesToQueryParam(ConversationTypes[] types) + { + //Translate the enum user-friendly names to API used names + List typesAsString = new List(); + if (types.Contains(ConversationTypes.PublicChannel)) + { + typesAsString.Add("public_channel"); + } + if (types.Contains(ConversationTypes.PrivateChannel)) + { + typesAsString.Add("private_channel"); + } + if (types.Contains(ConversationTypes.GroupMessage)) + { + typesAsString.Add("mpim"); + } + if (types.Contains(ConversationTypes.DirectMessage)) + { + typesAsString.Add("im"); + } + + return string.Join(",", types); + } + } + + public enum ConversationTypes + { + PublicChannel, //public_channel + PrivateChannel, //private_channel + GroupMessage, //mpim + DirectMessage //im + } } diff --git a/SlackAPI/RPCMessages/ConversationsListResponse.cs b/SlackAPI/RPCMessages/ConversationsListResponse.cs new file mode 100644 index 0000000..005938f --- /dev/null +++ b/SlackAPI/RPCMessages/ConversationsListResponse.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace SlackAPI.RPCMessages +{ + [RequestPath("conversations.list")] + public class ConversationsListResponse : Response + { + public Channel[] channels; + } +} diff --git a/SlackAPI/Response.cs b/SlackAPI/Response.cs index cff403b..339bc0b 100644 --- a/SlackAPI/Response.cs +++ b/SlackAPI/Response.cs @@ -25,5 +25,12 @@ public void AssertOk() if (!(ok)) throw new InvalidOperationException(string.Format("An error occurred: {0}", this.error)); } + + public ResponseMetaData response_metadata; + } + + public class ResponseMetaData + { + public string next_cursor; } } diff --git a/SlackAPI/SlackClient.cs b/SlackAPI/SlackClient.cs index d0fbcbc..52f52c8 100644 --- a/SlackAPI/SlackClient.cs +++ b/SlackAPI/SlackClient.cs @@ -10,718 +10,754 @@ namespace SlackAPI { - /// - /// SlackClient is intended to solely handle RPC (HTTP-based) functionality. Does not handle WebSocket connectivity. - /// - /// For WebSocket connectivity, refer to - /// - public class SlackClient : SlackClientBase - { - private readonly string APIToken; - - public Self MySelf; - public User MyData; - public Team MyTeam; - - public List starredChannels; - - public List Users; - public List Bots; - public List Channels; - public List Groups; - public List DirectMessages; - - public Dictionary UserLookup; - public Dictionary ChannelLookup; - public Dictionary GroupLookup; - public Dictionary DirectMessageLookup; - public Dictionary ConversationLookup; - - public SlackClient(string token) - { - APIToken = token; - } - - public SlackClient(string token, IWebProxy proxySettings) - : base(proxySettings) - { - APIToken = token; - } + /// + /// SlackClient is intended to solely handle RPC (HTTP-based) functionality. Does not handle WebSocket connectivity. + /// + /// For WebSocket connectivity, refer to + /// + public class SlackClient : SlackClientBase + { + private readonly string APIToken; + + public Self MySelf; + public User MyData; + public Team MyTeam; + + public List starredChannels; + public List Users; + public List Bots; + public List Channels; + public List Groups; + public List DirectMessages; + + public Dictionary UserLookup; + public Dictionary ChannelLookup; + public Dictionary GroupLookup; + public Dictionary DirectMessageLookup; + public Dictionary ConversationLookup; + + public SlackClient(string token) + { + APIToken = token; + } + + public SlackClient(string token, IWebProxy proxySettings) + : base(proxySettings) + { + APIToken = token; + } public virtual void Connect(Action onConnected = null, Action onSocketConnected = null) - { - EmitLogin((loginDetails) => - { - if (loginDetails.ok) - Connected(loginDetails); - - if (onConnected != null) - onConnected(loginDetails); - }); - } - - protected virtual void Connected(LoginResponse loginDetails) - { - MySelf = loginDetails.self; - MyData = loginDetails.users.First((c) => c.id == MySelf.id); - MyTeam = loginDetails.team; - - Users = new List(loginDetails.users.Where((c) => !c.deleted)); - Bots = new List(loginDetails.bots.Where((c) => !c.deleted)); - Channels = new List(loginDetails.channels); - Groups = new List(loginDetails.groups); - DirectMessages = new List(loginDetails.ims.Where((c) => Users.Exists((a) => a.id == c.user) && c.id != MySelf.id)); - starredChannels = - Groups.Where((c) => c.is_starred).Select((c) => c.id) - .Union( - DirectMessages.Where((c) => c.is_starred).Select((c) => c.user) - ).Union( - Channels.Where((c) => c.is_starred).Select((c) => c.id) - ).ToList(); - - UserLookup = new Dictionary(); - foreach (User u in Users) UserLookup.Add(u.id, u); - - ChannelLookup = new Dictionary(); - ConversationLookup = new Dictionary(); - foreach (Channel c in Channels) - { - ChannelLookup.Add(c.id, c); - ConversationLookup.Add(c.id, c); - } - - GroupLookup = new Dictionary(); - foreach (Channel g in Groups) - { - GroupLookup.Add(g.id, g); - ConversationLookup.Add(g.id, g); - } - - DirectMessageLookup = new Dictionary(); - foreach (DirectMessageConversation im in DirectMessages) - { - DirectMessageLookup.Add(im.id, im); - ConversationLookup.Add(im.id, im); - } - } - - public void APIRequestWithToken(Action callback, params Tuple[] getParameters) - where K : Response - { - Tuple[] tokenArray = new Tuple[]{ - new Tuple("token", APIToken) - }; - - if (getParameters != null && getParameters.Length > 0) - tokenArray = tokenArray.Concat(getParameters).ToArray(); - - APIRequest(callback, tokenArray, new Tuple[0]); - } - - public void TestAuth(Action callback) - { - APIRequestWithToken(callback); - } - - public void GetUserList(Action callback) - { - APIRequestWithToken(callback); - } - - public void GetUserByEmail(Action callback, string email) - { - APIRequestWithToken(callback, new Tuple("email", email)); - } - - public void ChannelsCreate(Action callback, string name) { + { + EmitLogin((loginDetails) => + { + if (loginDetails.ok) + Connected(loginDetails); + + if (onConnected != null) + onConnected(loginDetails); + }); + } + + protected virtual void Connected(LoginResponse loginDetails) + { + MySelf = loginDetails.self; + MyData = loginDetails.users.First((c) => c.id == MySelf.id); + MyTeam = loginDetails.team; + + Users = new List(loginDetails.users.Where((c) => !c.deleted)); + Bots = new List(loginDetails.bots.Where((c) => !c.deleted)); + Channels = new List(loginDetails.channels); + Groups = new List(loginDetails.groups); + DirectMessages = new List(loginDetails.ims.Where((c) => Users.Exists((a) => a.id == c.user) && c.id != MySelf.id)); + starredChannels = + Groups.Where((c) => c.is_starred).Select((c) => c.id) + .Union( + DirectMessages.Where((c) => c.is_starred).Select((c) => c.user) + ).Union( + Channels.Where((c) => c.is_starred).Select((c) => c.id) + ).ToList(); + + UserLookup = new Dictionary(); + foreach (User u in Users) UserLookup.Add(u.id, u); + + ChannelLookup = new Dictionary(); + ConversationLookup = new Dictionary(); + foreach (Channel c in Channels) + { + ChannelLookup.Add(c.id, c); + ConversationLookup.Add(c.id, c); + } + + GroupLookup = new Dictionary(); + foreach (Channel g in Groups) + { + GroupLookup.Add(g.id, g); + ConversationLookup.Add(g.id, g); + } + + DirectMessageLookup = new Dictionary(); + foreach (DirectMessageConversation im in DirectMessages) + { + DirectMessageLookup.Add(im.id, im); + ConversationLookup.Add(im.id, im); + } + } + + public void APIRequestWithToken(Action callback, params Tuple[] getParameters) + where K : Response + { + Tuple[] tokenArray = new Tuple[]{ + new Tuple("token", APIToken) + }; + + if (getParameters != null && getParameters.Length > 0) + tokenArray = tokenArray.Concat(getParameters).ToArray(); + + APIRequest(callback, tokenArray, new Tuple[0]); + } + + public void TestAuth(Action callback) + { + APIRequestWithToken(callback); + } + + #region Channels + + public void ChannelsCreate(Action callback, string name) + { APIRequestWithToken(callback, new Tuple("name", name)); } - public void ChannelsInvite(Action callback, string userId, string channelId) - { - List> parameters = new List>(); + public void ChannelsInvite(Action callback, string userId, string channelId) + { + List> parameters = new List>(); - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("user", userId)); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); - APIRequestWithToken(callback, parameters.ToArray()); - } - - public void GetChannelList(Action callback, bool ExcludeArchived = true) - { - APIRequestWithToken(callback, new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); - } - - public void GetGroupsList(Action callback, bool ExcludeArchived = true) - { - APIRequestWithToken(callback, new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); - } + APIRequestWithToken(callback, parameters.ToArray()); + } - public void GetDirectMessageList(Action callback) - { - APIRequestWithToken(callback); - } + public void GetChannelList(Action callback, bool ExcludeArchived = true) + { + APIRequestWithToken(callback, new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); + } - public void GetFiles(Action callback, string userId = null, DateTime? from = null, DateTime? to = null, int? count = null, int? page = null, FileTypes types = FileTypes.all, string channel = null) - { - List> parameters = new List>(); + public void GetChannelHistory(Action callback, Channel channelInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + GetHistory(callback, channelInfo.id, latest, oldest, count, unreads); + } - if (!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); - - if (from.HasValue) - parameters.Add(new Tuple("ts_from", from.Value.ToProperTimeStamp())); - - if (to.HasValue) - parameters.Add(new Tuple("ts_to", to.Value.ToProperTimeStamp())); - - if (!types.HasFlag(FileTypes.all)) - { - FileTypes[] values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); - - StringBuilder building = new StringBuilder(); - bool first = true; - for (int i = 0; i < values.Length; ++i) - { - if (types.HasFlag(values[i])) - { - if (!first) building.Append(","); - - building.Append(values[i].ToString()); - - first = false; - } - } - - if (building.Length > 0) - parameters.Add(new Tuple("types", building.ToString())); - } - - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); - - if (!string.IsNullOrEmpty(channel)) - parameters.Add(new Tuple("channel", channel)); + public void MarkChannel(Action callback, string channelId, DateTime ts) + { + APIRequestWithToken(callback, + new Tuple("channel", channelId), + new Tuple("ts", ts.ToProperTimeStamp()) + ); + } - APIRequestWithToken(callback, parameters.ToArray()); - } - - void GetHistory(Action historyCallback, string channel, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - where K : MessageHistory - { - List> parameters = new List>(); - parameters.Add(new Tuple("channel", channel)); - - if(latest.HasValue) - parameters.Add(new Tuple("latest", latest.Value.ToProperTimeStamp())); - if(oldest.HasValue) - parameters.Add(new Tuple("oldest", oldest.Value.ToProperTimeStamp())); - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - if (unreads.HasValue) - parameters.Add(new Tuple("unreads", unreads.Value ? "1" : "0")); - - APIRequestWithToken(historyCallback, parameters.ToArray()); - } - - public void GetChannelHistory(Action callback, Channel channelInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - { - GetHistory(callback, channelInfo.id, latest, oldest, count, unreads); - } - - public void GetDirectMessageHistory(Action callback, DirectMessageConversation conversationInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - { - GetHistory(callback, conversationInfo.id, latest, oldest, count, unreads); - } - - public void GetGroupHistory(Action callback, Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - { - GetHistory(callback, groupInfo.id, latest, oldest, count, unreads); - } - - public void MarkChannel(Action callback, string channelId, DateTime ts) - { - APIRequestWithToken(callback, - new Tuple("channel", channelId), - new Tuple("ts", ts.ToProperTimeStamp()) - ); - } - - public void GetFileInfo(Action callback, string fileId, int? page = null, int? count = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("file", fileId)); - - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + #endregion - APIRequestWithToken(callback, parameters.ToArray()); - } - #region Groups - public void GroupsArchive(Action callback, string channelId) - { - APIRequestWithToken(callback, new Tuple("channel", channelId)); - } - - public void GroupsClose(Action callback, string channelId) - { - APIRequestWithToken(callback, new Tuple("channel", channelId)); - } + #region Conversations - public void GroupsCreate(Action callback, string name) - { - APIRequestWithToken(callback, new Tuple("name", name)); - } + public void GetConversationsList(Action callback, string cursor = "", bool ExcludeArchived = true, int limit = 100, ConversationTypes[] types = null) + { + List> parameters = new List>() + { + Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") + }; + if (limit > 0) + Tuple.Create("limit", limit.ToString()); + if (types != null && types.Any()) + Tuple.Create("types", Conversation.ConversationTypesToQueryParam(types)); + if (!string.IsNullOrEmpty(cursor)) + parameters.Add(new Tuple("cursor", cursor)); - public void GroupsCreateChild(Action callback, string channelId) - { - APIRequestWithToken(callback, new Tuple("channel", channelId)); - } + APIRequestWithToken(callback, parameters.ToArray()); + } - public void GroupsInvite(Action callback, string userId, string channelId) - { - List> parameters = new List>(); + #endregion - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("user", userId)); + #region Groups - APIRequestWithToken(callback, parameters.ToArray()); - } + public void GetGroupsList(Action callback, bool ExcludeArchived = true) + { + APIRequestWithToken(callback, new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); + } - public void GroupsKick(Action callback, string userId, string channelId) - { - List> parameters = new List>(); + public void GroupsArchive(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("user", userId)); + public void GroupsClose(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } - APIRequestWithToken(callback, parameters.ToArray()); - } + public void GroupsCreate(Action callback, string name) + { + APIRequestWithToken(callback, new Tuple("name", name)); + } - public void GroupsLeave(Action callback, string channelId) - { - APIRequestWithToken(callback, new Tuple("channel", channelId)); - } + public void GroupsCreateChild(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } - public void GroupsMark(Action callback, string channelId, DateTime ts) - { - APIRequestWithToken(callback, new Tuple("channel", channelId), new Tuple("ts", ts.ToProperTimeStamp())); - } + public void GroupsInvite(Action callback, string userId, string channelId) + { + List> parameters = new List>(); - public void GroupsOpen(Action callback, string channelId) - { - APIRequestWithToken(callback, new Tuple("channel", channelId)); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); - public void GroupsRename(Action callback, string channelId, string name) - { - List> parameters = new List>(); + APIRequestWithToken(callback, parameters.ToArray()); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("name", name)); + public void GroupsKick(Action callback, string userId, string channelId) + { + List> parameters = new List>(); - APIRequestWithToken(callback, parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); - public void GroupsSetPurpose(Action callback, string channelId, string purpose) - { - List> parameters = new List>(); + APIRequestWithToken(callback, parameters.ToArray()); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("purpose", purpose)); + public void GroupsLeave(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } - APIRequestWithToken(callback, parameters.ToArray()); - } + public void GroupsMark(Action callback, string channelId, DateTime ts) + { + APIRequestWithToken(callback, new Tuple("channel", channelId), new Tuple("ts", ts.ToProperTimeStamp())); + } - public void GroupsSetTopic(Action callback, string channelId, string topic) - { - List> parameters = new List>(); + public void GroupsOpen(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("topic", topic)); + public void GroupsRename(Action callback, string channelId, string name) + { + List> parameters = new List>(); - APIRequestWithToken(callback, parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("name", name)); - public void GroupsUnarchive(Action callback, string channelId) - { - APIRequestWithToken(callback, new Tuple("channel", channelId)); - } + APIRequestWithToken(callback, parameters.ToArray()); + } - #endregion + public void GroupsSetPurpose(Action callback, string channelId, string purpose) + { + List> parameters = new List>(); - public void SearchAll(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) - { - List> parameters = new List>(); - parameters.Add(new Tuple("query", query)); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("purpose", purpose)); - if (sorting != null) - parameters.Add(new Tuple("sort", sorting)); + APIRequestWithToken(callback, parameters.ToArray()); + } - if (direction.HasValue) - parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); + public void GroupsSetTopic(Action callback, string channelId, string topic) + { + List> parameters = new List>(); - if (enableHighlights) - parameters.Add(new Tuple("highlight", "1")); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("topic", topic)); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void GroupsUnarchive(Action callback, string channelId) + { + APIRequestWithToken(callback, new Tuple("channel", channelId)); + } + + public void GetGroupHistory(Action callback, Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + GetHistory(callback, groupInfo.id, latest, oldest, count, unreads); + } + + #endregion + + #region Search + + public void SearchAll(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("query", query)); - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (sorting != null) + parameters.Add(new Tuple("sort", sorting)); - APIRequestWithToken(callback, parameters.ToArray()); - } + if (direction.HasValue) + parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); - public void SearchMessages(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) - { - List> parameters = new List>(); - parameters.Add(new Tuple("query", query)); + if (enableHighlights) + parameters.Add(new Tuple("highlight", "1")); - if (sorting != null) - parameters.Add(new Tuple("sort", sorting)); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - if (direction.HasValue) - parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); - if (enableHighlights) - parameters.Add(new Tuple("highlight", "1")); + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void SearchMessages(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("query", query)); + + if (sorting != null) + parameters.Add(new Tuple("sort", sorting)); + + if (direction.HasValue) + parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (enableHighlights) + parameters.Add(new Tuple("highlight", "1")); - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - APIRequestWithToken(callback, parameters.ToArray()); - } + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); - public void SearchFiles(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) - { - List> parameters = new List>(); - parameters.Add(new Tuple("query", query)); + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void SearchFles(Action callback, string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("query", query)); - if (sorting != null) - parameters.Add(new Tuple("sort", sorting)); + if (sorting != null) + parameters.Add(new Tuple("sort", sorting)); - if (direction.HasValue) - parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); + if (direction.HasValue) + parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); - if (enableHighlights) - parameters.Add(new Tuple("highlight", "1")); + if (enableHighlights) + parameters.Add(new Tuple("highlight", "1")); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); - APIRequestWithToken(callback, parameters.ToArray()); - } + APIRequestWithToken(callback, parameters.ToArray()); + } - public void GetStars(Action callback, string userId = null, int? count = null, int? page = null){ - List> parameters = new List>(); + #endregion - if(!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); + #region Users - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + public void GetUserList(Action callback) + { + APIRequestWithToken(callback); + } - if(page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + public void GetUserByEmail(Action callback, string email) + { + APIRequestWithToken(callback, new Tuple("email", email)); + } + + public void GetCounts(Action callback) + { + APIRequestWithToken(callback); + } + + public void GetPresence(Action callback, string user) + { + APIRequestWithToken(callback, new Tuple("user", user)); + } + + public void GetInfo(Action callback, string user) + { + APIRequestWithToken(callback, new Tuple("user", user)); + } + + #endregion + + #region DirectMessage + + public void GetDirectMessageHistory(Action callback, DirectMessageConversation conversationInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + GetHistory(callback, conversationInfo.id, latest, oldest, count, unreads); + } + + public void GetDirectMessageList(Action callback) + { + APIRequestWithToken(callback); + } + + public void JoinDirectMessageChannel(Action callback, string user) + { + var param = new Tuple("user", user); + APIRequestWithToken(callback, param); + } - APIRequestWithToken(callback, parameters.ToArray()); - } + #endregion - public void DeleteMessage(Action callback, string channelId, DateTime ts) - { - List> parameters = new List>() - { - new Tuple("ts", ts.ToProperTimeStamp()), - new Tuple("channel", channelId) - }; + public void GetFiles(Action callback, string userId = null, DateTime? from = null, DateTime? to = null, int? count = null, int? page = null, FileTypes types = FileTypes.all, string channel = null) + { + List> parameters = new List>(); - APIRequestWithToken(callback, parameters.ToArray()); - } - - public void EmitPresence(Action callback, Presence status) - { - APIRequestWithToken(callback, new Tuple("presence", status.ToString())); - } - - public void GetPreferences(Action callback) - { - APIRequestWithToken(callback); - } + if (!string.IsNullOrEmpty(userId)) + parameters.Add(new Tuple("user", userId)); - #region Users - - public void GetCounts(Action callback) - { - APIRequestWithToken(callback); - } - - public void GetPresence(Action callback, string user) - { - APIRequestWithToken(callback, new Tuple("user", user)); - } - - public void GetInfo(Action callback, string user) - { - APIRequestWithToken(callback, new Tuple("user", user)); - } - - #endregion - - public void EmitLogin(Action callback, string agent = "Inumedia.SlackAPI") - { - APIRequestWithToken(callback, new Tuple("agent", agent)); - } - - public void Update( - Action callback, - string ts, - string channelId, - string text, - string botName = null, - string parse = null, - bool linkNames = false, - IBlock[] blocks = null, - Attachment[] attachments = null, - bool as_user = false) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("ts", ts)); - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); - - if (!string.IsNullOrEmpty(botName)) - parameters.Add(new Tuple("username", botName)); - - if (!string.IsNullOrEmpty(parse)) - parameters.Add(new Tuple("parse", parse)); - - if (linkNames) - parameters.Add(new Tuple("link_names", "1")); - - if (blocks != null && blocks.Length > 0) - parameters.Add(new Tuple("blocks", - JsonConvert.SerializeObject(blocks, new JsonSerializerSettings() - { - NullValueHandling = NullValueHandling.Ignore - }))); - - if (attachments != null && attachments.Length > 0) - parameters.Add(new Tuple("attachments", - JsonConvert.SerializeObject(attachments, new JsonSerializerSettings() - { - NullValueHandling = NullValueHandling.Ignore - }))); - - - parameters.Add(new Tuple("as_user", as_user.ToString())); - - APIRequestWithToken(callback, parameters.ToArray()); - } - - public void JoinDirectMessageChannel(Action callback, string user) - { - var param = new Tuple("user", user); - APIRequestWithToken(callback, param); - } - - public void PostMessage( - Action callback, - string channelId, - string text, - string botName = null, - string parse = null, - bool linkNames = false, - IBlock[] blocks = null, - Attachment[] attachments = null, - bool? unfurl_links = null, - string icon_url = null, - string icon_emoji = null, - bool? as_user = null, - string thread_ts = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); - - if(!string.IsNullOrEmpty(botName)) - parameters.Add(new Tuple("username", botName)); - - if (!string.IsNullOrEmpty(parse)) - parameters.Add(new Tuple("parse", parse)); - - if (linkNames) - parameters.Add(new Tuple("link_names", "1")); - - if (blocks != null && blocks.Length > 0) - parameters.Add(new Tuple("blocks", - JsonConvert.SerializeObject(blocks, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); - - if (attachments != null && attachments.Length > 0) - parameters.Add(new Tuple("attachments", - JsonConvert.SerializeObject(attachments, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); - - if (unfurl_links.HasValue) - parameters.Add(new Tuple("unfurl_links", unfurl_links.Value ? "true" : "false")); - - if (!string.IsNullOrEmpty(icon_url)) - parameters.Add(new Tuple("icon_url", icon_url)); - - if (!string.IsNullOrEmpty(icon_emoji)) - parameters.Add(new Tuple("icon_emoji", icon_emoji)); - - if (as_user.HasValue) - parameters.Add(new Tuple("as_user", as_user.ToString())); - - if (!string.IsNullOrEmpty(thread_ts)) - parameters.Add(new Tuple("thread_ts", thread_ts)); - - APIRequestWithToken(callback, parameters.ToArray()); - } - - public void PostEphemeralMessage( - Action callback, - string channelId, - string text, - string targetuser, - string parse = null, - bool linkNames = false, - Block[] blocks = null, - Attachment[] attachments = null, - bool as_user = false, - string thread_ts = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); - parameters.Add(new Tuple("user", targetuser)); - - if (!string.IsNullOrEmpty(parse)) - parameters.Add(new Tuple("parse", parse)); - - if (linkNames) - parameters.Add(new Tuple("link_names", "1")); - - if (blocks != null && blocks.Length > 0) - parameters.Add(new Tuple("blocks", - JsonConvert.SerializeObject(blocks, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); - - if (attachments != null && attachments.Length > 0) - parameters.Add(new Tuple("attachments", - JsonConvert.SerializeObject(attachments, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); - - parameters.Add(new Tuple("as_user", as_user.ToString())); - - APIRequestWithToken(callback, parameters.ToArray()); - } - public void DialogOpen( - Action callback, - string triggerId, - Dialog dialog) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("trigger_id", triggerId)); - - parameters.Add(new Tuple("dialog", - JsonConvert.SerializeObject(dialog, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }))); - - APIRequestWithToken(callback, parameters.ToArray()); - } - - public void AddReaction( - Action callback, - string name = null, - string channel = null, - string timestamp = null) - { - List> parameters = new List>(); - - if (!string.IsNullOrEmpty(name)) - parameters.Add(new Tuple("name", name)); - - if (!string.IsNullOrEmpty(channel)) - parameters.Add(new Tuple("channel", channel)); - - if (!string.IsNullOrEmpty(timestamp)) - parameters.Add(new Tuple("timestamp", timestamp)); - - APIRequestWithToken(callback, parameters.ToArray()); - } - - public void UploadFile(Action callback, byte[] fileData, string fileName, string[] channelIds, string title = null, string initialComment = null, bool useAsync = false, string fileType = null) - { - Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); - - List parameters = new List(); - parameters.Add(string.Format("token={0}", APIToken)); - - //File/Content - if (!string.IsNullOrEmpty(fileType)) - parameters.Add(string.Format("{0}={1}", "filetype", fileType)); - - if (!string.IsNullOrEmpty(fileName)) - parameters.Add(string.Format("{0}={1}", "filename", fileName)); - - if (!string.IsNullOrEmpty(title)) - parameters.Add(string.Format("{0}={1}", "title", title)); - - if (!string.IsNullOrEmpty(initialComment)) - parameters.Add(string.Format("{0}={1}", "initial_comment", initialComment)); - - parameters.Add(string.Format("{0}={1}", "channels", string.Join(",", channelIds))); - - using (MultipartFormDataContent form = new MultipartFormDataContent()) - { - form.Add(new ByteArrayContent(fileData), "file", fileName); - HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); - string result = response.Content.ReadAsStringAsync().Result; - callback(result.Deserialize()); - } - } - - public void DeleteFile(Action callback, string file = null) - { - if (string.IsNullOrEmpty(file)) - return; - - APIRequestWithToken(callback, new Tuple("file", file)); - } - } + if (from.HasValue) + parameters.Add(new Tuple("ts_from", from.Value.ToProperTimeStamp())); + + if (to.HasValue) + parameters.Add(new Tuple("ts_to", to.Value.ToProperTimeStamp())); + + if (!types.HasFlag(FileTypes.all)) + { + FileTypes[] values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); + + StringBuilder building = new StringBuilder(); + bool first = true; + for (int i = 0; i < values.Length; ++i) + { + if (types.HasFlag(values[i])) + { + if (!first) building.Append(","); + + building.Append(values[i].ToString()); + + first = false; + } + } + + if (building.Length > 0) + parameters.Add(new Tuple("types", building.ToString())); + } + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + if (!string.IsNullOrEmpty(channel)) + parameters.Add(new Tuple("channel", channel)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + void GetHistory(Action historyCallback, string channel, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + where K : MessageHistory + { + List> parameters = new List>(); + parameters.Add(new Tuple("channel", channel)); + + if (latest.HasValue) + parameters.Add(new Tuple("latest", latest.Value.ToProperTimeStamp())); + if (oldest.HasValue) + parameters.Add(new Tuple("oldest", oldest.Value.ToProperTimeStamp())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + if (unreads.HasValue) + parameters.Add(new Tuple("unreads", unreads.Value ? "1" : "0")); + + APIRequestWithToken(historyCallback, parameters.ToArray()); + } + + public void GetFileInfo(Action callback, string fileId, int? page = null, int? count = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("file", fileId)); + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void EmitLogin(Action callback, string agent = "Inumedia.SlackAPI") + { + APIRequestWithToken(callback, new Tuple("agent", agent)); + } + + public void GetStars(Action callback, string userId = null, int? count = null, int? page = null) + { + List> parameters = new List>(); + + if (!string.IsNullOrEmpty(userId)) + parameters.Add(new Tuple("user", userId)); + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void DeleteMessage(Action callback, string channelId, DateTime ts) + { + List> parameters = new List>() + { + new Tuple("ts", ts.ToProperTimeStamp()), + new Tuple("channel", channelId) + }; + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void EmitPresence(Action callback, Presence status) + { + APIRequestWithToken(callback, new Tuple("presence", status.ToString())); + } + + public void GetPreferences(Action callback) + { + APIRequestWithToken(callback); + } + + public void Update( + Action callback, + string ts, + string channelId, + string text, + string botName = null, + string parse = null, + bool linkNames = false, + IBlock[] blocks = null, + Attachment[] attachments = null, + bool as_user = false) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("ts", ts)); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", + JsonConvert.SerializeObject(blocks, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", + JsonConvert.SerializeObject(attachments, new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + + parameters.Add(new Tuple("as_user", as_user.ToString())); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void PostMessage( + Action callback, + string channelId, + string text, + string botName = null, + string parse = null, + bool linkNames = false, + IBlock[] blocks = null, + Attachment[] attachments = null, + bool? unfurl_links = null, + string icon_url = null, + string icon_emoji = null, + bool? as_user = null, + string thread_ts = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", + JsonConvert.SerializeObject(blocks, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", + JsonConvert.SerializeObject(attachments, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (unfurl_links.HasValue) + parameters.Add(new Tuple("unfurl_links", unfurl_links.Value ? "true" : "false")); + + if (!string.IsNullOrEmpty(icon_url)) + parameters.Add(new Tuple("icon_url", icon_url)); + + if (!string.IsNullOrEmpty(icon_emoji)) + parameters.Add(new Tuple("icon_emoji", icon_emoji)); + + if (as_user.HasValue) + parameters.Add(new Tuple("as_user", as_user.ToString())); + + if (!string.IsNullOrEmpty(thread_ts)) + parameters.Add(new Tuple("thread_ts", thread_ts)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void PostEphemeralMessage( + Action callback, + string channelId, + string text, + string targetuser, + string parse = null, + bool linkNames = false, + Block[] blocks = null, + Attachment[] attachments = null, + bool as_user = false, + string thread_ts = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + parameters.Add(new Tuple("user", targetuser)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", + JsonConvert.SerializeObject(blocks, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", + JsonConvert.SerializeObject(attachments, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + parameters.Add(new Tuple("as_user", as_user.ToString())); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void AddReaction( + Action callback, + string name = null, + string channel = null, + string timestamp = null) + { + List> parameters = new List>(); + + if (!string.IsNullOrEmpty(name)) + parameters.Add(new Tuple("name", name)); + + if (!string.IsNullOrEmpty(channel)) + parameters.Add(new Tuple("channel", channel)); + + if (!string.IsNullOrEmpty(timestamp)) + parameters.Add(new Tuple("timestamp", timestamp)); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void DialogOpen( + Action callback, + string triggerId, + Dialog dialog) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("trigger_id", triggerId)); + + parameters.Add(new Tuple("dialog", + JsonConvert.SerializeObject(dialog, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }))); + + APIRequestWithToken(callback, parameters.ToArray()); + } + + public void UploadFile(Action callback, byte[] fileData, string fileName, string[] channelIds, string title = null, string initialComment = null, bool useAsync = false, string fileType = null) + { + Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); + + List parameters = new List(); + parameters.Add(string.Format("token={0}", APIToken)); + + //File/Content + if (!string.IsNullOrEmpty(fileType)) + parameters.Add(string.Format("{0}={1}", "filetype", fileType)); + + if (!string.IsNullOrEmpty(fileName)) + parameters.Add(string.Format("{0}={1}", "filename", fileName)); + + if (!string.IsNullOrEmpty(title)) + parameters.Add(string.Format("{0}={1}", "title", title)); + + if (!string.IsNullOrEmpty(initialComment)) + parameters.Add(string.Format("{0}={1}", "initial_comment", initialComment)); + + parameters.Add(string.Format("{0}={1}", "channels", string.Join(",", channelIds))); + + using (MultipartFormDataContent form = new MultipartFormDataContent()) + { + form.Add(new ByteArrayContent(fileData), "file", fileName); + HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); + string result = response.Content.ReadAsStringAsync().Result; + callback(result.Deserialize()); + } + } + + public void DeleteFile(Action callback, string file = null) + { + if (string.IsNullOrEmpty(file)) + return; + + APIRequestWithToken(callback, new Tuple("file", file)); + } + } } diff --git a/SlackAPI/SlackTaskClient.cs b/SlackAPI/SlackTaskClient.cs index 4b19cab..e063703 100644 --- a/SlackAPI/SlackTaskClient.cs +++ b/SlackAPI/SlackTaskClient.cs @@ -11,656 +11,697 @@ namespace SlackAPI { - public class SlackTaskClient : SlackClientBase - { - private readonly string APIToken; - - public Self MySelf; - public User MyData; - public Team MyTeam; - - public List starredChannels; - - public List Users; - public List Channels; - public List Groups; - public List DirectMessages; - - public Dictionary UserLookup; - public Dictionary ChannelLookup; - public Dictionary GroupLookup; - public Dictionary DirectMessageLookup; - - public SlackTaskClient(string token) - { - APIToken = token; - } - - public SlackTaskClient(string token, IWebProxy proxySettings) - : base(proxySettings) - { - APIToken = token; - } - - public virtual async Task ConnectAsync() - { - var loginDetails = await EmitLoginAsync(); - if(loginDetails.ok) - Connected(loginDetails); - - return loginDetails; - } - - protected virtual void Connected(LoginResponse loginDetails) - { - MySelf = loginDetails.self; - MyData = loginDetails.users.First((c) => c.id == MySelf.id); - MyTeam = loginDetails.team; - - Users = new List(loginDetails.users.Where((c) => !c.deleted)); - Channels = new List(loginDetails.channels); - Groups = new List(loginDetails.groups); - DirectMessages = new List(loginDetails.ims.Where((c) => Users.Exists((a) => a.id == c.user) && c.id != MySelf.id)); - starredChannels = - Groups.Where((c) => c.is_starred).Select((c) => c.id) - .Union( - DirectMessages.Where((c) => c.is_starred).Select((c) => c.user) - ).Union( - Channels.Where((c) => c.is_starred).Select((c) => c.id) - ).ToList(); - - UserLookup = new Dictionary(); - foreach (User u in Users) UserLookup.Add(u.id, u); - - ChannelLookup = new Dictionary(); - foreach (Channel c in Channels) ChannelLookup.Add(c.id, c); - - GroupLookup = new Dictionary(); - foreach (Channel g in Groups) GroupLookup.Add(g.id, g); - - DirectMessageLookup = new Dictionary(); - foreach (DirectMessageConversation im in DirectMessages) DirectMessageLookup.Add(im.id, im); - } - - public Task APIRequestWithTokenAsync() - where K : Response - { - return APIRequestWithTokenAsync(new Tuple[] { }); - } - - public Task APIRequestWithTokenAsync(params Tuple[] postParameters) - where K : Response - { - Tuple[] tokenArray = new Tuple[]{ - new Tuple("token", APIToken) - }; - - return APIRequestAsync(tokenArray, postParameters); - } - - public Task TestAuthAsync() - { - return APIRequestWithTokenAsync(); - } - - public Task GetUserListAsync() - { - return APIRequestWithTokenAsync(); - } - - public Task GetUserByEmailAsync(string email) - { - return APIRequestWithTokenAsync(new Tuple("email", email)); - } - - public Task ChannelsCreateAsync(string name) { - return APIRequestWithTokenAsync(new Tuple("name", name)); - } - - public Task ChannelsInviteAsync(string userId, string channelId) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("user", userId)); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task GetChannelListAsync(bool ExcludeArchived = true) - { - return APIRequestWithTokenAsync(new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); - } - - public Task GetGroupsListAsync(bool ExcludeArchived = true) - { - return APIRequestWithTokenAsync(new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); - } - - public Task GetDirectMessageListAsync() - { - return APIRequestWithTokenAsync(); - } - - public Task GetFilesAsync(string userId = null, DateTime? from = null, DateTime? to = null, int? count = null, int? page = null, FileTypes types = FileTypes.all) - { - List> parameters = new List>(); - - if (!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); - - if (from.HasValue) - parameters.Add(new Tuple("ts_from", from.Value.ToProperTimeStamp())); - - if (to.HasValue) - parameters.Add(new Tuple("ts_to", to.Value.ToProperTimeStamp())); - - if (!types.HasFlag(FileTypes.all)) - { - FileTypes[] values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); - - StringBuilder building = new StringBuilder(); - bool first = true; - for (int i = 0; i < values.Length; ++i) - { - if (types.HasFlag(values[i])) - { - if (!first) building.Append(","); - - building.Append(values[i].ToString()); - - first = false; - } - } - - if (building.Length > 0) - parameters.Add(new Tuple("types", building.ToString())); - } - - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - private Task GetHistoryAsync(string channel, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - where K : MessageHistory - { - List> parameters = new List>(); - parameters.Add(new Tuple("channel", channel)); - - if(latest.HasValue) - parameters.Add(new Tuple("latest", latest.Value.ToProperTimeStamp())); - if(oldest.HasValue) - parameters.Add(new Tuple("oldest", oldest.Value.ToProperTimeStamp())); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - if (unreads.HasValue) - parameters.Add(new Tuple("unreads", unreads.Value ? "1" : "0")); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task GetChannelHistoryAsync(Channel channelInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - { - return GetHistoryAsync(channelInfo.id, latest, oldest, count, unreads); - } - - public Task GetDirectMessageHistoryAsync(DirectMessageConversation conversationInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - { - return GetHistoryAsync(conversationInfo.id, latest, oldest, count, unreads); - } - - public Task GetGroupHistoryAsync(Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) - { - return GetHistoryAsync(groupInfo.id, latest, oldest, count, unreads); - } - - public Task MarkChannelAsync(string channelId, DateTime ts) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId), - new Tuple("ts", ts.ToProperTimeStamp()) - ); - } - - public Task GetFileInfoAsync(string fileId, int? page = null, int? count = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("file", fileId)); - - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - #region Groups - public Task GroupsArchiveAsync(string channelId) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId)); - } + public class SlackTaskClient : SlackClientBase + { + private readonly string APIToken; + + public Self MySelf; + public User MyData; + public Team MyTeam; + + public List starredChannels; + public List Users; + public List Channels; + public List Groups; + public List DirectMessages; + + public Dictionary UserLookup; + public Dictionary ChannelLookup; + public Dictionary GroupLookup; + public Dictionary DirectMessageLookup; + + public SlackTaskClient(string token) + { + APIToken = token; + } + + public SlackTaskClient(string token, IWebProxy proxySettings) + : base(proxySettings) + { + APIToken = token; + } + + public virtual async Task ConnectAsync() + { + var loginDetails = await EmitLoginAsync(); + if (loginDetails.ok) + Connected(loginDetails); + + return loginDetails; + } + + protected virtual void Connected(LoginResponse loginDetails) + { + MySelf = loginDetails.self; + MyData = loginDetails.users.First((c) => c.id == MySelf.id); + MyTeam = loginDetails.team; + + Users = new List(loginDetails.users.Where((c) => !c.deleted)); + Channels = new List(loginDetails.channels); + Groups = new List(loginDetails.groups); + DirectMessages = new List(loginDetails.ims.Where((c) => Users.Exists((a) => a.id == c.user) && c.id != MySelf.id)); + starredChannels = + Groups.Where((c) => c.is_starred).Select((c) => c.id) + .Union( + DirectMessages.Where((c) => c.is_starred).Select((c) => c.user) + ).Union( + Channels.Where((c) => c.is_starred).Select((c) => c.id) + ).ToList(); + + UserLookup = new Dictionary(); + foreach (User u in Users) UserLookup.Add(u.id, u); + + ChannelLookup = new Dictionary(); + foreach (Channel c in Channels) ChannelLookup.Add(c.id, c); + + GroupLookup = new Dictionary(); + foreach (Channel g in Groups) GroupLookup.Add(g.id, g); + + DirectMessageLookup = new Dictionary(); + foreach (DirectMessageConversation im in DirectMessages) DirectMessageLookup.Add(im.id, im); + } + + public Task APIRequestWithTokenAsync() + where K : Response + { + return APIRequestWithTokenAsync(new Tuple[] { }); + } + + public Task APIRequestWithTokenAsync(params Tuple[] postParameters) + where K : Response + { + Tuple[] tokenArray = new Tuple[]{ + new Tuple("token", APIToken) + }; + + return APIRequestAsync(tokenArray, postParameters); + } + + public Task TestAuthAsync() + { + return APIRequestWithTokenAsync(); + } + + + #region Channels + + public Task ChannelsCreateAsync(string name) + { + return APIRequestWithTokenAsync(new Tuple("name", name)); + } + + public Task ChannelsInviteAsync(string userId, string channelId) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task GetChannelListAsync(bool ExcludeArchived = true) + { + return APIRequestWithTokenAsync(new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); + } + + public Task GetChannelHistoryAsync(Channel channelInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + return GetHistoryAsync(channelInfo.id, latest, oldest, count, unreads); + } + + public Task MarkChannelAsync(string channelId, DateTime ts) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId), + new Tuple("ts", ts.ToProperTimeStamp()) + ); + } + + public Task ChannelSetTopicAsync(string channelId, string newTopic) + { + return APIRequestWithTokenAsync( + new Tuple("channel", channelId), + new Tuple("topic", newTopic)); + } + + #endregion + + #region Conversations + + public Task GetConversationsListAsync(string cursor = "", bool ExcludeArchived = true, int limit = 100, ConversationTypes[] types = null) + { + List> parameters = new List>() + { + Tuple.Create("exclude_archived", ExcludeArchived ? "1" : "0") + }; + if (limit > 0) + parameters.Add(Tuple.Create("limit", limit.ToString())); + if (types != null && types.Any()) + parameters.Add(Tuple.Create("types", Conversation.ConversationTypesToQueryParam(types))); + if (!string.IsNullOrEmpty(cursor)) + parameters.Add(new Tuple("cursor", cursor)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + #endregion + + #region Groups - public Task GroupsCloseAsync(string channelId) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId)); - } + public Task GetGroupsListAsync(bool ExcludeArchived = true) + { + return APIRequestWithTokenAsync(new Tuple("exclude_archived", ExcludeArchived ? "1" : "0")); + } - public Task GroupsCreateAsync(string name) - { - return APIRequestWithTokenAsync(new Tuple("name", name)); - } + public Task GroupsArchiveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } + + public Task GroupsCloseAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } - public Task GroupsCreateChildAsync(string channelId) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId)); - } + public Task GroupsCreateAsync(string name) + { + return APIRequestWithTokenAsync(new Tuple("name", name)); + } - public Task GroupsInviteAsync(string userId, string channelId) - { - List> parameters = new List>(); + public Task GroupsCreateChildAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("user", userId)); + public Task GroupsInviteAsync(string userId, string channelId) + { + List> parameters = new List>(); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); - public Task GroupsKickAsync(string userId, string channelId) - { - List> parameters = new List>(); + return APIRequestWithTokenAsync(parameters.ToArray()); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("user", userId)); + public Task GroupsKickAsync(string userId, string channelId) + { + List> parameters = new List>(); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("user", userId)); - public Task GroupsLeaveAsync(string channelId) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId)); - } + return APIRequestWithTokenAsync(parameters.ToArray()); + } - public Task GroupsMarkAsync(string channelId, DateTime ts) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId), new Tuple("ts", ts.ToProperTimeStamp())); - } + public Task GroupsLeaveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } - public Task GroupsOpenAsync(string channelId) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId)); - } + public Task GroupsMarkAsync(string channelId, DateTime ts) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId), new Tuple("ts", ts.ToProperTimeStamp())); + } - public Task GroupsRenameAsync(string channelId, string name) - { - List> parameters = new List>(); + public Task GroupsOpenAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("name", name)); + public Task GroupsRenameAsync(string channelId, string name) + { + List> parameters = new List>(); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("name", name)); - public Task GroupsSetPurposeAsync(string channelId, string purpose) - { - List> parameters = new List>(); + return APIRequestWithTokenAsync(parameters.ToArray()); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("purpose", purpose)); + public Task GroupsSetPurposeAsync(string channelId, string purpose) + { + List> parameters = new List>(); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("purpose", purpose)); - public Task GroupsSetTopicAsync(string channelId, string topic) - { - List> parameters = new List>(); + return APIRequestWithTokenAsync(parameters.ToArray()); + } - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("topic", topic)); + public Task GroupsSetTopicAsync(string channelId, string topic) + { + List> parameters = new List>(); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("topic", topic)); - public Task GroupsUnarchiveAsync(string channelId) - { - return APIRequestWithTokenAsync(new Tuple("channel", channelId)); - } + return APIRequestWithTokenAsync(parameters.ToArray()); + } - #endregion + public Task GroupsUnarchiveAsync(string channelId) + { + return APIRequestWithTokenAsync(new Tuple("channel", channelId)); + } - public Task SearchAllAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) - { - List> parameters = new List>(); - parameters.Add(new Tuple("query", query)); + public Task GetGroupHistoryAsync(Channel groupInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + return GetHistoryAsync(groupInfo.id, latest, oldest, count, unreads); + } - if (sorting != null) - parameters.Add(new Tuple("sort", sorting)); + #endregion - if (direction.HasValue) - parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); + #region Search - if (enableHighlights) - parameters.Add(new Tuple("highlight", "1")); + public Task SearchAllAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("query", query)); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (sorting != null) + parameters.Add(new Tuple("sort", sorting)); - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (direction.HasValue) + parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + if (enableHighlights) + parameters.Add(new Tuple("highlight", "1")); - public Task SearchMessagesAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) - { - List> parameters = new List>(); - parameters.Add(new Tuple("query", query)); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - if (sorting != null) - parameters.Add(new Tuple("sort", sorting)); + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); - if (direction.HasValue) - parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); + return APIRequestWithTokenAsync(parameters.ToArray()); + } - if (enableHighlights) - parameters.Add(new Tuple("highlight", "1")); + public Task SearchMessagesAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("query", query)); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (sorting != null) + parameters.Add(new Tuple("sort", sorting)); - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (direction.HasValue) + parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + if (enableHighlights) + parameters.Add(new Tuple("highlight", "1")); - public Task SearchFilesAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) - { - List> parameters = new List>(); - parameters.Add(new Tuple("query", query)); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); - if (sorting != null) - parameters.Add(new Tuple("sort", sorting)); + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); - if (direction.HasValue) - parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); + return APIRequestWithTokenAsync(parameters.ToArray()); + } - if (enableHighlights) - parameters.Add(new Tuple("highlight", "1")); + public Task SearchFilesAsync(string query, string sorting = null, SearchSortDirection? direction = null, bool enableHighlights = false, int? count = null, int? page = null) + { + List> parameters = new List>(); + parameters.Add(new Tuple("query", query)); - if (count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); + if (sorting != null) + parameters.Add(new Tuple("sort", sorting)); - if (page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); + if (direction.HasValue) + parameters.Add(new Tuple("sort_dir", direction.Value.ToString())); - return APIRequestWithTokenAsync(parameters.ToArray()); - } + if (enableHighlights) + parameters.Add(new Tuple("highlight", "1")); - public Task GetStarsAsync(string userId = null, int? count = null, int? page = null){ - List> parameters = new List>(); - - if(!string.IsNullOrEmpty(userId)) - parameters.Add(new Tuple("user", userId)); - - if(count.HasValue) - parameters.Add(new Tuple("count", count.Value.ToString())); - - if(page.HasValue) - parameters.Add(new Tuple("page", page.Value.ToString())); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task DeleteMessageAsync(string channelId, DateTime ts) - { - List> parameters = new List>() - { - new Tuple("ts", ts.ToProperTimeStamp()), - new Tuple("channel", channelId) - }; - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task EmitPresence(Presence status) - { - return APIRequestWithTokenAsync(new Tuple("presence", status.ToString())); - } - - public Task GetPreferencesAsync() - { - return APIRequestWithTokenAsync(); - } - - public Task GetCountsAsync() - { - return APIRequestWithTokenAsync(); - } - - public Task EmitLoginAsync(string agent = "Inumedia.SlackAPI") - { - return APIRequestWithTokenAsync(new Tuple("agent", agent)); - } - public Task UpdateAsync(string ts, - string channelId, - string text, - string botName = null, - string parse = null, - bool linkNames = false, - Attachment[] attachments = null, - bool as_user = false, - IBlock[] blocks = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("ts", ts)); - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); - - if (!string.IsNullOrEmpty(botName)) - parameters.Add(new Tuple("username", botName)); - - if (!string.IsNullOrEmpty(parse)) - parameters.Add(new Tuple("parse", parse)); - - if (linkNames) - parameters.Add(new Tuple("link_names", "1")); - - if (attachments != null && attachments.Length > 0) - parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments))); - - parameters.Add(new Tuple("as_user", as_user.ToString())); - - if (blocks != null && blocks.Length > 0) - parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, - new JsonSerializerSettings() - { - NullValueHandling = NullValueHandling.Ignore - }))); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task JoinDirectMessageChannelAsync(string user) - { - var param = new Tuple("user", user); - return APIRequestWithTokenAsync(param); - } - - public Task PostMessageAsync( - string channelId, - string text, - string botName = null, - string parse = null, - bool linkNames = false, - IBlock[] blocks = null, - Attachment[] attachments = null, - bool? unfurl_links = null, - string icon_url = null, - string icon_emoji = null, - bool as_user = false, - string thread_ts = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); - - if(!string.IsNullOrEmpty(botName)) - parameters.Add(new Tuple("username", botName)); - - if (!string.IsNullOrEmpty(parse)) - parameters.Add(new Tuple("parse", parse)); - - if (linkNames) - parameters.Add(new Tuple("link_names", "1")); - - if (blocks != null && blocks.Length > 0) - parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, - new JsonSerializerSettings() - { - NullValueHandling = NullValueHandling.Ignore - }))); - - if (attachments != null && attachments.Length > 0) - parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments, - new JsonSerializerSettings() - { - NullValueHandling = NullValueHandling.Ignore - }))); - - if (unfurl_links.HasValue) - parameters.Add(new Tuple("unfurl_links", unfurl_links.Value ? "true" : "false")); - - if (!string.IsNullOrEmpty(icon_url)) - parameters.Add(new Tuple("icon_url", icon_url)); - - if (!string.IsNullOrEmpty(icon_emoji)) - parameters.Add(new Tuple("icon_emoji", icon_emoji)); - - if (as_user) - parameters.Add(new Tuple("as_user", true.ToString())); - - if (!string.IsNullOrEmpty(thread_ts)) - parameters.Add(new Tuple("thread_ts", thread_ts)); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task PostEphemeralMessageAsync( - string channelId, - string text, - string targetuser, - string parse = null, - bool linkNames = false, - Attachment[] attachments = null, - bool as_user = false, - string thread_ts = null) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("channel", channelId)); - parameters.Add(new Tuple("text", text)); - parameters.Add(new Tuple("user", targetuser)); - - if (!string.IsNullOrEmpty(parse)) - parameters.Add(new Tuple("parse", parse)); - - if (linkNames) - parameters.Add(new Tuple("link_names", "1")); - - if (attachments != null && attachments.Length > 0) - parameters.Add(new Tuple("attachments", - JsonConvert.SerializeObject(attachments, Formatting.None, - new JsonSerializerSettings // Shouldn't include a not set property - { - NullValueHandling = NullValueHandling.Ignore - }))); - - parameters.Add(new Tuple("as_user", as_user.ToString())); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task AddReactionAsync( - string name = null, - string channel = null, - string timestamp = null) - { - List> parameters = new List>(); - - if (!string.IsNullOrEmpty(name)) - parameters.Add(new Tuple("name", name)); - - if (!string.IsNullOrEmpty(channel)) - parameters.Add(new Tuple("channel", channel)); - - if (!string.IsNullOrEmpty(timestamp)) - parameters.Add(new Tuple("timestamp", timestamp)); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public Task DialogOpenAsync( - string triggerId, - Dialog dialog) - { - List> parameters = new List>(); - - parameters.Add(new Tuple("trigger_id", triggerId)); - - parameters.Add(new Tuple("dialog", - JsonConvert.SerializeObject(dialog, - new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }))); - - return APIRequestWithTokenAsync(parameters.ToArray()); - } - - public async Task UploadFileAsync(byte[] fileData, string fileName, string[] channelIds, string title = null, string initialComment = null, bool useAsync = false, string fileType = null) - { - Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); - - List parameters = new List(); - parameters.Add(string.Format("token={0}", APIToken)); - - //File/Content - if (!string.IsNullOrEmpty(fileType)) - parameters.Add(string.Format("{0}={1}", "filetype", fileType)); - - if (!string.IsNullOrEmpty(fileName)) - parameters.Add(string.Format("{0}={1}", "filename", fileName)); - - if (!string.IsNullOrEmpty(title)) - parameters.Add(string.Format("{0}={1}", "title", title)); - - if (!string.IsNullOrEmpty(initialComment)) - parameters.Add(string.Format("{0}={1}", "initial_comment", initialComment)); - - parameters.Add(string.Format("{0}={1}", "channels", string.Join(",", channelIds))); - - using (MultipartFormDataContent form = new MultipartFormDataContent()) - { - form.Add(new ByteArrayContent(fileData), "file", fileName); - HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); - string result = await response.Content.ReadAsStringAsync(); - return result.Deserialize(); - } - } - - public Task ChannelSetTopicAsync(string channelId, string newTopic) - { - return APIRequestWithTokenAsync( - new Tuple("channel", channelId), - new Tuple("topic", newTopic)); - } - } + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + #endregion + + #region Users + + public Task GetUserListAsync() + { + return APIRequestWithTokenAsync(); + } + + public Task GetUserByEmailAsync(string email) + { + return APIRequestWithTokenAsync(new Tuple("email", email)); + } + + public Task GetCountsAsync() + { + return APIRequestWithTokenAsync(); + } + + #endregion + + #region DirectMessage + + public Task GetDirectMessageHistoryAsync(DirectMessageConversation conversationInfo, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + { + return GetHistoryAsync(conversationInfo.id, latest, oldest, count, unreads); + } + + public Task GetDirectMessageListAsync() + { + return APIRequestWithTokenAsync(); + } + + public Task JoinDirectMessageChannelAsync(string user) + { + var param = new Tuple("user", user); + return APIRequestWithTokenAsync(param); + } + + #endregion + + public Task GetFilesAsync(string userId = null, DateTime? from = null, DateTime? to = null, int? count = null, int? page = null, FileTypes types = FileTypes.all) + { + List> parameters = new List>(); + + if (!string.IsNullOrEmpty(userId)) + parameters.Add(new Tuple("user", userId)); + + if (from.HasValue) + parameters.Add(new Tuple("ts_from", from.Value.ToProperTimeStamp())); + + if (to.HasValue) + parameters.Add(new Tuple("ts_to", to.Value.ToProperTimeStamp())); + + if (!types.HasFlag(FileTypes.all)) + { + FileTypes[] values = (FileTypes[])Enum.GetValues(typeof(FileTypes)); + + StringBuilder building = new StringBuilder(); + bool first = true; + for (int i = 0; i < values.Length; ++i) + { + if (types.HasFlag(values[i])) + { + if (!first) building.Append(","); + + building.Append(values[i].ToString()); + + first = false; + } + } + + if (building.Length > 0) + parameters.Add(new Tuple("types", building.ToString())); + } + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + private Task GetHistoryAsync(string channel, DateTime? latest = null, DateTime? oldest = null, int? count = null, bool? unreads = false) + where K : MessageHistory + { + List> parameters = new List>(); + parameters.Add(new Tuple("channel", channel)); + + if (latest.HasValue) + parameters.Add(new Tuple("latest", latest.Value.ToProperTimeStamp())); + if (oldest.HasValue) + parameters.Add(new Tuple("oldest", oldest.Value.ToProperTimeStamp())); + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + if (unreads.HasValue) + parameters.Add(new Tuple("unreads", unreads.Value ? "1" : "0")); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task GetFileInfoAsync(string fileId, int? page = null, int? count = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("file", fileId)); + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task EmitLoginAsync(string agent = "Inumedia.SlackAPI") + { + return APIRequestWithTokenAsync(new Tuple("agent", agent)); + } + + public Task GetStarsAsync(string userId = null, int? count = null, int? page = null) + { + List> parameters = new List>(); + + if (!string.IsNullOrEmpty(userId)) + parameters.Add(new Tuple("user", userId)); + + if (count.HasValue) + parameters.Add(new Tuple("count", count.Value.ToString())); + + if (page.HasValue) + parameters.Add(new Tuple("page", page.Value.ToString())); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task DeleteMessageAsync(string channelId, DateTime ts) + { + List> parameters = new List>() + { + new Tuple("ts", ts.ToProperTimeStamp()), + new Tuple("channel", channelId) + }; + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task EmitPresence(Presence status) + { + return APIRequestWithTokenAsync(new Tuple("presence", status.ToString())); + } + + public Task GetPreferencesAsync() + { + return APIRequestWithTokenAsync(); + } + + public Task UpdateAsync(string ts, + string channelId, + string text, + string botName = null, + string parse = null, + bool linkNames = false, + Attachment[] attachments = null, + bool as_user = false, + IBlock[] blocks = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("ts", ts)); + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments))); + + parameters.Add(new Tuple("as_user", as_user.ToString())); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task PostMessageAsync( + string channelId, + string text, + string botName = null, + string parse = null, + bool linkNames = false, + IBlock[] blocks = null, + Attachment[] attachments = null, + bool? unfurl_links = null, + string icon_url = null, + string icon_emoji = null, + bool as_user = false, + string thread_ts = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + + if (!string.IsNullOrEmpty(botName)) + parameters.Add(new Tuple("username", botName)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (blocks != null && blocks.Length > 0) + parameters.Add(new Tuple("blocks", JsonConvert.SerializeObject(blocks, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", JsonConvert.SerializeObject(attachments, + new JsonSerializerSettings() + { + NullValueHandling = NullValueHandling.Ignore + }))); + + if (unfurl_links.HasValue) + parameters.Add(new Tuple("unfurl_links", unfurl_links.Value ? "true" : "false")); + + if (!string.IsNullOrEmpty(icon_url)) + parameters.Add(new Tuple("icon_url", icon_url)); + + if (!string.IsNullOrEmpty(icon_emoji)) + parameters.Add(new Tuple("icon_emoji", icon_emoji)); + + if (as_user) + parameters.Add(new Tuple("as_user", true.ToString())); + + if (!string.IsNullOrEmpty(thread_ts)) + parameters.Add(new Tuple("thread_ts", thread_ts)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task PostEphemeralMessageAsync( + string channelId, + string text, + string targetuser, + string parse = null, + bool linkNames = false, + Attachment[] attachments = null, + bool as_user = false, + string thread_ts = null) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("channel", channelId)); + parameters.Add(new Tuple("text", text)); + parameters.Add(new Tuple("user", targetuser)); + + if (!string.IsNullOrEmpty(parse)) + parameters.Add(new Tuple("parse", parse)); + + if (linkNames) + parameters.Add(new Tuple("link_names", "1")); + + if (attachments != null && attachments.Length > 0) + parameters.Add(new Tuple("attachments", + JsonConvert.SerializeObject(attachments, Formatting.None, + new JsonSerializerSettings // Shouldn't include a not set property + { + NullValueHandling = NullValueHandling.Ignore + }))); + + parameters.Add(new Tuple("as_user", as_user.ToString())); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task AddReactionAsync( + string name = null, + string channel = null, + string timestamp = null) + { + List> parameters = new List>(); + + if (!string.IsNullOrEmpty(name)) + parameters.Add(new Tuple("name", name)); + + if (!string.IsNullOrEmpty(channel)) + parameters.Add(new Tuple("channel", channel)); + + if (!string.IsNullOrEmpty(timestamp)) + parameters.Add(new Tuple("timestamp", timestamp)); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public Task DialogOpenAsync( + string triggerId, + Dialog dialog) + { + List> parameters = new List>(); + + parameters.Add(new Tuple("trigger_id", triggerId)); + + parameters.Add(new Tuple("dialog", + JsonConvert.SerializeObject(dialog, + new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }))); + + return APIRequestWithTokenAsync(parameters.ToArray()); + } + + public async Task UploadFileAsync(byte[] fileData, string fileName, string[] channelIds, string title = null, string initialComment = null, bool useAsync = false, string fileType = null) + { + Uri target = new Uri(Path.Combine(APIBaseLocation, useAsync ? "files.uploadAsync" : "files.upload")); + + List parameters = new List(); + parameters.Add(string.Format("token={0}", APIToken)); + + //File/Content + if (!string.IsNullOrEmpty(fileType)) + parameters.Add(string.Format("{0}={1}", "filetype", fileType)); + + if (!string.IsNullOrEmpty(fileName)) + parameters.Add(string.Format("{0}={1}", "filename", fileName)); + + if (!string.IsNullOrEmpty(title)) + parameters.Add(string.Format("{0}={1}", "title", title)); + + if (!string.IsNullOrEmpty(initialComment)) + parameters.Add(string.Format("{0}={1}", "initial_comment", initialComment)); + + parameters.Add(string.Format("{0}={1}", "channels", string.Join(",", channelIds))); + + using (MultipartFormDataContent form = new MultipartFormDataContent()) + { + form.Add(new ByteArrayContent(fileData), "file", fileName); + HttpResponseMessage response = PostRequest(string.Format("{0}?{1}", target, string.Join("&", parameters.ToArray())), form); + string result = await response.Content.ReadAsStringAsync(); + return result.Deserialize(); + } + } + } } \ No newline at end of file