I start investigating BotFramework and encountered one annoying issue.
Created "Hello world" bot.
Here if the code
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
// calculate something for us to return
int length = (activity.Text ?? string.Empty).Length;
// return our reply to the user
Activity reply = activity.CreateReply($"You sent {activity.Text} which was {length} characters");
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
It works fine locally
Deployed it on Azure.
Set correct BotId, MicrosoftAppId and MicrosoftAppPassword parameters in web.config.
URL with my bot is http://funnyskypebot20171026010946.azurewebsites.net and it looks it works
But when i try to "communicate" with bit via Bot Framework Channel Emulator i do not receive any messages back ...
What could be wrong ? Please advise.
I assume you already followed the steps in https://learn.microsoft.com/en-us/bot-framework/deploy-dotnet-bot-visual-studio for deployment to Azure.
Have you seen this https://learn.microsoft.com/en-us/bot-framework/debug-bots-emulator with regards to debugging remotely using ngrok?
If you are using Visual Studio, on the toolbar, you can click on 'View -> Server Explorer'. Under 'Azure -> App Service', you should see your resource group there. Under your resource group, you should see your app service. Right-click and select 'Attach Debugger' so that you can view the output ('View -> Output') and debug your deployed app service.
Internal server error generally means there is some sort of issue with your code. Try debugging locally using ngrok. You can change your endpoint in the dev portal to the one that ngrok generates when you use this command ngrok http 3979 -host-header="localhost:3979" change to the port your bot runs on.
More info:
Blog Post
Blog Post
Related
I have a web application which is published on a same PC where I do coding and debugging.
One of the functionalities is an interface to company's Azure DevOps server to read or write WorkItems.
I am working with VS19. If I am in debug mode started from VS (F5 or ctrl+F5), communication to DevOps is working great, I can read and write WorkItems. If I try to do same from published site with debug configuration, which is hosted on same PC, I get response, that my request is refused.
To test my connection state I implemented a small test connection method according to guidelines
Authentication is realized with PAT. PAT is correct and authentication is working.
public async Task<ConnectionStatus> CheckAzureConnection()
{
string url = _uri + "/_apis/connectionData?api-version=5.1-preview";
ConnectionStatus status = new ConnectionStatus();
try
{
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "My User Name", _personalAccessToken))));
using (HttpResponseMessage response = await client.GetAsync(url))
{
status.Status = response.StatusCode.ToString();
return status;
}
}
}
catch (Exception ex)
{
status.Status = "Not OK";
return status;
}
}
This code is working during debug, but not in published website. Site is published on IIS Webserver. An internal valid certificate is bound to site. IIS Basic authentication is switched of according to Microsoft. Honestly, I tried to switch it on and off.
First site was published with release configuration, but actually because of issue I switched to debug configuration, without success to issue.
Do anyone have any ideas what I did forget? Why my request get declined?
Issue was in IIS configuration. As I mentioned in my question, site is running in company network. I configured application pool to be executed by a local user. After I changed local user to a network user it worked.
As I know, VS has its own IIS and this is running with signed network user. This was a difference to IIS on host.
I am currently following Teams Conversation Bot sample. I have followed it to the letter as far as i can see.
What works.
When i talk to the bot though the web view
I can see it hitting the code on my localhost.
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
turnContext.Activity.RemoveRecipientMention();
switch (turnContext.Activity.Text.Trim())
{
case "MentionMe":
await MentionActivityAsync(turnContext, cancellationToken);
break;
case "UpdateCardAction":
await UpdateCardActivityAsync(turnContext, cancellationToken);
break;
case "Delete":
await DeleteCardActivityAsync(turnContext, cancellationToken);
break;
case "MessageAllMembers":
await MessageAllMembersAsync(turnContext, cancellationToken);
break;
default:
var value = new JObject { { "count", 0 } };
var card = new HeroCard
{
Title = "Welcome Card",
Text = "Click the buttons below to update this card",
Buttons = new List<CardAction>
{
new CardAction
{
Type= ActionTypes.MessageBack,
Title = "Update Card",
Text = "UpdateCardAction",
Value = value
},
new CardAction
{
Type = ActionTypes.MessageBack,
Title = "Message all members",
Text = "MessageAllMembers"
}
}
};
await turnContext.SendActivityAsync(MessageFactory.Attachment(card.ToAttachment()));
break;
}
}
what doesn't work
It appears to send the response back but nothing appears in the response window. How do i test this if it doesn't show the response?
Ngrok error
After a bit more digging I can see that ngrok is getting an error back of sorts its a web page I managed to pick the following error out of it.
AggregateException: Failed to acquire token for client credentials. (AADSTS700016: Application with identifier '9e0d71-7665-4f24-8898-f82f9bebba56' was not found in the directory 'botframework.com'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.
Trace ID: 4bf53bae-84dc-4b16-98e8-e99b322dc200
Correlation ID: 3c249469-d177-49dd-989f-80044a3b9faa
Timestamp: 2019-11-12 08:41:56Z) (AADSTS700016: Application with identifier 'e0d71-7665-4f24-8898-f82f9bebba56' was not found in the directory 'botframework.com'. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You may have sent your authentication request to the wrong tenant.
I have checked the settings on the bot and the application itself. They have the same secret and application client id.
botframework.com appears to contain a list of bots that were created on azure.
What i have tried.
Visual studio is running as administrator.
Chckedbotframework.com my bot is listed.
Users have the write to create apps in AD, I am currently the only user anyway.
dev tools logs shows its authenticating.
Edge and chrome
web chat errors
I can see in the bot that its logging errors with the web chat
The thing is the bot is responding.
Emulator
Running the emulator does work. The issue is when hosted.
cross posted
Issue #1974
I realize this is an old thread but I just got hit by this today. After much pain, the fix in our situation was this:
Go to Azure Portal > Azure Active Directory
Click "App registrations"
Find the registration for the bot app in question and click on it.
Under Manage, choose Authentication.
Change "Supported account types" to "Accounts in any organizational directory."
In retrospect: the AADSTS700016 error was thrown when trying to get the detailed info of the person the bot is chatting with via Microsoft.Bot.Builder.Teams.TeamsInfo.GetMemberAsync(). Since our "Supported account types" in the app registration was restricted, when the bot was running in a Teams Office365 Tenant that was different than our Azure AD Tenant, Azure AD was saying, "Nope." After flipping this, then GetMemberAsync() was able to authenticate aginst the Teams Office365 Tenant to obtain the requested user information. Yay!
I want to create a Line messaging bot using API wrapper provided by pierre3 hosted on local environment.
Line Messaging Service ~~POST~~> WebApi.Net ~X-> Offline-Directline ---> Echobot (Bot Framework)
I am using the node package "offline-directline" which should enable to route
messages to the local bot, created from Echobot template bundled in
Microsoft BotFramework Extension.
This is the text printed on the node terminal:
Offline-Directline: Listening for messages from client on http://127.0.0.1:3000
Routing messages to bot on http://localhost:3978/api/messages
So far, my webapi is able to receive the request from Line Messenging Service.
The problem is I don't know how to connect from webapi to the offline-directline.
DirectLineClient doesnt throw exception, but
whenever the webapi execute StartConversationAsync(), the conversation always return null.
I can confirm my Echobot is working, because I can interact with it using Bot Framework Emulator.
var uri = new Uri("http://localhost:3978/api/messages");
var cred = new DirectLineClientCredentials(null, http://localhost:3000/directline");
this.dlClient = new DirectLineClient(uri, cred);
var conversation = await dlClient.Conversations.StartConversationAsync();
//this is always return null
I expect when I send the text "hello world" via Line Messenger,
the bot will respond with the same text "hello world" on Line Messenger.
And for extra information, I am not sure this is relevant or not:
the Line Messaging Api Wrapper require to use Azure blob storage.
I don't have a online Azure Blob Storage, instead I am using Storage Emulator and set the connection string to "UseDevelopmentStorage=true".
I assume this is working because I have checked the instance of CloudBlobClient is not null and it contains the valid uri pointing to local emulator.
--
I have stuck on this for many hours yet having no clue.
Any help would be much appreciated.
Background
I have a C# plugin in Dynamics 2016 on-premise that uses a library to make calls to other systems. Part of that library is a call to dynamics using the Web API. The Plugin is taking action as I can see the changes in dynamics, however I am expecting it to take a different action than it is taking. When I try to debug the plugin using the Plugin Registration tool, I am running into some issues. When I profile the plugin using the Exception method, I get an exception file that I am able to debug through to a point. When I get to the below code, the Plugin Registration Tool crashes without an error message. When I debug using the Persist to Entity Method, my plugin appears to succeed, but no Profiles are logged in the Plugin Registration Tool. My plugin is fired from an action which is triggered from a workflow that is attached to the completion of a Business Process Flow (this is based on this article). My initial question is here which led to this question. Any thoughts on getting the debugger to work with my code?
Code
HttpClient client = new HttpClient(new HttpClientHandler() { Credentials = new NetworkCredential("admin", "password", "DOMAIN") });
client.BaseAddress = new Uri(Helpers.GetSystemUrl(COHEN.APIConnector.Application.Dynamics));
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
HttpResponseMessage responseMessage;
string url = "ccseq_clients";
responseMessage = client.GetAsync(url).Result;
I remember this issue, when I was debugging SharePoint online REST API calls it will always crash. Then I added tracing service & logged checkpoints to verify the code execution path. Instead of debugging, I will download the Profiler trace log & replay in PRT to see success or failure branch.
When you configure plugin tracing to log All under system settings, it’s Dev mode & will be super helpful.
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Attempting to obtain Phone value...");
phone = account["telephone1"].ToString();
}
catch(Exception error)
{
tracingService.Trace("Failed to obtain Phone field. Error Details: " + error.ToString());
throw new InvalidPluginExecutionException("A problem has occurred. Please press OK to continue using the application.");
}
Reference
In your case:
if(responseMessage != null)
{
tracingService.Trace("API call success & got responseMessage.");
}
else
{
tracingService.Trace("responseMessage was empty.");
}
I'm really new in Xamarin development, and I just tried Xamarin.Forms to Develop Android & iOS App with shared Code, and what I'm trying to do here is to get data from API with Plugin.RestClient NuGet package.
Here's my MainViewModel.
public MainViewModel(){
InitializeDataAsync();
}
public async Task InitializeDataAsync(){
var employeeServices = new EmployeeServices();
EmployeesList = await employeeServices.getEmployeesAsync();
}
And here's my Services
public async Task<List<Employee>> getEmployeesAsync(){
RestClient<Employee> restClient = new RestClient<Employee>();
var employeeList = await restClient.GetAsync("http://localhost:3000/employee");
return employeeList;
}
And this is my RestClient
public async Task<List<T>> GetAsync(string WebServiceUrl){
var httpClient = new HttpClient();
var json = await httpClient.GetStringAsync(WebServiceUrl);
Debug.WriteLine(WebServiceUrl);
Debug.WriteLine(json);
var taskModels = JsonConvert.DeserializeObject<List<T>>(json);
return taskModels;
}
The code works fine on my iPhone Emulator. I can see my Debug for the url and json response. But on my Android Emulator there's nothing on the list. I can't even find my Debug for url and json response, I already checked my Application Output and my Device Log (I used Xamarin Studio for Mac btw).
I also already add internet permission on my Android Manifest.
What should I do?
You can only access localhost on your local machine. You need to change localhost to the IP address of the machine on which your api is hosted.
So the api endpoint for
http://localhost:3000/employee
should be something like
http://192.168.0.5:3000/employee
If you are getting a timed out error then it's probably because "localhost" to the Android OS means the phone itself, which is probably not where you're not running the web server. There are some special IP addresses you can use while testing with Android emulators to reach the host OS:
The Google emulators allow you to reach the host OS from 10.0.2.2.
The Microsoft Android emulator allows you to reach the host OS from 169.254.80.80.
You could try changing your URL based on the type of emulator you are using. Alternatively, you can plugin your workstations IP address instead, but this is less desirable because it can change.
If this doesn't allow you to reach the server then you may consider looking at any firewalls to see if your traffic is being blocked.