@@ -65,19 +65,70 @@ public async Task<Dictionary<string, MessagePerson[]>> GetMessagePeopleAsync(Can
6565 }
6666
6767 /// <summary>
68- /// Get the you message inbox
68+ /// Get the your message inbox
6969 /// </summary>
7070 /// <param name="ct">Cancellation token</param>
71- /// <returns>The message previews </returns>
71+ /// <returns>The first value (messageInbox) are the normal inbox and the second value (confirmationMessages) are the messages that request a confirmation with <see cref="ConfirmMessageAsync(Message, CancellationToken)"/> </returns>
7272 /// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
7373 /// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
7474 /// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
75- public async Task < MessagePreview [ ] > GetMessageInboxAsync ( CancellationToken ct = default )
75+ public async Task < ( MessagePreview [ ] messageInbox , MessagePreview [ ] confirmationMessages ) > GetMessageInboxAsync ( CancellationToken ct = default )
7676 {
7777 string responseString = await MakeAPIGetRequestAsync ( "/WebUntis/api/rest/view/v1/messages" , ct ) ;
7878
79- JArray jsonMsg = JObject . Parse ( responseString ) . Value < JArray > ( "incomingMessages" ) ;
80- return new JsonSerializer ( ) . Deserialize < List < MessagePreview > > ( jsonMsg . CreateReader ( ) ) . ToArray ( ) ;
79+ JObject responseObject = JObject . Parse ( responseString ) ;
80+ MessagePreview [ ] inboxMsg = responseObject [ "incomingMessages" ] . ToObject < MessagePreview [ ] > ( ) ;
81+ MessagePreview [ ] readConfirmMsg = responseObject [ "readConfirmationMessages" ] . ToObject < MessagePreview [ ] > ( ) ;
82+
83+ return ( inboxMsg , readConfirmMsg ) ;
84+ }
85+
86+ /// <summary>
87+ /// Confirm a recived message
88+ /// </summary>
89+ /// <remarks>
90+ /// You should only use this for confirmation requested messages
91+ /// </remarks>
92+ /// <param name="message">The message to confirm</param>
93+ /// <param name="ct">Cancellation token</param>
94+ /// <returns>Informations about the confirm</returns>
95+ /// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
96+ /// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
97+ /// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
98+ public async Task < ConfirmationInformations > ConfirmMessageAsync ( Message message , CancellationToken ct = default )
99+ {
100+ if ( _disposedValue )
101+ throw new ObjectDisposedException ( GetType ( ) . FullName ) ;
102+
103+ if ( ! LoggedIn )
104+ throw new UnauthorizedAccessException ( "You're not logged in" ) ;
105+
106+ HttpRequestMessage request = new HttpRequestMessage ( )
107+ {
108+ Method = HttpMethod . Post ,
109+ RequestUri = new Uri ( ServerUrl + $ "/WebUntis/api/rest/view/v1/messages/{ message . Id } /read-confirmation")
110+ } ;
111+ request . Headers . Add ( "JSESSIONID" , _sessonId ) ;
112+ request . Headers . Add ( "schoolname" , _schoolName ) ;
113+ request . Headers . Authorization = new AuthenticationHeaderValue ( "Bearer" , _bearerToken ) ;
114+
115+ HttpResponseMessage response = await _client . SendAsync ( request , ct ) ;
116+
117+ // Check cancellation token
118+ if ( ct . IsCancellationRequested )
119+ return default ;
120+
121+ // Verify response
122+ if ( response . StatusCode == HttpStatusCode . Unauthorized || response . StatusCode == HttpStatusCode . Forbidden )
123+ {
124+ _ = LogoutAsync ( ) ;
125+ throw new UnauthorizedAccessException ( "You're not logged in" ) ;
126+ }
127+
128+ if ( response . StatusCode != HttpStatusCode . OK )
129+ throw new HttpRequestException ( $ "There was an error while the http request (Code: { response . StatusCode } ).") ;
130+
131+ return JObject . Parse ( await response . Content . ReadAsStringAsync ( ) ) . ToObject < ConfirmationInformations > ( ) ;
81132 }
82133
83134 /// <summary>
@@ -101,13 +152,14 @@ public async Task<MessagePreview[]> GetSentMessagesAsync(CancellationToken ct =
101152 /// </summary>
102153 /// <param name="draft">The draft that you want to send</param>
103154 /// <param name="recipients">The recipients for the message</param>
155+ /// <param name="requestConfirmation">Is a confirmation requested (You need the permission)</param>
104156 /// <param name="timeout">The time out for the attachment download (when the draft had attachments they must be downloaded to send them)</param>
105157 /// <param name="ct">Cancellation token</param>
106158 /// <returns>The preview of the sent message</returns>
107159 /// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
108160 /// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
109161 /// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
110- public async Task < MessagePreview > SendMessageAsync ( Draft draft , MessagePerson [ ] recipients , TimeSpan timeout , CancellationToken ct = default )
162+ public async Task < MessagePreview > SendMessageAsync ( Draft draft , MessagePerson [ ] recipients , bool requestConfirmation , TimeSpan timeout , CancellationToken ct = default )
111163 {
112164 Tuple < string , Stream > [ ] attachments = new Tuple < string , Stream > [ 0 ] ;
113165 if ( draft . Attachments . Count > 0 )
@@ -121,7 +173,7 @@ public async Task<MessagePreview> SendMessageAsync(Draft draft, MessagePerson[]
121173 attachments = attachmentTasks . Select ( attachment => new Tuple < string , Stream > ( attachment . Key , attachment . Value . Result ) ) . ToArray ( ) ;
122174 }
123175
124- return await SendMessageAsync ( draft . Subject , draft . Content , recipients , draft . ForbidReply , attachments , ct ) ;
176+ return await SendMessageAsync ( draft . Subject , draft . Content , recipients , requestConfirmation , draft . ForbidReply , attachments , ct ) ;
125177 }
126178
127179 /// <summary>
@@ -131,13 +183,14 @@ public async Task<MessagePreview> SendMessageAsync(Draft draft, MessagePerson[]
131183 /// <param name="content">The content (use <![CDATA[<br>]]> for line breaks</param>
132184 /// <param name="recipients">The recipients for the message</param>
133185 /// <param name="forbidReply">Is a reply forbidden (it need a permission to to that)</param>
186+ /// <param name="requestConfirmation">Is a confirmation requested (You need the permission)</param>
134187 /// <param name="attachments">The attachments to send (Item1 is the name and Item2 the content)</param>
135188 /// <param name="ct">Cancellation token</param>
136189 /// <returns>The preview of the sent message</returns>
137190 /// <exception cref="ObjectDisposedException">Thrown when the instance was disposed</exception>
138191 /// <exception cref="UnauthorizedAccessException">Thrown when you're logged in</exception>
139192 /// <exception cref="HttpRequestException">Thrown when an error happened while the http request</exception>
140- public async Task < MessagePreview > SendMessageAsync ( string subject , string content , MessagePerson [ ] recipients , bool forbidReply , Tuple < string , Stream > [ ] attachments = null , CancellationToken ct = default )
193+ public async Task < MessagePreview > SendMessageAsync ( string subject , string content , MessagePerson [ ] recipients , bool requestConfirmation , bool forbidReply , Tuple < string , Stream > [ ] attachments = null , CancellationToken ct = default )
141194 {
142195 // Check for disposing
143196 if ( _disposedValue )
@@ -162,7 +215,7 @@ public async Task<MessagePreview> SendMessageAsync(string subject, string conten
162215 writer . WriteValue ( content ) ;
163216
164217 writer . WritePropertyName ( "requestConfirmation" ) ;
165- writer . WriteValue ( false ) ;
218+ writer . WriteValue ( requestConfirmation ) ;
166219
167220 writer . WritePropertyName ( "recipientUserIds" ) ;
168221 writer . WriteStartArray ( ) ;
0 commit comments