Skip to content

Commit c75ce71

Browse files
committed
Add methods to get a reply template and sent a reply
1 parent ec00da3 commit c75ce71

3 files changed

Lines changed: 146 additions & 8 deletions

File tree

API.Test/MessagesTests.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,20 @@ public void GetDrafts()
100100
else
101101
Assert.Fail();
102102
}
103+
104+
[Test]
105+
public void GetReplyForm()
106+
{
107+
Client.LoginAsync(s_Server, s_LoginName, s_UserName, s_Password).Wait();
108+
109+
Task<MessagePreview[]> messages = Client.GetMessageInboxAsync();
110+
messages.Wait();
111+
112+
Task<Message> drafts = Client.GetReplyFormAsync(messages.Result[0]);
113+
drafts.Wait();
114+
if (drafts.Result != null)
115+
Assert.Pass();
116+
else
117+
Assert.Fail();
118+
}
103119
}

WebUntisAPI.Client/Models/Messages/Message.cs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System;
33
using System.Collections.Generic;
44
using System.Diagnostics;
5+
using System.Linq;
56
using WebUntisAPI.Client.Converter;
67

78
namespace WebUntisAPI.Client.Models.Messages
@@ -22,7 +23,7 @@ public class Message
2223
/// The subject of the message
2324
/// </summary>
2425
[JsonProperty("subject")]
25-
public string Subject { get; set; }
26+
public string Subject { get; set; } = string.Empty;
2627

2728
/// <summary>
2829
/// The sender of the message (only for messages in the inbox)
@@ -34,13 +35,13 @@ public class Message
3435
/// Is the message a reply
3536
/// </summary>
3637
[JsonProperty("isReply")]
37-
public bool IsReply { get; set; }
38+
public bool IsReply { get; set; } = false;
3839

3940
/// <summary>
4041
/// Can you reply the message
4142
/// </summary>
4243
[JsonProperty("isReplyAllowed")]
43-
public bool IsReplyAllowed { get; set; }
44+
public bool IsReplyAllowed { get; set; } = true;
4445

4546
/// <summary>
4647
/// The send time of the message
@@ -53,7 +54,7 @@ public class Message
5354
/// Is allowed to delete the message
5455
/// </summary>
5556
[JsonProperty("allowMessageDeletion")]
56-
public bool AllowMessageDeletion { get; set; }
57+
public bool AllowMessageDeletion { get; set; } = true;
5758

5859
/// <summary>
5960
/// Idk
@@ -65,22 +66,31 @@ public class Message
6566
/// All the recipients for a message (only for self-sends messages)
6667
/// </summary>
6768
/// <remarks>
68-
/// When its <see langword="null"/> is the recipient the current user
69+
/// When its epmpty is the recipient the current user
6970
/// </remarks>
7071
[JsonProperty("recipientPersons")]
71-
public List<MessagePerson> Recipients { get; set; } = null;
72+
public List<MessagePerson> Recipients { get; set; } = new List<MessagePerson>();
73+
74+
#pragma warning disable IDE0051
75+
[JsonProperty("recipient")]
76+
private MessagePerson Recipient
77+
#pragma warning restore IDE0051 // Nicht verwendete private Member entfernen
78+
{
79+
get => Recipients.FirstOrDefault();
80+
set => Recipients.Add(value);
81+
}
7282

7383
/// <summary>
7484
/// The full content of the message
7585
/// </summary>
7686
[JsonProperty("content")]
77-
public string Content { get; set; }
87+
public string Content { get; set; } = string.Empty;
7888

7989
/// <summary>
8090
/// Is the message revoked
8191
/// </summary>
8292
[JsonProperty("isRevoked")]
83-
public bool IsRevoked { get; set; }
93+
public bool IsRevoked { get; set; } = false;
8494

8595
/// <summary>
8696
/// The file attachments of the message

WebUntisAPI.Client/WebUntisClient.Messages.cs

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,118 @@ public async Task<MessagePreview> SendMessageAsync(string subject, string conten
218218

219219
return JsonConvert.DeserializeObject<MessagePreview>(await response.Content.ReadAsStringAsync());
220220
}
221+
222+
/// <summary>
223+
/// Get a message instance as template for the reply
224+
/// </summary>
225+
/// <param name="replyMessage">The message you want to reply</param>
226+
/// <param name="ct">Cancellation token</param>
227+
/// <returns>The template</returns>
228+
/// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
229+
/// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
230+
/// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
231+
public async Task<Message> GetReplyFormAsync(MessagePreview replyMessage, CancellationToken ct = default)
232+
{
233+
return await GetReplyFormAsync(new Message() { Id = replyMessage.Id }, ct);
234+
}
235+
236+
/// <summary>
237+
/// Get a message instance as template for the reply
238+
/// </summary>
239+
/// <param name="replyMessage">The message you want to reply</param>
240+
/// <param name="ct">Cancellation token</param>
241+
/// <returns>The template</returns>
242+
/// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
243+
/// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
244+
/// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
245+
public async Task<Message> GetReplyFormAsync(Message replyMessage, CancellationToken ct = default)
246+
{
247+
string responseString = await MakeAPIGetRequestAsync($"/WebUntis/api/rest/view/v1/messages/{replyMessage.Id}/reply-form", ct);
248+
return JObject.Parse(responseString).ToObject<Message>();
249+
}
250+
251+
/// <summary>
252+
/// Reply a message
253+
/// </summary>
254+
/// <remarks>
255+
/// Use this only for incoming messages and check if it is allowed
256+
/// </remarks>
257+
/// <param name="replyMessage">The message to reply</param>
258+
/// <param name="subject">The subject</param>
259+
/// <param name="content">The content (use <![CDATA[<br>]]> for line breaks</param>
260+
/// <param name="attachments">The attachments to send (Item1 is the name and Item2 the content)</param>
261+
/// <param name="ct">Cancellation token</param>
262+
/// <returns>The preview of the sent message</returns>
263+
/// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
264+
/// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
265+
/// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
266+
public async Task ReplyMessageAsync(Message replyMessage, string subject, string content, Tuple<string, Stream>[] attachments = null, CancellationToken ct = default)
267+
{
268+
// Check for disposing
269+
if (_disposedValue)
270+
throw new ObjectDisposedException(GetType().FullName);
271+
272+
// Check if you logged in
273+
if (!LoggedIn)
274+
throw new UnauthorizedAccessException("You're not logged in");
275+
276+
MultipartFormDataContent requestContent = new MultipartFormDataContent();
277+
278+
// Json part
279+
StringWriter sw = new StringWriter();
280+
using (JsonWriter writer = new JsonTextWriter(sw))
281+
{
282+
writer.WriteStartObject();
283+
284+
writer.WritePropertyName("subject");
285+
writer.WriteValue(subject);
286+
287+
writer.WritePropertyName("content");
288+
writer.WriteValue(content);
289+
290+
writer.WritePropertyName("oneDriveAttachments");
291+
writer.WriteStartArray();
292+
writer.WriteEndArray();
293+
294+
writer.WriteEndObject();
295+
296+
StringContent jsonContent = new StringContent(sw.GetStringBuilder().ToString(), Encoding.UTF8, "application/json");
297+
requestContent.Add(jsonContent, "request", "blob");
298+
}
299+
300+
// Attachment part
301+
foreach (Tuple<string, Stream> attachment in attachments)
302+
{
303+
byte[] buffer = new byte[attachment.Item2.Length];
304+
int bytesRead = await attachment.Item2.ReadAsync(buffer, 0, buffer.Length);
305+
ByteArrayContent fileContent = new ByteArrayContent(buffer, 0, bytesRead);
306+
307+
fileContent.Headers.Add("Content-Type", "application/x-msdownload");
308+
requestContent.Add(fileContent, "attachments", attachment.Item1);
309+
}
310+
311+
HttpRequestMessage request = new HttpRequestMessage()
312+
{
313+
Method = HttpMethod.Post,
314+
RequestUri = new Uri(ServerUrl + $"/WebUntis/api/rest/view/v2/messages/{replyMessage.Id}/reply"),
315+
Content = requestContent
316+
};
317+
request.Headers.Add("JSESSIONID", _sessonId);
318+
request.Headers.Add("schoolname", _schoolName);
319+
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _bearerToken);
320+
321+
HttpResponseMessage response = await _client.SendAsync(request, ct);
322+
323+
// Verify response
324+
if (response.StatusCode == HttpStatusCode.Unauthorized || response.StatusCode == HttpStatusCode.Forbidden)
325+
{
326+
_ = LogoutAsync();
327+
throw new UnauthorizedAccessException("You're not logged in");
328+
}
329+
330+
if (response.StatusCode != HttpStatusCode.OK)
331+
throw new HttpRequestException($"There was an error while the http request (Code: {response.StatusCode}).");
332+
}
221333

222334
/// <summary>
223335
/// Revoke a message (move back into drafts)(only for self-sent messages!)

0 commit comments

Comments
 (0)