BotBuilder-MicrosoftTeams-dotnet icon indicating copy to clipboard operation
BotBuilder-MicrosoftTeams-dotnet copied to clipboard

trying a ChannelConversation post message as 1:1

Open pkaushik23 opened this issue 5 years ago • 8 comments

Describe the bug My use case is to create a proactive channel conversation as a group conversation by including other user. But when i try it creates a 1:1 conversation/

Expected behavior I expect, that when i execute below code, then, a message should be posted to a specific team channel of my ms-teams team from the bot.

Nuget Dependencies "Microsoft.AspNetCore" Version="2.1.3" "Microsoft.AspNetCore.All" Version="2.0.8" "Microsoft.Bot.Builder" Version="4.2.0" "Microsoft.Bot.Builder.Integration.AspNet.Core" Version="4.2.0" "microsoft.bot.builder.teams" Version="4.0.0-beta1" "Microsoft.Bot.Configuration" Version="4.2.0" "Microsoft.Bot.Connector" Version="4.2.0" "Microsoft.Bot.Schema" Version="4.2.0" "Microsoft.Extensions.Logging.AzureAppServices" Version="2.1.1"

.Net Version Microsoft.NETCore.App(2.1)

CODE This is the source code i am trying :

ClaimsIdentity claimsIdentity = turnContext.TurnState.Get<ClaimsIdentity>("BotIdentity");
Claim botAppIdClaim = claimsIdentity.Claims?.SingleOrDefault(claim => claim.Type == AuthenticationConstants.AudienceClaim)
                        ??
                        claimsIdentity.Claims?.SingleOrDefault(claim => claim.Type == AuthenticationConstants.AppIdClaim);

string appPassword = await this.credentialProvider.GetAppPasswordAsync(botAppIdClaim.Value).ConfigureAwait(false);
var identity =  new MicrosoftAppCredentials(botAppIdClaim.Value, appPassword);
MicrosoftAppCredentials.TrustServiceUrl(teamConversationData.ServiceUrl);
var connectorClient = new ConnectorClient(new Uri(teamConversationData.ServiceUrl),identity);

var mem2 = new List<ChannelAccount> { teamConversationData.TeamRoster.First().Value };
var parameters = new ConversationParameters
{
       //teamConversationData has my state info. like team roster ,tenant id, ms teams channels for my team etc.
	Bot = new ChannelAccount(teamConversationData.BotID, teamConversationData.BotName),
	Members = mem2,//Cant set to more than one account, if i try result in bad request exception
	IsGroup = false, //if this is set to true then always get an error while creating a conversation.
	TopicName = "Anything ",
	ChannelData = JObject.FromObject(
					new TeamsChannelData
					{
						Tenant = new TenantInfo(teamConversationData.Tenant.Id),
						Team = new TeamInfo(teamConversationData.Team.Id),
						Channel = new ChannelInfo(teamConversationData.Channels.Conversations[0].Id),
					},
					JsonSerializer.Create(new JsonSerializerSettings()
					{
						NullValueHandling = NullValueHandling.Ignore,
					})),

};
//things  which are not working..
//1. having more then 1 member in the members property of conversation parameter AND/OR setting isGroup to true. it throws a bad request error.                    
var conversationResource = await connectorClient.Conversations.CreateConversationAsync(parameters);
var message = Activity.CreateMessageActivity();
message.From = new ChannelAccount(teamConversationData.BotID, teamConversationData.BotName);
message.Conversation = new ConversationAccount(id: conversationResource.Id.ToString());
var mentions = new List<Entity>();
 var activityText = new StringBuilder($"a notification message, for following users : ");
foreach (var member in members)
{
	var mentionsText = $"<at>@{member.Name}</at>";
	mentions.Add(new Entity()
				{
					Type = "mention",
					Properties = JObject.FromObject(
												new { mentioned = new { id = member.Id, name = member.Name }, text = mentionsText }
												, JsonSerializer.Create(new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, })),
				});
	activityText.Append(mentionsText);

}                   
message.Entities = mentions;
message.Text = activityText.ToString();

await connectorClient.Conversations.SendToConversationAsync((Activity)message);

pkaushik23 avatar May 02 '19 13:05 pkaushik23

What exactly are you getting while creating a 1on1 conversation? Group conversation not working is expected (it's not supported). Also please try using GetConversationParametersForCreateOrGetDirectConversation method to get the conversation creation\get parameters.

You can also use MentionEntity for creating mentions instead of doing it by yourself.

RamjotSingh avatar May 02 '19 16:05 RamjotSingh

Thanks @RamjotSingh for your response. This is what i am trying to accomplish, please advise if it can be achieved in some other way. Use case: Some external system will notify my bot (when some event happens, for example when a daily job is completed. Then, do some processing and post on a specific team channel (Initialize a Channel Conversation). This is what i am doing

  1. I am fetching and storing roster,channelInfo,teamInfo,tenantInfo,botInfo when the bot is added to a team. I am utilizing conversationUpdate with EventType == "teamMemberAdded"
  2. The external system : an api call (using directline) from Microsoft flow creates a conversation and post some data to my bot. As this activity is not created within a teams context so teamsChannelData will not be there. Therefore , cannot use : GetConversationParametersForCreateOrGetDirectConversation
  3. Once i have the data to act upon (say list of some users in my team who are lagging behind in their daily sales target), I want to post a message to a particular channel (say, dailySalesReport channel). Tagging specific users from the data i received.
  4. Plus, also want to init a 1:1 between bot and each of those uer to get some more info. Perhaps will use adaptive cards. But yet to implement that.
  5. The code i shared above is what i want to do as outlined in step 3.

To answer your following question:

What exactly are you getting while creating a 1on1 conversation? Group conversation not working is expected (it's not supported).

  1. I am able to create a 1:1 conversation using the code i shared
  2. When GroupConversation is not supported , what is the use of having a collection type(a list which can take more than one member) for Members parameter of ConversationParameters.c'tor. And, in what circumstances i would set the parmeter IsGroup to true. Setting more than 1 member in Members parameter and/or setting IsGroup as True results in error.

Thanks, Prerak

pkaushik23 avatar May 02 '19 17:05 pkaushik23

Kind of found the solution to the issue i was facing. Have documented it here @RamjotSingh please feel free to advise on following:

This is what i am doing

pkaushik23 avatar May 03 '19 11:05 pkaushik23

Looks fine to me. I think this answers your IsGroup=true 's use as well.

RamjotSingh avatar May 03 '19 16:05 RamjotSingh

@pkaushik23 you closed the other issue, but I noticed you do seem to have a bit confusion between creating a conversation and continuing a conversation in relation to a teams channel.

Conversation ID -> use continueConversation and send a reply on the same reply chain in the channel Channel ID (no conversation ID) -> createConversation and creates a new reply chain

01 avatar May 03 '19 17:05 01

@01 again Thanks. your observation is bang on. To summarize my understanding , when i have created a channel conversation (using channelID in channelData parameter) on a channel then for subsequent activity i can use the conversationID without specifying the channelID. Thus replying to same conversation which was created and started.

am i right ?

I need to check if i can directly send a 1:1 like i did for channel conversation. That is just creating a conversation and not using await connectorClient.Conversations.SendToConversationAsync((Activity)messageOneToOne);

Thanks again.

pkaushik23 avatar May 03 '19 17:05 pkaushik23

@pkaushik23 I would have to check you may still need channel id.

You would need user id but create conversation is exactly how you send a 1:1 message proactively,

A great way to understand it all better is to look at the actual bot service api. All these libraries are simply wrappers to form the api calls, so looking at this might give some better context

https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-connector-api-reference?view=azure-bot-service-4.0

01 avatar May 03 '19 23:05 01

@01, sure would definitely check reference. Thanks again for sorting out things for me.

pkaushik23 avatar May 05 '19 09:05 pkaushik23