Skip to content

Commit bd97d58

Browse files
committed
added work context. made the services work with provided context.
1 parent ed47d7e commit bd97d58

17 files changed

+287
-82
lines changed

RedmineTelegramBot.Core/Commands.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace RedmineTelegramBot.Core
1010
public static class Commands
1111
{
1212
public const string Cancel = "cancel";
13+
public const string Register = "register";
1314
public const string ProjectList = "projectlist";
1415
public const string AddIssue = "addissue";
1516

@@ -22,6 +23,11 @@ public static List<BotCommand> GetBotCommands()
2223
Description = "Cancel current command."
2324
},
2425
new BotCommand()
26+
{
27+
Command = Register,
28+
Description = "Register user & secret."
29+
},
30+
new BotCommand()
2531
{
2632
Command = ProjectList,
2733
Description = "Returns list of projects ids and project names."
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using RedmineTelegramBot.Core;
2+
using System;
3+
4+
namespace RedmineTelegramBot.Core
5+
{
6+
public class ContextualServiceProvider : IServiceProvider
7+
{
8+
private readonly IWorkContext _workContext;
9+
private readonly IServiceProvider _wrappedServiceProvider;
10+
11+
public ContextualServiceProvider(IWorkContext workContext, IServiceProvider wrappedServiceProvider)
12+
{
13+
_workContext = workContext;
14+
_wrappedServiceProvider = wrappedServiceProvider;
15+
}
16+
17+
public object GetService(Type serviceType)
18+
{
19+
if (serviceType == typeof(IWorkContext))
20+
{
21+
return _workContext;
22+
}
23+
else
24+
{
25+
return _wrappedServiceProvider.GetService(serviceType);
26+
}
27+
}
28+
}
29+
}

RedmineTelegramBot.Core/ConversationHandler.cs

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using RedmineTelegramBot.Core.Models;
1+
using RedmineTelegramBot.Core.Data;
2+
using RedmineTelegramBot.Core.Models;
23
using System;
34
using System.Linq;
45
using System.Threading.Tasks;
@@ -9,23 +10,32 @@ namespace RedmineTelegramBot.Core
910
{
1011
public class ConversationHandler : IConversationHandler
1112
{
13+
private readonly IWorkContext _workContext;
1214
private readonly ITelegramBotClient _telegramBotClient;
1315
private readonly IRedmineApiClient _redmineApiClient;
16+
private readonly IUserSettingsRepository _userSettingsRepository;
17+
private readonly IConversationStateRepository _conversationStateRepository;
1418

15-
private readonly ConversationStateModel _conversationState;
19+
private ConversationStateModel _conversationState;
1620

1721
public ConversationHandler(
22+
IWorkContext workContext,
1823
ITelegramBotClient telegramBotClient,
1924
IRedmineApiClient redmineApiClient,
20-
ConversationStateModel conversationState)
25+
IUserSettingsRepository userSettingsRepository,
26+
IConversationStateRepository conversationStateRepository)
2127
{
28+
_workContext = workContext;
2229
_telegramBotClient = telegramBotClient;
2330
_redmineApiClient = redmineApiClient;
24-
_conversationState = conversationState;
31+
_userSettingsRepository = userSettingsRepository;
32+
_conversationStateRepository = conversationStateRepository;
2533
}
2634

2735
public async Task Handle(Message message)
2836
{
37+
_conversationState = _conversationStateRepository.GetConversationState(_workContext.Username);
38+
2939
if (message.Text == $"/{Commands.Cancel}")
3040
{
3141
await ChangeState(message, State.Command);
@@ -35,6 +45,18 @@ public async Task Handle(Message message)
3545

3646
if (_conversationState.State == State.Command)
3747
{
48+
if (message.Text == $"/{Commands.Register}")
49+
{
50+
await ChangeState(message, State.RegisterSecret);
51+
return;
52+
}
53+
54+
if (!CheckRegistration())
55+
{
56+
await ReplyMessage(message, "You must register your redmine secret before using any functionality.");
57+
return;
58+
}
59+
3860
if (message.Text == $"/{Commands.ProjectList}")
3961
{
4062
await ChangeState(message, State.SearchProjects);
@@ -49,6 +71,23 @@ public async Task Handle(Message message)
4971
}
5072
}
5173

74+
if (_conversationState.State == State.RegisterSecret)
75+
{
76+
var settings = _userSettingsRepository.GetSettings(_conversationState.Username);
77+
if (settings == null)
78+
{
79+
settings = new UserSettings()
80+
{
81+
Username = _conversationState.Username
82+
};
83+
}
84+
settings.RedmineSecret = message.Text;
85+
_userSettingsRepository.StoreSettings(settings);
86+
await ReplyMessage(message, "User registered.");
87+
await ChangeState(message, State.Command);
88+
return;
89+
}
90+
5291
if (_conversationState.State == State.SearchProjects)
5392
{
5493
await ReplyWithProjectList(message, message.Text);
@@ -87,11 +126,26 @@ public async Task Handle(Message message)
87126
await ReplyMessage(message, "Unknown text or command:\n" + message.Text);
88127
}
89128

129+
private bool CheckRegistration()
130+
{
131+
var userSettings = _userSettingsRepository.GetSettings(_workContext.Username);
132+
if (userSettings == null || string.IsNullOrEmpty(userSettings.RedmineSecret))
133+
{
134+
return false;
135+
}
136+
137+
return true;
138+
}
139+
90140
private async Task ChangeState(Message message, State state)
91141
{
92142
_conversationState.State = state;
93143

94-
if (state == State.AddIssueSetIssueProjectId)
144+
if (state == State.RegisterSecret)
145+
{
146+
await ReplyMessage(message, "Redmine Secret:\n");
147+
}
148+
else if (state == State.AddIssueSetIssueProjectId)
95149
{
96150
await ReplyMessage(message, "Project Id:\n");
97151
}
@@ -172,5 +226,10 @@ private async Task AddIssue(Message message)
172226
await ReplyMessage(message, "Issue created.");
173227
}
174228
}
229+
230+
public void SaveState()
231+
{
232+
_conversationStateRepository.StoreConversationState(_conversationState);
233+
}
175234
}
176235
}

RedmineTelegramBot.Core/ConversationHandlerFactory.cs

Lines changed: 0 additions & 34 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using RedmineTelegramBot.Core.Models;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
8+
namespace RedmineTelegramBot.Core.Data
9+
{
10+
public interface IConversationStateRepository
11+
{
12+
ConversationStateModel GetConversationState(string username);
13+
14+
void StoreConversationState(ConversationStateModel conversationState);
15+
16+
void DeleteConversationState(string username);
17+
}
18+
}

RedmineTelegramBot.Core/Data/IUserSettingsRepository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace RedmineTelegramBot.Core.Data
88
{
99
public interface IUserSettingsRepository
1010
{
11-
void StoreSettings(string username, UserSettings userSettings);
11+
void StoreSettings(UserSettings userSettings);
1212

1313
UserSettings GetSettings(string username);
1414
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using RedmineTelegramBot.Core.Models;
2+
using System.Collections.Generic;
3+
using System.Text.Json;
4+
5+
namespace RedmineTelegramBot.Core.Data
6+
{
7+
public class InMemoryConversationStateRepository : IConversationStateRepository
8+
{
9+
// store serialized versions of the state to avoid concurrency issues and make it behave like a db.
10+
private readonly Dictionary<string, string> _store;
11+
12+
public InMemoryConversationStateRepository()
13+
{
14+
_store = new Dictionary<string, string>();
15+
}
16+
17+
public void DeleteConversationState(string username)
18+
{
19+
if (!_store.ContainsKey(username))
20+
throw new BotException("Conversation state for this username does not exists!");
21+
22+
_store.Remove(username);
23+
}
24+
25+
public ConversationStateModel GetConversationState(string username)
26+
{
27+
if (_store.ContainsKey(username))
28+
{
29+
return JsonSerializer.Deserialize<ConversationStateModel>(_store[username]);
30+
}
31+
32+
return null;
33+
}
34+
35+
public void StoreConversationState(ConversationStateModel conversationState)
36+
{
37+
_store[conversationState.Username] = JsonSerializer.Serialize(conversationState);
38+
}
39+
}
40+
}

RedmineTelegramBot.Core/Data/UsersSettingsFileRepository.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ public UserSettings GetSettings(string username)
2929
return null;
3030
}
3131

32-
public void StoreSettings(string username, UserSettings userSettings)
32+
public void StoreSettings(UserSettings userSettings)
3333
{
34-
var path = MakePath(username);
34+
if (string.IsNullOrEmpty(userSettings.Username))
35+
throw new BotException("Username can't be null or empty!");
36+
37+
var path = MakePath(userSettings.Username);
3538
var json = JsonSerializer.Serialize(userSettings);
3639
File.WriteAllText(path, json);
3740
}

RedmineTelegramBot.Core/IConversationHandler.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,7 @@ namespace RedmineTelegramBot.Core
1111
public interface IConversationHandler
1212
{
1313
Task Handle(Message message);
14+
15+
void SaveState();
1416
}
1517
}

RedmineTelegramBot.Core/IConversationHandlerFactory.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

0 commit comments

Comments
 (0)