Added SendFile, Message now parses attachments
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using Discord.API.Models;
|
using Discord.API.Models;
|
||||||
using Discord.Helpers;
|
using Discord.Helpers;
|
||||||
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Discord.API
|
namespace Discord.API
|
||||||
@@ -86,6 +87,8 @@ namespace Discord.API
|
|||||||
=> Http.Post(Endpoints.ChannelTyping(channelId));
|
=> Http.Post(Endpoints.ChannelTyping(channelId));
|
||||||
public static Task DeleteMessage(string channelId, string msgId)
|
public static Task DeleteMessage(string channelId, string msgId)
|
||||||
=> Http.Delete(Endpoints.ChannelMessage(channelId, msgId));
|
=> Http.Delete(Endpoints.ChannelMessage(channelId, msgId));
|
||||||
|
public static Task SendFile(string channelId, Stream stream, string filename = null)
|
||||||
|
=> Http.File<APIResponses.SendMessage>(Endpoints.ChannelMessages(channelId), stream, filename);
|
||||||
|
|
||||||
//Voice
|
//Voice
|
||||||
public static Task<APIResponses.GetRegions[]> GetVoiceRegions()
|
public static Task<APIResponses.GetRegions[]> GetVoiceRegions()
|
||||||
@@ -129,6 +132,5 @@ namespace Discord.API
|
|||||||
var request = new APIRequests.ChangePassword { NewPassword = newPassword, CurrentEmail = currentEmail, CurrentPassword = currentPassword };
|
var request = new APIRequests.ChangePassword { NewPassword = newPassword, CurrentEmail = currentEmail, CurrentPassword = currentPassword };
|
||||||
return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request);
|
return Http.Patch<SelfUserInfo>(Endpoints.UserMe, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,20 @@ namespace Discord.API.Models
|
|||||||
}
|
}
|
||||||
internal class Message : MessageReference
|
internal class Message : MessageReference
|
||||||
{
|
{
|
||||||
|
public class Attachment
|
||||||
|
{
|
||||||
|
[JsonProperty(PropertyName = "id")]
|
||||||
|
public string Id;
|
||||||
|
[JsonProperty(PropertyName = "url")]
|
||||||
|
public string Url;
|
||||||
|
[JsonProperty(PropertyName = "proxy_url")]
|
||||||
|
public string ProxyUrl;
|
||||||
|
[JsonProperty(PropertyName = "size")]
|
||||||
|
public int Size;
|
||||||
|
[JsonProperty(PropertyName = "filename")]
|
||||||
|
public string Filename;
|
||||||
|
}
|
||||||
|
|
||||||
[JsonProperty(PropertyName = "tts")]
|
[JsonProperty(PropertyName = "tts")]
|
||||||
public bool IsTextToSpeech;
|
public bool IsTextToSpeech;
|
||||||
[JsonProperty(PropertyName = "mention_everyone")]
|
[JsonProperty(PropertyName = "mention_everyone")]
|
||||||
@@ -159,9 +173,9 @@ namespace Discord.API.Models
|
|||||||
[JsonProperty(PropertyName = "mentions")]
|
[JsonProperty(PropertyName = "mentions")]
|
||||||
public UserReference[] Mentions;
|
public UserReference[] Mentions;
|
||||||
[JsonProperty(PropertyName = "embeds")]
|
[JsonProperty(PropertyName = "embeds")]
|
||||||
public object[] Embeds;
|
public object[] Embeds; //TODO: Parse this
|
||||||
[JsonProperty(PropertyName = "attachments")]
|
[JsonProperty(PropertyName = "attachments")]
|
||||||
public object[] Attachments;
|
public Attachment[] Attachments;
|
||||||
[JsonProperty(PropertyName = "content")]
|
[JsonProperty(PropertyName = "content")]
|
||||||
public string Content;
|
public string Content;
|
||||||
[JsonProperty(PropertyName = "author")]
|
[JsonProperty(PropertyName = "author")]
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using Discord.API.Models;
|
|||||||
using Discord.Helpers;
|
using Discord.Helpers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@@ -100,7 +101,19 @@ namespace Discord
|
|||||||
if (model is API.Models.Message)
|
if (model is API.Models.Message)
|
||||||
{
|
{
|
||||||
var extendedModel = model as API.Models.Message;
|
var extendedModel = model as API.Models.Message;
|
||||||
message.Attachments = extendedModel.Attachments;
|
if (extendedModel.Attachments != null)
|
||||||
|
{
|
||||||
|
message.Attachments = extendedModel.Attachments.Select(x => new Message.Attachment
|
||||||
|
{
|
||||||
|
Id = x.Id,
|
||||||
|
Url = x.Url,
|
||||||
|
ProxyUrl = x.ProxyUrl,
|
||||||
|
Size = x.Size,
|
||||||
|
Filename = x.Filename
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
extendedModel.Attachments = null;
|
||||||
message.Embeds = extendedModel.Embeds;
|
message.Embeds = extendedModel.Embeds;
|
||||||
message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
|
message.IsMentioningEveryone = extendedModel.IsMentioningEveryone;
|
||||||
message.IsTTS = extendedModel.IsTextToSpeech;
|
message.IsTTS = extendedModel.IsTextToSpeech;
|
||||||
@@ -802,6 +815,18 @@ namespace Discord
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task SendFile(Channel channel, string path)
|
||||||
|
=> SendFile(channel.Id, path);
|
||||||
|
public Task SendFile(string channelId, string path)
|
||||||
|
=> SendFile(channelId, File.OpenRead(path), Path.GetFileName(path));
|
||||||
|
public Task SendFile(Channel channel, Stream stream, string filename = null)
|
||||||
|
=> SendFile(channel.Id, stream, filename);
|
||||||
|
public Task SendFile(string channelId, Stream stream, string filename = null)
|
||||||
|
{
|
||||||
|
return DiscordAPI.SendFile(channelId, stream, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Voice
|
//Voice
|
||||||
public Task Mute(Server server, User user)
|
public Task Mute(Server server, User user)
|
||||||
=> Mute(server.Id, user.Id);
|
=> Mute(server.Id, user.Id);
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ using System.Net.Http;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.IO;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace Discord.Helpers
|
namespace Discord.Helpers
|
||||||
{
|
{
|
||||||
@@ -55,9 +57,9 @@ namespace Discord.Helpers
|
|||||||
|
|
||||||
internal static Task<ResponseT> Post<ResponseT>(string path, object data)
|
internal static Task<ResponseT> Post<ResponseT>(string path, object data)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(HttpMethod.Post, path, data);
|
=> Send<ResponseT>(HttpMethod.Post, path, AsJson(data));
|
||||||
internal static Task<string> Post(string path, object data)
|
internal static Task<string> Post(string path, object data)
|
||||||
=> Send(HttpMethod.Post, path, data);
|
=> Send(HttpMethod.Post, path, AsJson(data));
|
||||||
internal static Task<ResponseT> Post<ResponseT>(string path)
|
internal static Task<ResponseT> Post<ResponseT>(string path)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(HttpMethod.Post, path, null);
|
=> Send<ResponseT>(HttpMethod.Post, path, null);
|
||||||
@@ -66,9 +68,9 @@ namespace Discord.Helpers
|
|||||||
|
|
||||||
internal static Task<ResponseT> Put<ResponseT>(string path, object data)
|
internal static Task<ResponseT> Put<ResponseT>(string path, object data)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(HttpMethod.Put, path, data);
|
=> Send<ResponseT>(HttpMethod.Put, path, AsJson(data));
|
||||||
internal static Task<string> Put(string path, object data)
|
internal static Task<string> Put(string path, object data)
|
||||||
=> Send(HttpMethod.Put, path, data);
|
=> Send(HttpMethod.Put, path, AsJson(data));
|
||||||
internal static Task<ResponseT> Put<ResponseT>(string path)
|
internal static Task<ResponseT> Put<ResponseT>(string path)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(HttpMethod.Put, path, null);
|
=> Send<ResponseT>(HttpMethod.Put, path, null);
|
||||||
@@ -77,9 +79,9 @@ namespace Discord.Helpers
|
|||||||
|
|
||||||
internal static Task<ResponseT> Patch<ResponseT>(string path, object data)
|
internal static Task<ResponseT> Patch<ResponseT>(string path, object data)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(_patch, path, data);
|
=> Send<ResponseT>(_patch, path, AsJson(data));
|
||||||
internal static Task<string> Patch(string path, object data)
|
internal static Task<string> Patch(string path, object data)
|
||||||
=> Send(_patch, path, data);
|
=> Send(_patch, path, AsJson(data));
|
||||||
internal static Task<ResponseT> Patch<ResponseT>(string path)
|
internal static Task<ResponseT> Patch<ResponseT>(string path)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(_patch, path, null);
|
=> Send<ResponseT>(_patch, path, null);
|
||||||
@@ -88,49 +90,52 @@ namespace Discord.Helpers
|
|||||||
|
|
||||||
internal static Task<ResponseT> Delete<ResponseT>(string path, object data)
|
internal static Task<ResponseT> Delete<ResponseT>(string path, object data)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(HttpMethod.Delete, path, data);
|
=> Send<ResponseT>(HttpMethod.Delete, path, AsJson(data));
|
||||||
internal static Task<string> Delete(string path, object data)
|
internal static Task<string> Delete(string path, object data)
|
||||||
=> Send(HttpMethod.Delete, path, data);
|
=> Send(HttpMethod.Delete, path, AsJson(data));
|
||||||
internal static Task<ResponseT> Delete<ResponseT>(string path)
|
internal static Task<ResponseT> Delete<ResponseT>(string path)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
=> Send<ResponseT>(HttpMethod.Delete, path, null);
|
=> Send<ResponseT>(HttpMethod.Delete, path, null);
|
||||||
internal static Task<string> Delete(string path)
|
internal static Task<string> Delete(string path)
|
||||||
=> Send(HttpMethod.Delete, path, null);
|
=> Send(HttpMethod.Delete, path, null);
|
||||||
|
|
||||||
internal static async Task<ResponseT> Send<ResponseT>(HttpMethod method, string path, object data)
|
internal static Task<ResponseT> File<ResponseT>(string path, Stream stream, string filename = null)
|
||||||
|
where ResponseT : class
|
||||||
|
=> Send<ResponseT>(HttpMethod.Post, path, AsFormData(stream, filename));
|
||||||
|
internal static Task<string> File(string path, Stream stream, string filename = null)
|
||||||
|
=> Send(HttpMethod.Post, path, AsFormData(stream, filename));
|
||||||
|
|
||||||
|
private static async Task<ResponseT> Send<ResponseT>(HttpMethod method, string path, HttpContent content)
|
||||||
where ResponseT : class
|
where ResponseT : class
|
||||||
{
|
{
|
||||||
string requestJson = data != null ? JsonConvert.SerializeObject(data) : null;
|
string responseJson = await SendRequest(method, path, content, true);
|
||||||
string responseJson = await SendRequest(method, path, requestJson, true);
|
|
||||||
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
var response = JsonConvert.DeserializeObject<ResponseT>(responseJson);
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CheckResponse(responseJson, response);
|
CheckResponse(responseJson, response);
|
||||||
#endif
|
#endif
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
internal static async Task<string> Send(HttpMethod method, string path, object data)
|
private static async Task<string> Send(HttpMethod method, string path, HttpContent content)
|
||||||
{
|
{
|
||||||
string requestJson = data != null ? JsonConvert.SerializeObject(data) : null;
|
string responseJson = await SendRequest(method, path, content, _isDebug);
|
||||||
string responseJson = await SendRequest(method, path, requestJson, _isDebug);
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
CheckEmptyResponse(responseJson);
|
CheckEmptyResponse(responseJson);
|
||||||
#endif
|
#endif
|
||||||
return responseJson;
|
return responseJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<string> SendRequest(HttpMethod method, string path, string data, bool hasResponse)
|
private static async Task<string> SendRequest(HttpMethod method, string path, HttpContent content, bool hasResponse)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Stopwatch stopwatch = Stopwatch.StartNew();
|
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||||
#endif
|
#endif
|
||||||
HttpRequestMessage msg = new HttpRequestMessage(method, path);
|
HttpRequestMessage msg = new HttpRequestMessage(method, path);
|
||||||
|
if (content != null)
|
||||||
if (data != null)
|
msg.Content = content;
|
||||||
msg.Content = new StringContent(data, Encoding.UTF8, "application/json");
|
|
||||||
|
|
||||||
string result;
|
string result;
|
||||||
HttpResponseMessage response;
|
HttpResponseMessage response;
|
||||||
if (hasResponse)
|
if (hasResponse)
|
||||||
{
|
{
|
||||||
response = await _client.SendAsync(msg, HttpCompletionOption.ResponseContentRead);
|
response = await _client.SendAsync(msg, HttpCompletionOption.ResponseContentRead);
|
||||||
if (!response.IsSuccessStatusCode)
|
if (!response.IsSuccessStatusCode)
|
||||||
@@ -167,5 +172,16 @@ namespace Discord.Helpers
|
|||||||
throw new Exception("API check failed: Response is not empty.");
|
throw new Exception("API check failed: Response is not empty.");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
private static StringContent AsJson(object obj)
|
||||||
|
{
|
||||||
|
return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");
|
||||||
|
}
|
||||||
|
private static MultipartFormDataContent AsFormData(Stream stream, string filename)
|
||||||
|
{
|
||||||
|
var content = new MultipartFormDataContent("Upload----" + DateTime.Now.ToString(CultureInfo.InvariantCulture));
|
||||||
|
content.Add(new StreamContent(stream), "file", filename);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ namespace Discord
|
|||||||
{
|
{
|
||||||
public sealed class Message
|
public sealed class Message
|
||||||
{
|
{
|
||||||
|
public struct Attachment
|
||||||
|
{
|
||||||
|
public string Id;
|
||||||
|
public string Url;
|
||||||
|
public string ProxyUrl;
|
||||||
|
public int Size;
|
||||||
|
public string Filename;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly DiscordClient _client;
|
private readonly DiscordClient _client;
|
||||||
|
|
||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
@@ -15,6 +24,7 @@ namespace Discord
|
|||||||
public bool IsTTS { get; internal set; }
|
public bool IsTTS { get; internal set; }
|
||||||
public string Text { get; internal set; }
|
public string Text { get; internal set; }
|
||||||
public DateTime Timestamp { get; internal set; }
|
public DateTime Timestamp { get; internal set; }
|
||||||
|
public Attachment[] Attachments { get; internal set; }
|
||||||
|
|
||||||
public string[] MentionIds { get; internal set; }
|
public string[] MentionIds { get; internal set; }
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
@@ -29,7 +39,6 @@ namespace Discord
|
|||||||
public User User => _client.GetUser(UserId);
|
public User User => _client.GetUser(UserId);
|
||||||
|
|
||||||
//Not Implemented
|
//Not Implemented
|
||||||
public object[] Attachments { get; internal set; }
|
|
||||||
public object[] Embeds { get; internal set; }
|
public object[] Embeds { get; internal set; }
|
||||||
|
|
||||||
internal Message(string id, string channelId, DiscordClient client)
|
internal Message(string id, string channelId, DiscordClient client)
|
||||||
|
|||||||
Reference in New Issue
Block a user