Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for Microsoft Teams conversation references #311

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 69 additions & 35 deletions api-module-library/microsoft-teams/api/bot.js
Original file line number Diff line number Diff line change
@@ -1,75 +1,94 @@
const { BotFrameworkAdapter, StatusCodes, TeamsActivityHandler, CardFactory, MessageFactory, TeamsInfo, TurnContext
const {
BotFrameworkAdapter,
StatusCodes,
TeamsActivityHandler,
TeamsInfo,
TurnContext,
} = require('botbuilder');
const {OAuth2Requester} = require("@friggframework/module-plugin");
const {get} = require("@friggframework/assertions");


class botApi {
#conversationReferencesInternal = {};

set conversationReferences(newConversationReferences) {
this.#conversationReferencesInternal = newConversationReferences;
this.bot.conversationReferences = newConversationReferences;
}
get conversationReferences() {
return this.#conversationReferencesInternal;
}

constructor(params) {
// bot expects to listen on
this.adapter = new BotFrameworkAdapter({
appId: params.client_id,
appPassword: params.client_secret
appPassword: params.client_secret,
});
this.adapter.onTurnError = async (context, error) => {
await context.sendTraceActivity(
'OnTurnError Trace',
`${ error }`,
`${error}`,
'https://www.botframework.com/schemas/error',
'TurnError'
);
await context.sendActivity('The bot encountered an error.');
};
this.conversationReferences = {};
this.botId = params.client_id;
this.tenantId = params.tenant_id;
this.serviceUrl = params.service_url;
this.bot = new Bot(this.adapter, this.conversationReferences);
}
async receiveActivity(req, res){
await this.adapter.process(req, res, (context) => this.bot.run(context));
async receiveActivity(req, res) {
await this.adapter.process(req, res, (context) =>
this.bot.run(context)
);
}

// this circumvents the adapter middleware, only for testing
// this circumvents the adapter middleware
async run(activity) {
console.log('only for testing!')
await this.bot.run(activity);
}

async setConversationReferenceFromMembers(members){
async setConversationReferenceFromMembers(members) {
const ref = {
bot: {
id: this.botId
id: this.botId,
},
conversation: {
tenantId: this.tenantId
tenantId: this.tenantId,
},
serviceUrl: this.serviceUrl,
channelId: 'msteams'
}
channelId: 'msteams',
};

const refRequests = [];
members.map( (member) => {
members.map((member) => {
ref.user = member;
refRequests.push( this.adapter.createConversation(ref, async (context) => {
const ref = TurnContext.getConversationReference(context.activity);
this.conversationReferences[member.email] = ref;
}));
refRequests.push(
this.adapter.createConversation(ref, async (context) => {
const ref = TurnContext.getConversationReference(
context.activity
);
this.conversationReferences[member.email] = ref;
})
);
});
await Promise.all(refRequests);
return this.conversationReferences
return this.conversationReferences;
}

async sendProactive(userEmail, activity) {
const conversationReference = this.conversationReferences[userEmail];
if (conversationReference !== undefined) {
await this.adapter.continueConversation(conversationReference, async (context) => {
await context.sendActivity(activity);
});
await this.adapter.continueConversation(
conversationReference,
async (context) => {
await context.sendActivity(activity);
}
);
}
}

async createConversationReference(initialRef,member){
async createConversationReference(initialRef, member) {
initialRef.user = member;
await this.adapter.createConversation(initialRef, async (context) => {
const ref = TurnContext.getConversationReference(context.activity);
Expand All @@ -84,11 +103,11 @@ const invokeResponse = (card) => {
const cardRes = {
statusCode: StatusCodes.OK,
type: 'application/vnd.microsoft.card.adaptive',
value: card
value: card,
};
const res = {
status: StatusCodes.OK,
body: cardRes
body: cardRes,
};
return res;
};
Expand All @@ -100,9 +119,18 @@ class Bot extends TeamsActivityHandler {
this.adapter = adapter;
this.onMembersAdded(async (context, next) => {
const membersAdded = context.activity.membersAdded;
await Promise.all(membersAdded.map(async member => {
await this.setConversationReferenceForNewMember(context, member);
}));
await Promise.all(
membersAdded
.filter(
(member) => member.id !== context.activity.recipient.id
)
.map(async (member) => {
await this.setConversationReferenceForNewMember(
context,
member
);
})
);
await next();
});
}
Expand All @@ -115,21 +143,27 @@ class Bot extends TeamsActivityHandler {

async getUserConversationReference(context) {
const TeamMembers = await TeamsInfo.getPagedMembers(context);
TeamMembers.members.map(async member => {
TeamMembers.members.map(async (member) => {
await this.setConversationReferenceForNewMember(context, member);
});
}

async setConversationReferenceForNewMember(context, member){
const initialRef = TurnContext.getConversationReference(context.activity);
async setConversationReferenceForNewMember(context, member) {
const initialRef = TurnContext.getConversationReference(
context.activity
);
initialRef.user = member;
delete initialRef.conversation.id;
delete initialRef.activityId;
initialRef.bot = {id: undefined}
initialRef.bot = { id: undefined };
let memberInfo;
await this.adapter.createConversation(initialRef, async (context) => {
const ref = TurnContext.getConversationReference(context.activity);
memberInfo = await this.adapter.getConversationMembers(context);
ref.user = {
...memberInfo[0],
aadObjectId: memberInfo[0].objectId,
};
this.conversationReferences[memberInfo[0].email] = ref;
});
}
Expand Down
Loading