1

I am creating a bot to proactively start a conversation with an account I have never had a previous conversation with. I have created another controller that I am posting to and doing the following steps:

  public class OutboundController : ApiController {
public HttpResponseMessage Post([FromUri] int id, [FromBody] OutboundData outboundData) {

  MicrosoftAppCredentials.TrustServiceUrl(outboundData.ServiceUrl);

  //create conversation
  var connector = new ConnectorClient(new Uri(outboundData.ServiceUrl));

  var botAccount = new ChannelAccount { Id = outboundData.FromAccountId, Name = outboundData.FromAccountName };
  var toAccount = new ChannelAccount { Id = outboundData.ToAccountId, Name = outboundData.ToAccountName };

  if(!MicrosoftAppCredentials.IsTrustedServiceUrl(outboundData.ServiceUrl)) {
    throw new Exception("service URL is not trusted!");
  }
  var conversationResponse = connector.Conversations.CreateDirectConversation(botAccount, toAccount);

  var client = new BuslogicClient();
  var confirmData = client.GetOutboundData(id);
  var greetingMessage = CreateGreetingMessage(confirmData);

  var convoMessage = Activity.CreateMessageActivity();
  convoMessage.Text = greetingMessage;
  convoMessage.From = botAccount;
  convoMessage.Recipient = toAccount;
  convoMessage.Conversation = new ConversationAccount(id: conversationResponse.Id);
  convoMessage.Locale = "en-Us";
  connector.Conversations.SendToConversationAsync((Activity)convoMessage);


  string message = string.Format("I received correlationid:{0} and started conversationId:{1}", id, conversationResponse.Id);
  var response = Request.CreateResponse(HttpStatusCode.OK, message);
  return response;
}

When I call connector.Conversations.CreateDirectConversation I am getting the following exception: Additional information: Authorization for Microsoft App ID [ID] failed with status code Unauthorized and reason phrase 'Unauthorized'. If I do this with appId and password blank everything works fine in the channel emulator. I've tried providing the MicrosoftAppCredentials to the constructor of the ConnectorClient, but that has no affect. I've read on other threads that the service URL must be trusted so I used MicrosoftAppCredentials.TrustServiceUrl.

versions I am using: BotBuilder 3.5.3 Channel Emulator 3.0.0.59

The use-case for my bot is to post to the outbound controller with some user info to create a proactive message to be sent out (specifically SMS). If the user responds to my message it will be intercepted by the messages controller and passed to my dialogs for further processing and conversation responses on that same channel.

I've also taken a look at: https://github.com/Microsoft/BotBuilder/issues/2155 but don't quite understand solution described in the comments or if it even pertains to the issue I'm trying to solve.

Any suggestions or help would be appreciated!

Jay Tina
  • 107
  • 7
  • Possible duplicate of [Initiate a message from bot to user on BotFramework](http://stackoverflow.com/questions/42749982/initiate-a-message-from-bot-to-user-on-botframework) – Artem Mar 22 '17 at 16:07
  • @artem The scenario is a bit different because I'm not resuming a previous incoming conversation. I am initiating a new conversation. In the link you provided someone asked about CreateDirectConversationAsync and you replied " sure I did. It doesn't work. Apparently error is not related with the way conversation is created" I'm wondering if I have to post to the connector api the account data first so that connector can fully trust the conversation creation. – Jay Tina Mar 22 '17 at 17:28

1 Answers1

0

You need to pass credentials explicitly to connector:

var credentials = new MicrosoftAppCredentials("YoursMicrosoftAppId", "YoursMicrosoftAppPassword");
var connector = new ConnectorClient(serviceUrl, credentials);
Artem
  • 2,084
  • 2
  • 21
  • 29
  • I've already tried this and I am still getting a unauthorized error when I try to create a direct conversation. There is no dependency on the channel accounts I'm using to create the conversation? Do they have to be specific bot Id/name? I'm going to look at code to see what createDirectConversation is doing. – Jay Tina Mar 22 '17 at 19:32
  • I did reproduce the issue with the code you posted. Passing credentials solved the problem for me. However I can see you set botAccountId as outboundData.FromAccountId. I guess FromAccount is a user account, isn't it? Shouldn't you swap them? – Artem Mar 22 '17 at 20:01
  • Here is sample outbound data:{ "ChannelId": "emulator", "ToAccountName": "Jay Tina", "ToAccountId": "+5555555555", "FromAccountName": "OutboundTestApp", "FromAccountId": "OutboundTestApp-1", "ServiceUrl": "http://localhost:9000" } Does FromAccountId need to be BotId I have defined in the web.config of my published app? I'm testing this with the channel emulator. – Jay Tina Mar 22 '17 at 20:11
  • I was able to get my bot to start a conversation with a user in the emulator. The caveat is that I had to produce an incoming conversationUpdate first, retrieve those channel accounts and then finally start a direct conversation. I was reading on anther thread that direct conversations can only be started with channel accounts that have previously interacted with your bot (inbound). Is this a true statement? – Jay Tina Mar 23 '17 at 17:29
  • To be able to start a conversation your bot needs to know UserAccount's information (Id) anyway. So, the statement above is true, as the bot will know this information after the first interaction only – Artem Mar 24 '17 at 06:22
  • For the sake of this thread I was able to successfully resume a conversation via the connector client. Thank you for confirming @Artem on the functionality I am now experiencing. It's a bit misleading to have a method stating I can simply "Create" a conversation vs basing it on an account I've previously interacted with. – Jay Tina Mar 27 '17 at 21:52