Reputation: 3
Overview: I built a bot using teams toolkit - I have had this issue for a while where the bot will lose references for the member when a new version comes out or after some time of not sending notifications. In order to counteract this, I'm implementing CosmosDB into the bot to store the member object for each user. This way when the bot loses the member, we can target the saved member object
It's important to know that I'm targeting a member object and not a conversation or a conversation reference so this is not a conversation context issue. Ill share how the targeting works below :
export async function handleDailyCard(
target: BotBuilderCloudAdapter.Member,
payload: DailyCardData
) {
const baseCard = // card_information_here
// CARD LOGIC HERE
try {
console.log("sending message to", target);
await target?.sendAdaptiveCard(
AdaptiveCards.declare<DailyCardData>(baseCard).render({
memberId: payload.memberId,
// other fields here
})
);
} catch (error) {
console.log("error sending note", error);
console.log(target);
}
now in my index.ts file - im inititalizing the bot and cosmos db like so:
const cosmosStorage = new CosmosDbPartitionedStorage({
cosmosDbEndpoint: "cosmos-db-endpoint",
authKey:"my-auth-key",
databaseId: "database-id",
containerId: "container-id",
compatibilityMode: false,
});
const teamsBot = new TeamsBot();
in the same index file - i define the functions to store and retrieve items from cosmos-
async function storeMemberInCosmos(member: BotBuilderCloudAdapter.Member) {
const memberData = {
id: member.account.aadObjectId, // Use the member ID as the document ID
memberInfo: member,
};
try {
// Write the full member object to Cosmos DB
await cosmosStorage.write({ [member.account.aadObjectId]: memberData });
} catch (error) {
console.error("Error storing member in Cosmos DB:", error);
}
}
async function getMemberFromCosmos(
memberId: string
): Promise<BotBuilderCloudAdapter.Member | null> {
try {
const memberData = await cosmosStorage.read([memberId]);
if (memberData && memberData[memberId]) {
const memberInfo = memberData[memberId].memberInfo;
const adapter = notificationApp.adapter;
// Here I'm reconstructing the parent portion with the adapter - allows me to use built in functions
const parent = {
...memberInfo.parent,
adapter: adapter, // Reassigning adapter here - might cause issues
};
// Rebuilding the member object with the adapter
const rebuiltMember = new BotBuilderCloudAdapter.Member(
parent,
memberInfo.account
);
return rebuiltMember;
} else {
console.log("Member not found in Cosmos DB");
return null;
}
} catch (error) {
console.error("Error retrieving member from Cosmos DB:", error);
return null;
}
}
Now my solution seems to be working locally with the storage but when I after I deploy it I seem to be getting a 500 server error and the logs dont really provide much information there- I think the deployment is successful and its getting zipped correctly- the pipeline and all the test cases seem to pass
I have no deployment issues if the storage integration is not included- do I need to fix the .yml files or deployment scripts? I hope my question is clear, but I can provide additional information if needed for clarity
Upvotes: 0
Views: 83
Reputation: 10844
For the 500 error, you should look into the logs and see what the detail is, or add logging to help with that. In any case, you're basing rolling your own state management when there is something built into the bot framework for this for you already - See https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-howto-v4-state?view=azure-bot-service-4.0&tabs=csharp for more on State management. There are various types, depending on your needs, but you'd want "User" (versus "Conversation") state, as you noted in your question.
Upvotes: 0