Skip to content

Commit f8e5f72

Browse files
committed
fixed #4 added feature for assigning issues to users.
1 parent 9a74080 commit f8e5f72

File tree

7 files changed

+146
-1
lines changed

7 files changed

+146
-1
lines changed

RedmineTelegramBot.Core/ConversationHandler.cs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ public async Task Handle(Message message)
8181
await ChangeState(message, State.AddIssueSetIssueProjectId);
8282
return;
8383
}
84+
85+
if (message.Text == $"/{Commands.AssignIssue}")
86+
{
87+
if (_conversationState.LastIssueId == 0)
88+
{
89+
await ReplyMessage(message, "No recently created issue exists.");
90+
return;
91+
}
92+
93+
await ChangeState(message, State.AssignIssueSetUserId);
94+
return;
95+
}
8496
}
8597

8698
if (_conversationState.State == State.RegisterSecret)
@@ -135,6 +147,13 @@ public async Task Handle(Message message)
135147
return;
136148
}
137149

150+
if (_conversationState.State == State.AssignIssueSetUserId)
151+
{
152+
await AssignIssue(message);
153+
await ChangeState(message, State.Command);
154+
return;
155+
}
156+
138157
await ReplyMessage(message, "Unknown text or command:\n" + message.Text);
139158
}
140159

@@ -185,6 +204,11 @@ private async Task ChangeState(Message message, State state)
185204
{
186205
await ReplyMessage(message, "Search pattern (type * for all):\n");
187206
}
207+
else if (state == State.AssignIssueSetUserId)
208+
{
209+
await ReplyWithUserList(message);
210+
await ReplyMessage(message, "User Id:\n");
211+
}
188212
}
189213

190214
private Task ReplyMessage(Message message, string text)
@@ -221,7 +245,7 @@ private async Task ReplyWithProjectList(Message message, string searchPattern)
221245
{
222246
await ReplyMessage(message, "No project found matching the filter.");
223247
}
224-
248+
225249
await ChangeState(message, State.Command);
226250
}
227251

@@ -233,6 +257,14 @@ private async Task ReplyWithTrackerList(Message message)
233257
await ReplyMessage(message, $"Trackers:\n{trackersStr}");
234258
}
235259

260+
private async Task ReplyWithUserList(Message message)
261+
{
262+
var users = await _redmineApiClient.GetUsers();
263+
var trackersStr = string.Join("\n", users.OrderBy(r => r.Id).Select(r => $"{r.Id}) {r.Login} ({r.Firstname} {r.Lastname})"));
264+
265+
await ReplyMessage(message, $"Users:\n{trackersStr}");
266+
}
267+
236268
private async Task AddIssue(Message message)
237269
{
238270
var response = await _redmineApiClient.AddIssue(_conversationState.CreateIssueModel);
@@ -247,6 +279,21 @@ private async Task AddIssue(Message message)
247279
}
248280
}
249281

282+
private async Task AssignIssue(Message message)
283+
{
284+
var model = new AssignIssueModel();
285+
model.issue.assigned_to_id = int.Parse(message.Text);
286+
var response = await _redmineApiClient.AssignIssue(_conversationState.LastIssueId, model);
287+
if (response.Errors != null && response.Errors.Count > 0)
288+
{
289+
await ReplyMessage(message, string.Join("\n", response.Errors));
290+
}
291+
else
292+
{
293+
await ReplyMessage(message, "Issue assigned to user.");
294+
}
295+
}
296+
250297
public void SaveState()
251298
{
252299
_conversationStateRepository.StoreConversationState(_conversationState);

RedmineTelegramBot.Core/IRedmineApiClient.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ public interface IRedmineApiClient
1313

1414
Task<IssueAddedModel> AddIssue(AddIssueModel issue);
1515

16+
Task<RedmineResponseModel> AssignIssue(int id, AssignIssueModel issue);
17+
1618
Task<IEnumerable<RedmineTrackerModel>> GetTrackers();
19+
20+
Task<IEnumerable<RedmineUserModel>> GetUsers();
1721
}
1822
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace RedmineTelegramBot.Core.Models
8+
{
9+
public class AssignIssueModel
10+
{
11+
public IssueModel issue { get; set; }
12+
13+
public AssignIssueModel()
14+
{
15+
issue = new IssueModel();
16+
}
17+
18+
public class IssueModel
19+
{
20+
public int assigned_to_id { get; set; }
21+
}
22+
}
23+
}

RedmineTelegramBot.Core/Models/ConversationStateModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,7 @@ public enum State
3131
AddIssueSetIssueSubject,
3232
AddIssueSetIssueDescription,
3333
AddIssueSetTrackerId,
34+
// assign issue
35+
AssignIssueSetUserId
3436
}
3537
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace RedmineTelegramBot.Core.Models
8+
{
9+
public class RedmineGetUsersModel
10+
{
11+
public List<RedmineUserModel> Users { get; set; }
12+
13+
public int TotalCount { get; set; }
14+
15+
public int Offset { get; set; }
16+
17+
public int Limit { get; set; }
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace RedmineTelegramBot.Core.Models
8+
{
9+
public class RedmineUserModel
10+
{
11+
public int Id { get; set; }
12+
13+
public string Login { get; set; }
14+
15+
public string Firstname { get; set; }
16+
17+
public string Lastname { get; set; }
18+
}
19+
}

RedmineTelegramBot.Core/RedmineApiClient.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,36 @@ public async Task<IEnumerable<RedmineTrackerModel>> GetTrackers()
5656

5757
return result.Trackers;
5858
}
59+
60+
public Task<RedmineResponseModel> AssignIssue(int id, AssignIssueModel issue)
61+
{
62+
var client = _restClientFactory.CreateRestClient();
63+
64+
var request = new RestRequest($"/issues/{id}.json", DataFormat.Json);
65+
request.AddJsonBody(issue);
66+
67+
return client.PutAsync<RedmineResponseModel>(request);
68+
}
69+
70+
public async Task<IEnumerable<RedmineUserModel>> GetUsers()
71+
{
72+
var client = _restClientFactory.CreateRestClient();
73+
74+
var users = new List<RedmineUserModel>();
75+
var offset = 0;
76+
var limit = 100;
77+
var total = 9999;
78+
79+
while (offset < total)
80+
{
81+
var request = new RestRequest($"/users.json?offset={offset}&limit={limit}");
82+
var result = await client.GetAsync<RedmineGetUsersModel>(request);
83+
users.AddRange(result.Users);
84+
total = result.TotalCount;
85+
offset += limit;
86+
}
87+
88+
return users;
89+
}
5990
}
6091
}

0 commit comments

Comments
 (0)