Доступ к CosmosDB от разных ботов - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь читать и писать из / в базу данных Azure Cosmos с двумя разными ботами (js, v4, ms botframework).

Chatbot 1: - общаться с пользователем, сохранять пользовательские данные и использоватьпозже

Chatbot 2: - Чтение и отображение некоторых пользовательских данных

Я использую следующий клиент: https://github.com/Microsoft/BotFramework-WebChat

Сценарий:

  1. Я фиксирую свой userID в клиенте (который имеет прямую ссылку на бота 1), скажем, «123»
  2. Я использую Bot 1 и ввожу свое имя пользователя в диалоговом окне (запрашивается ботом)
  3. Я обновляю веб-сайт, на котором работает бот 1 с тем же идентификатором «123»
  4. Я вижу, что бот все еще хранит мои данные
  5. Я изменяю идентификатор в моем клиенте на «124»
  6. Я использую Bot 1 и вижу, что нет сохраненных данных (что ожидается, поскольку идентификатор "124" никогда не общался с Bot 1)
  7. Я изменяю идентификатор обратно на "123"
  8. Я использую бота 1 и вижу, что данные из шага 2 все еще там
  9. Я использую бота 2 с идентификатором "123"
  10. Я вижу, что данных нет ("undefined ")
  11. Я снова использую бота с идентификатором" 123 "
  12. Я вижу, что данные с шага 2 исчезают

Это означает, что всякий раз, когда я получаю доступ кбаза данных с моим вторым ботом кажется, что данные очищаются / удаляются.

Вот так я получаю доступ к БД в index.js:

//Add CosmosDB (info in .env file)
const memoryStorage = new CosmosDbStorage({
    serviceEndpoint: process.env.ACTUAL_SERVICE_ENDPOINT, 
    authKey: process.env.ACTUAL_AUTH_KEY, 
    databaseId: process.env.DATABASE,
    collectionId: process.env.COLLECTION
})

// ConversationState and UserState
const conversationState = new ConversationState(memoryStorage);
const userState = new UserState(memoryStorage);

// Use middleware to write/read from DB
adapter.use(new AutoSaveStateMiddleware(conversationState));
adapter.use(new AutoSaveStateMiddleware(userState));

Вот так я использую БД вbot.js:

constructor(conversationState, userState, dialogSet, memoryStorage) {
        // Creates a new state accessor property.
        // See https://aka.ms/about-bot-state-accessors to learn more about the bot state and state accessors
        this.conversationState = conversationState;
        this.userState = userState;

        // Memory storage
        this.memoryStorage = memoryStorage;

        // Conversation Data Property for ConversationState
        this.conversationData = conversationState.createProperty(CONVERSATION_DATA_PROPERTY);
        // Properties for UserState
        this.userData = userState.createProperty(USER_DATA_PROPERTY);
        this.investmentData = userState.createProperty(INVESTMENT_DATA_PROPERTY);

}

    async displayPayout (step) {
            console.log("Display Payout");
            // Retrieve user object from UserState storage
            const userInvestData = await this.investmentData.get(step.context, {});
            const user = await this.userData.get(step.context, {});

            await step.context.sendActivity(`Hallo ${user.name}. Am Ausgang kannst du dir deine Bezahlung von ${userInvestData.payout} abholen.` );
    }

Полученный код взят из бота 2. Бот 1 сохраняет данные таким же образом.Вы можете найти репозитории здесь:

Бот 1: https://github.com/FRANZKAFKA13/roboadvisoryBot

Бот 2: https://github.com/FRANZKAFKA13/displayBot

Клиент для Бот 1: https://github.com/FRANZKAFKA13/ra-bot-website-c

Клиент для бота 2: https://github.com/FRANZKAFKA13/ra-bot-website-display

Я также попытался использовать ключ "readOnly" из CosmosDB в боте 2, который выдает ошибку:

     [onTurnError]: [object Object]
(node:1640) UnhandledPromiseRejectionWarning: TypeError: Cannot perform 'set' on a proxy that has been revoked
    at adapter.sendActivities.then (C:\Users\X\Implementierung\display_bot\node_modules\botbuilder-core\lib\turnContext.js:175:36)
    at <anonymous>
    at process._tickDomainCallback (internal/process/next_tick.js:229:7)
(node:1640) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 3)

Другое поведение, которое у меня естьзамечено: когда я запускаю «событие соединения» через мой клиент с хранилищем редуксов, пользовательские данные также не сохраняются (каждый раз, когда я обновляю страницу, данные исчезают, несмотря на постоянное использование одного и того же идентификатора «123»)

dispatch({
              type: 'WEB_CHAT/SEND_EVENT',
              payload: {
                // Event starting bot's conversation
                name: 'webchat/join',
                value: {}
              }

Есть идеи?Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Редактировать: Исправлено путем добавления «[this.userID]» после каждого вызова «пользователя».

Я пробовал ваш метод, и всякий раз, когда я записывал данные, создавался новый тег eTag, который приводит к объекту.разделение на части:

"document": {
    "25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
        "25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
            "25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
                "25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
                    "25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
                        "name": "",
                        "age": "",
                        "gender": "",
                        "education": "",
                        "major": "",
                        "eTag": "\"00003998-0000-0000-0000-5c797fff0000\""
                    },
                    "name": "Jane Doe",
                    "eTag": "\"00003e98-0000-0000-0000-5c7980080000\""
                },
                "age": 22,
                "eTag": "\"00004898-0000-0000-0000-5c7980150000\""
            },
            "gender": "female",
            "eTag": "\"00004d98-0000-0000-0000-5c79801b0000\""
        },
        "education": "Bachelor",
        "eTag": "\"00005498-0000-0000-0000-5c7980200000\""
    },
    "major": "Business Administration",
    "complete": true

Как я могу предотвратить это?

Мой код:

В конструкторе:

this.changes = {};
this.userID = "";
this.userDatax = {
    name: "",
    age: "",
    gender: "",
    education: "",
    major: "",

    eTag: '*',
}

В диалогах:

async welcomeUser (step) {
    console.log("Welcome User Dialog");
    //step.context.sendActivity({ type: ActivityTypes.Typing});

    // Initialize UserData Object and save it to DB
    this.changes[this.userID] = this.userDatax;
    await this.memoryStorage.write(this.changes);
}

async promptForAge (step) {
    console.log("Age Prompt");
    // Read UserData from DB
    var user = await this.memoryStorage.read([this.userID]);
    console.log(user);

    // Before saving entry, check if it already exists
    if(!user.name) {
        user.name = step.result;
        user.eTag = '*';
        // Write userData to DB
        this.changes[this.userID] = user;
        await this.memoryStorage.write(this.changes);
    }
}
0 голосов
/ 01 марта 2019

Поскольку идентификаторы хранилища (см. Изображение) создаются автоматически на основе идентификаторов пользователей (которые также могут создаваться автоматически и зависят от канала) и идентификаторов каналов, это может быть очень сложно сделать.Это может затруднить сохранение данных о пользователях и разговорах, особенно по ботам и каналам.

Пример ID:

enter image description here

Подробнее о том, как работают идентификаторы .

Лично я бы написал бы свое собственное хранилище вместо (или в дополнение к) сохранения его с UserState.

Чтобы записать свои данные, сделайте что-то вроде этого:

const changes = {};
const userDataToWrite = {
    name: step.result,
    eTag: '*',
}
// Replace 'UserId' with however you want to set the UserId
changes['UserId'] = userDataToWrite;
this.memoryStorage.write(changes);

Это сохранит документ, который выглядит следующим образом (я установил для UserId значение user123:

enter image description here

Для чтения:

const userDataFromStorage = await this.memoryStorage.read(['UserId']);

userDataFromStorage будет выглядеть так:

{ UserId:
   { name: 'myName',
     eTag: '"0000c700-0000-0000-0000-5c7879d30000"' } }

Вам придетсяУправляйте пользовательскими идентификаторами самостоятельно, но это обеспечит возможность чтения данных между ботами, каналами и пользователями.

...