Доступ к пользовательским данным через StateClient для локального бота, который не зарегистрирован без активности
Привет всем, я пытаюсь сохранить некоторые данные из контроллера входа в хранилище данных пользователей.
[HttpGet, Route("api/{channelId}/{userId}/authorize")]
public async System.Threading.Tasks.Task<HttpResponseMessage> Authorize(string channelId, string userId, string code)
{
string protocalAndDomain = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority);
AuthenticationContext ac = new AuthenticationContext(Constants.AD_AUTH_CONTEXT);
ClientCredential cc = new ClientCredential(Constants.AD_CLIENT_ID, Constants.AD_CLIENT_SECRET);
AuthenticationResult ar = await ac.AcquireTokenByAuthorizationCodeAsync(code, new Uri(protocalAndDomain + "/api/" + channelId + "/" + userId + "/authorize"), cc);
MicrosoftAppCredentials.TrustServiceUrl(protocalAndDomain, DateTime.Now.AddHours(1));
if (!String.IsNullOrEmpty(ar.AccessToken))
{
// Store access token & User Id to bot state
//var botCred = new MicrosoftAppCredentials(Constants.MS_APP_ID, Constants.MS_APP_PASSWORD);
//https://state.botframework.com
using (var sc = new StateClient(new Uri("http://localhost:3979/")))
if (sc != null)
{
var botData = new BotData(data: null, eTag: "*");
botData.SetProperty("accessToken", ar.AccessToken);
botData.SetProperty("userEmail", ar.UserInfo.DisplayableId);
//i get a 401 response here
await sc.BotState.SetUserDataAsync(channelId, userId, botData);
}
var response = Request.CreateResponse(HttpStatusCode.Moved);
response.Headers.Location = new Uri("/loggedin.html", UriKind.Relative);
return response;
}
else
return Request.CreateResponse(HttpStatusCode.Unauthorized);
}
Я видел примеры, в которых вы можете использовать AppId appPassword для доступа к состоянию бота, но, насколько я понимаю, они недоступны до тех пор, пока ваш бот не будет опубликован / зарегистрирован на портале приложений Azuer, чего я сейчас не могу сделать.
или что вы можете получить к нему доступ через действие, к которому у меня снова нет доступа.
на самом деле это всего лишь временное решение, в котором я планирую в конечном итоге сохранить пользовательские данные в хранилище таблиц Azure, однако в настоящее время я хотел бы получить временное решение; Я рассматриваю сериализацию и десериализацию словаря в локальный текстовый файл, но сейчас это кажется излишним, и кажется глупым, что я не могу локально сохранить пользовательские данные, не зарегистрировав свое приложение в Azure.
ура любая помощь высоко ценится.
1 ответ
С этой строкой:
var sc = new StateClient(new Uri("http://localhost:3979/"))
вы инструктируете BotBuilder использовать государственную службу в http://localhost:3979/
Но в этой конечной точке нет государственной службы.
Если вы хотите иметь временное решение, пока вы не добавите хранилище таблиц Azure, вы можете использовать InMemoryDataStore
:
protected void Application_Start()
{
Conversation.UpdateContainer(
builder =>
{
builder.RegisterModule(new AzureModule(Assembly.GetExecutingAssembly()));
var store = new InMemoryDataStore(); // volatile in-memory store
builder.Register(c => store)
.Keyed<IBotDataStore<BotData>>(AzureModule.Key_DataStore)
.AsSelf()
.SingleInstance();
});
GlobalConfiguration.Configure(WebApiConfig.Register);
}
Примечание. Для этого требуется пакет nuget для расширений Azure https://www.nuget.org/packages/Microsoft.Bot.Builder.Azure/
Как только InMemoryDataStore зарегистрирован, вы можете получить к нему доступ, используя что-то вроде:
var message = new Activity()
{
ChannelId = ChannelIds.Directline,
From = new ChannelAccount(userId, userName),
Recipient = new ChannelAccount(botId, botName),
Conversation = new ConversationAccount(id: conversationId),
ServiceUrl = serviceUrl
}.AsMessageActivity();
using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, message))
{
var botDataStore = scope.Resolve<IBotDataStore<BotData>>();
var key = new AddressKey()
{
BotId = message.Recipient.Id,
ChannelId = message.ChannelId,
UserId = message.From.Id,
ConversationId = message.Conversation.Id,
ServiceUrl = message.ServiceUrl
};
var userData = await botDataStore.LoadAsync(key, BotStoreType.BotUserData, CancellationToken.None);
userData.SetProperty("key 1", "value1");
userData.SetProperty("key 2", "value2");
await botDataStore.SaveAsync(key, BotStoreType.BotUserData, userData, CancellationToken.None);
await botDataStore.FlushAsync(key, CancellationToken.None);
}