I'm trying to make a proactive message according to this.
I can understand the way to it. I'm worried about security. So I'm trying to use BotAuthentication. But I don't know how to use it. I tried to add a token according to this.
But it seems useless. How to use BotAuthentication? By the way, do I need to worry about security?
using Bot.Dialogs.FAQ.Liquidation;
using Bot.Dialogs.Menu;
using Bot.Resources;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Resources;
using System.Threading.Tasks;
using System.Web.Http;
namespace Bot
{
[BotAuthentication]
public class CustomWebAPIController : ApiController
{
[HttpGet]
[Route("api/CustomWebAPI")]
public async Task<HttpResponseMessage> SendMessage()
{
try
{
if (!string.IsNullOrEmpty(ConversationStarter.conversationReference))
{
await ConversationStarter.Resume(); //We don't need to wait for this, just want to start the interruption here
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Content = new StringContent($"<html><body>Message sent, thanks.</body></html>", System.Text.Encoding.UTF8, #"text/html");
return resp;
}
else
{
var resp = new HttpResponseMessage(HttpStatusCode.OK);
resp.Content = new StringContent($"<html><body>You need to talk to the bot first so it can capture your details.</body></html>", System.Text.Encoding.UTF8, #"text/html");
return resp;
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}
}
You don't need to handle bot authentication. That is done by the SDK.
You should not be using v3 as it is deprecated and no longer being developed. V4 is the current version.
Here is the documentation on V4 proactive messages.
And here is a sample that shows how to use proactive messages.
Related
I've found lots of questions about downloading images and as my code shows that is what I ended up doing. However that is not the behavior I want. I just want it to return the image directly.
using System.Net;
using Microsoft.Extensions.Logging;
using System.IO;
public static async Task<HttpResponseMessage> Run(HttpRequest req, ILogger log, string data)
{
log.LogInformation("start function...");
string qrData = $"{data}";//req.Query["id"];
string QrGeneratorUrl = "https://api.qrserver.com/v1/create-qr-code/?size=100x100&data="+ qrData;
log.LogInformation("QrUrl= " + QrGeneratorUrl);
var filename = "temp.png";
var filePath = Path.Combine(#"d:\home\site\wwwroot\QrGeneratorTest\"+filename);
WebClient myWebClient = new WebClient();
myWebClient.DownloadFile(QrGeneratorUrl, filePath);
var response = new HttpResponseMessage(HttpStatusCode.OK);
var fileStream = new FileStream(filePath, FileMode.Open);
response.Content = new StreamContent(fileStream);
return response;
}
I've tried converting the image to a byte stream and adding the stream to the response content, I've tried putting the image data directly as string content... nothing seems to work - it only transmits the image if it is a local file and I add it to the response via fileStream. Does someone know how I can get it to just put the response I get into the response I am returning? Or explain why it can't be done? This is functionality that exists in a web app that we are trying the move into a function and the web app is able to pass the content along without saving it. Using a byte stream. But I can't seem to replicate that in the function.
There are 2 reasons we are not calling qr server directly
1) it's a 3d party site so it could go down and we need to be able to swap it out for a new provider from one location.
2) we need to build the url so it has not parameters (?p=1&q=2&r=3...) as this is going into an email and having a bunch of parameters often tags the email as junk. With Azure (as with our web app) we can build the url like this: /getImage/1/2/3 which is less likely to be tagged as spam
any insight would be appreciated!!
//*******************//
ANSWER
here is my final code. I think the issue was Stream vs MemoryStream... In any case here is the full code:
#r "Newtonsoft.Json"
using System.Net;
using System;
using System.Web;
using System.Threading.Tasks;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
public static async Task<HttpResponseMessage> Run(HttpRequest req, ILogger log, string data)
{
log.LogInformation("start function...");
string qrData = $"{data}";
//string qrData = DateTime.Now.Ticks.ToString();
string QrGeneratorUrl = "https://api.qrserver.com/v1/create-qr-code/?size=100x100&qzone=2&data="+ qrData;
//get the QR image from 3d party api
var httpWebRequest = WebRequest.Create(QrGeneratorUrl);
var httpResponse = await httpWebRequest.GetResponseAsync();
//put 3d party response into function response
Stream ms = httpResponse.GetResponseStream(); //new MemoryStream(bytes);
var result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(ms);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
return result;
}
Suppose you want to download the image to stream and just return it(If use browser send the request, show the image in the browser, If I get it wrong please let me know). If this is your purpose you could refer to my below code, I download the image from blob and return it to FileContentResult.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Blob;
using System.DrawingCore;
namespace FunctionApp72
{
public static class Function1
{
[FunctionName("Function1")]
public static async Task<IActionResult> RunAsync(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
CloudStorageAccount blobAccount = CloudStorageAccount.Parse(Environment.GetEnvironmentVariable("AzureWebJobsStorage"));
CloudBlobClient blobClient = blobAccount.CreateCloudBlobClient();
CloudBlobContainer blobContainer = blobClient.GetContainerReference("test");
CloudBlockBlob cloudBlockBlob = blobContainer.GetBlockBlobReference("test.jpg");
MemoryStream streamIn = new MemoryStream();
await cloudBlockBlob.DownloadToStreamAsync(streamIn);
Image originalImage = Bitmap.FromStream(streamIn);
return new FileContentResult(ImageToByteArray(originalImage), "image/jpeg");
}
private static byte[] ImageToByteArray(Image image)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(image, typeof(byte[]));
}
}
}
And I deploy it to azure It still could return the image.
The following works great on my local IIS and return videos. When I run it on my GoDaddy shared hosting website (using https), it returns "This page can't be displayed". My code is below and I have isolated the problem down to this statement:
// Execute search
SearchListResponse searchListResponse = searchListRequest.Execute();
I have searched but cannot find solution and even called GoDaddy for help but no joy yet. Hope someone can help resolve.
Here's the source code snippet:
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
//using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Upload;
using Google.Apis.Util.Store;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
public void runSearch(string query)
{
try
{
// Create YouTube Service
YouTubeService youTubeService = new YouTubeService(new BaseClientService.Initializer()
{
ApiKey = "xxxx",
ApplicationName = this.GetType().ToString()
});
SearchResource.ListRequest searchListRequest = youTubeService.Search.List("snippet");
searchListRequest.Q = query;
searchListRequest.MaxResults = 15;
searchListRequest.Type = "video";
// Execute search
SearchListResponse searchListResponse = searchListRequest.Execute();
...
}
I am making a simple app that sends location data to a server using http get request.
The problem is that the request is made only on the first time despite the fact that it is inside the positionchanged event handler.
Here is my code. I can't find what is wrong with it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Device.Location;
namespace kechap
{
public partial class MainPage : PhoneApplicationPage
{
GeoCoordinateWatcher gw = new GeoCoordinateWatcher();
Uri url = new Uri("http://127.0.0.1:5000/upload/1e3fae069dd62fa1641183cd77092ed2053a0e75/1/2");
// Constructor
public MainPage()
{
InitializeComponent();
gw.MovementThreshold = 10;
gw.PositionChanged += (s, e) =>
{
MyMap.Center = e.Position.Location;
MyPushpin.Location = e.Position.Location;
WebClient wc = new WebClient();
wc.OpenReadAsync(url);
wc.OpenReadCompleted += (ss, ee) =>
{
};
};
gw.Start();
}
}
}
At a guess I would say the URI, which in the code you have posted does not change between calls, is resolved from cache after the first time. I suggest you use the age old hack of appending a parameter and giving it a value that changes with each invocation (eg the position you seem to want to report).
I used visual2010 to write a simple app with httpWebRequest class. The very first time of running the app, it'd work but after some successes, it was stuck with warning
"unable to connect the remote server".
I have read a lot in net but not much clues could done, almost said because the anti virus soft or firewall cause the problem, but when i'd turn off both, it still does not work. I also reinstall visual2010 but the problem still
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace new_httpWebRequest
{
class Program
{
static void Main(string[] args)
{
string result ="";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://my-favor.net");
// line code problem below:
`HttpWebResponse response = (HttpWebResponse)request.GetResponse();`
var sr = new StreamReader(response.GetResponseStream() ?? System.IO.Stream.Null, Encoding.UTF8);
result = sr.ReadToEnd();
sr.Close();
Console.Write(result);
Console.ReadLine();
}
}
}
finally, i find the solution just by adding this line:
request.Proxy = null;
I don't know why it work, just do it by god bless.
I wrote one program which sends request for particular site and gets response. It properly runs with localhost. but, if i put www.google.com then it prompts error as "The remore sever returned an error: Not Found"
****Code*****
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO;
namespace WindowsPhoneApplication2
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
var request = (HttpWebRequest)WebRequest.Create(new Uri(#"http://www.google.com"));
request.BeginGetResponse(r =>
{
var httpRequest = (HttpWebRequest)r.AsyncState;
var httpResponse = (HttpWebResponse)httpRequest.EndGetResponse(r);
using (var reader = new StreamReader(httpResponse.GetResponseStream()))
{
var response = reader.ReadToEnd();
Deployment.Current.Dispatcher.BeginInvoke(new Action(() => { textBox1.Text = response; }));
}
}, request);
}
}
}
please tell me soultion
thanx in advance
Your code works for me.
Can you access Google from IE on the device/emulator?
I suspect that this is a networking issue local to you and not related to the device.