MS Bot get current page url - c#

I have created a bot with MS Bot SDK. Then, I want to get the page URL where I'm hosting the bot. I just inject the script to a page to host the bot. But, does anyone who knows how to get the current page URL from C#?
I can see someone is trying to use Activity for getting the URL, but I can't find the right property from Activity.

I just inject the script to a page to host the bot. But, does anyone who knows how to get the current page URL from C#?
If you embed webchat in your web site and you want to get the URL of the web page where you embed the webchat, you can try the following approach to get the URL and pass it to your bot.
Pass the URL to bot:
<script>
var urlref = window.location.href;
BotChat.App({
directLine: { secret: "{directline_secret}" },
user: { id: 'You', pageurl: urlref},
bot: { id: '{bot_id}' },
resize: 'detect'
}, document.getElementById("bot"));
</script>
Retrieve the URL in bot application:
if (activity.From.Properties["pageurl"] != null)
{
var urlref= activity.From.Properties["pageurl"].ToString();
}

ChannelData was designed to enable sending custom information from client to bot, and back. Similar to Fei Han's answer, you can intercept outgoing messages and provide custom ChannelData for every activity sent.
<script>
var dl = new BotChat.DirectLine({
secret: 'yourdlsecret',
webSocket: false,
pollingInterval: 1000,
});
var urlref = window.location.href;
BotChat.App({
botConnection: {
...dl,
postActivity: activity => dl.postActivity({
...activity,
channelData: { pageurl: urlref }
})
},
user: { id: 'userid' },
bot: { id: 'botid' },
resize: 'detect'
}, document.getElementById("bot"));
</script>
Then, in the bot:

Related

Why Fetch Post request with JSON parameter in the body to ASP.NET Core 3.1 WEB API or MVC Controller does not get anything?

Trying over a week so far with no success, to find out why I can't get the response from my controller.
Note I am not fluent in JS, only C#, but I already have a good understanding of what the fetch does.
Now learning ASP.NET Core, but still somewhere under junior level in my overall C# and .Net experience maybe.
It is regarding the process of redirecting to Stripe checkout, but fetch and the method as mentioned, can't agree around 200.
Originally the controller was a normal MVC controller but among many things tried, I made it also an API controller, hoping something which I apparently don't understand, might fix the issue with its method.
Turned over the web upside down searching for similar issues, and I have no other options except reaching to you guys, many experienced devs here.
The method functions 100%, I mean the logic inside. It returns a session object.
The API version returns the session; the MVC version returns this.Json(session);
I know that both versions work because I was debugging them by entering inside after a button click
Its all happening on localhost, therefore I provided credentials: 'include' in the headers... if I am correct.
Trying anything with Postman with authorization of course, but no luck so far.
Firefox Debugging currently throws no errors when going through the fetch.
The Questions:
- Does the fetch function properly according to my code?
- Is the controller prepared to get the payment id from the JSON body of the request?
- When I hardcode the paymentId inside the controller so that I don't expect any parameter, why this doesn't work as well (the fetch has session undefined)?
Here is the fetch in my Pay.cshtml view
<script src="https://js.stripe.com/v3/"></script>
<div id="checkout">
<form id="payment-form">
<div class="row d-flex justify-content-center">
<div class="col-6 py-4 text-center">
<button id="checkout-button"
value="Pay"
class="btn btn-sm btn-labeled btn-primary">
<span class="btn-label">
<ion-icon name="card-outline"></ion-icon>
</span>Pay $ #Model.Amount
</button>
</div>
</div>
</form>
</div>
<script>
var stripe = Stripe('#HomyTestPublishableKey');
var payButton = document.getElementById('checkout-button');
payButton.addEventListener('click', function(event) {
event.preventDefault();
stripe.redirectToCheckout({
sessionId: sessionId
});
});
var sessionId;
var paymentId = '#Model.Id';
fetch("/api/payment/createsession/", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify({id: paymentId })
}).then(function(r) {
return r.json();
}).then(function(response) {
sessionId = response.id;
})
.catch(error => console.error('Error:', error));
</script>
The method in the API Controller looks like this:
// Create PaymentSession
[HttpPost]
[Route("createsession")]
public async Task<Session> CreateSession([FromBody]string id)
{
var userId = this.userManager.GetUserId(this.User);
var payment = await this.paymentService.GetPaymentDetailsAsync(id, userId);
var successStringUrl = "https://localhost:44319/Checkout/success?session_id={CHECKOUT_SESSION_ID}";
var cancelStringUrl = "https://localhost:44319/Checkout/cancel";
var options = new SessionCreateOptions
{
PaymentMethodTypes = new List<string>
{
"card",
},
LineItems = new List<SessionLineItemOptions>
{
new SessionLineItemOptions
{
Quantity = 1,
Amount = (long)payment.Amount * 100,
Currency = CurrencyUSD,
Description = $"Payment Id: {payment.Id} for rental at {payment.RentalAddress}",
Name = $"Rent Payment for {DateTime.UtcNow.Month} | {DateTime.UtcNow.Year} for rental at {payment.RentalAddress}",
},
},
PaymentIntentData = new SessionPaymentIntentDataOptions
{
ApplicationFeeAmount = (long)((payment.Amount * 0.01m) * 100),
CaptureMethod = "manual",
TransferData = new SessionPaymentIntentTransferDataOptions
{
Destination = payment.ToStripeAccountId,
},
},
SuccessUrl = successStringUrl,
CancelUrl = cancelStringUrl,
};
var service = new SessionService();
Session session = service.Create(options);
return session; // the MVC version returns Task<IActionResult> of this.Json(session);
}
The options method of Stripe is not important, its only importnat why the fetch can't get anything. and what am I doing fundamentally wrong.
Here is a Stripe engineer CJ Avilla, demonstrating this with PHP and JS but you could get an idea.
After minute mark 20:30 you want to see him creating the fetch and later on, how checkout flow cicks in.
https://www.youtube.com/watch?v=VQ5jccnZ2Ow&t=1160s
Will appreciate any suggestions. Throw them to me.
Anyone with serious experience and a little time to dig in, I can provide access to the private github repo (its my first web project and I have to defend it at the end of the ASP.NET Core course at SoftUni).
Thank you!
P.S.
Edit 1:
Added binding model for the Id param, as I was wrongly expecting string but passing json object. However this still does not prove or allow the method to be accessed by the fetch...
Screen-shot added from my browser debugging.
Edit 2:
This code return Status 400 in console
fetch("https://localhost:44319/api/payment/createsession", {
method: 'POST',
mode: 'same-origin',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include',
body: JSON.stringify({ id: paymentId })
})
.then(r => r.json().then(data => ({status: r.status, body: data})))
.then(obj => console.log(obj));
why the fetch can't get anything. and what am I doing fundamentally wrong
Your CreateSession action accepts a string-type parameter id, on your JavaScript client side, you can pass data through request body like below.
body: JSON.stringify(paymentId)
Besides, if you'd like to make your action can handle body: JSON.stringify({id: paymentId }) well from client, you can also modify your action to accept a custom model parameter, like below.
[HttpPost]
[Route("createsession")]
public async Task<Session> CreateSession([FromBody]MyTestModel myTestModel)
{
var id = myTestModel.id;
//your code logic here
//...
MyTestModel class
public class MyTestModel
{
public string id { get; set; }
}
let serverResponse = await fetch('https://localhost:{port}/api/payment/createsession/',
{
method: 'POST',
mode: 'cors',
headers: {
'Accept': 'application/json'
},
body: JSON.stringify({ id: paymentId })
}
);
serverResponse.json().then(function (data) {
// server response value come to "data" variable
debugger;
});

Handling Twilio response with Sharepoint

I am working with TWILIO and Sharepoint 2016 to send text messages. I have created a Studio Dashboard to send the text messages and a Twilio function to send a response back to a Sharepoint list. My website is external facing with FBA accounts
All of this works if I paste the FEDAUTH code in my function. My question is how do I get the FEDAUTH code ? The pasted FEDAUTH seems to expire after awhile.
exports.handler = function(context, event, callback) {
var options = {
"method": "GET",
"hostname": "www.mysite.org",
"port": null,
"path": "/_layouts/15/Login.aspx",
"headers": {
"authorization": xxxx,
"content-type": "application/x-www-form-urlencoded",
"cache-control": "no-cache",
}
};
var req = http.request(options, function(res) {
var chunks = [];
res.on("data", function(chunk) {
chunks.push(chunk);
});
res.on("end", function() {
var body = Buffer.concat(chunks);
sendAPI();// passed FEDAUTH to /_api/contextinfo/
});
});
req.end();
};

Typeahead JSON request Access-control-allow-origin

I'm trying to use Typeahead to read Belgian postal codes. I'm using a website which provides json files upon typing but I get an access-control-allow-origin error. I'm viewing my web application through localhost. What am I doing wrong here? I'm using typeahead 0.11.1
This is the script throwing the error:
<script>
var postalCodes = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Postcode'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: 'http://www.opzoeken-postcode.be/%QUERY.json',
wildcard: '%QUERY'
}
});
$('.typeahead').typeahead(null, {
name: 'postal-codes',
display: 'Postcode',
source: postalCodes
});
</script>

Using c# with JavaScript in ArcGIS

I am new to ArcGIS. I am using an API to bookmark locations on a map. When a specific location is clicked (eg. Galway bay), the map will then zoom in to that location.
<script>
dojo.require("dijit.layout.BorderContainer");
dojo.require("dijit.layout.ContentPane");
dojo.require("dijit.form.DropDownButton");
dojo.require("esri.map");
dojo.require("esri.dijit.Bookmarks");
dojo.require("esri/dijit/HomeButton");
dojo.require("dojo/domReady!");
var map, bookmarks, home;
function init() {
map = new esri.Map("map", {
basemap: "oceans",
center: [-7.5, 53],
zoom: 6
});
The list of location, which a user can select is generated using JavaScript like the example below. You use spatial reference to locate a point on a map and then give it a name.
// Bookmarks can be specified as an array of objects with the structure:
// { extent: <esri.geometry.Extent>, name: <some string> }
var bookmarks_list = [{
"extent": {
"spatialReference": {
"wkid": 102100
},
"xmin": -1882000,
"ymin": 6638000,
"xmax": -316000,
"ymax": 7583000
},
"name": "Full View....."
}, {
"extent": {
"spatialReference": {
"wkid": 102100
},
"xmin": -1020761,
"ymin": 7009798,
"xmax": -996800,
"ymax": 7048100
},
"name": "Galway Bay"
}, {
"extent": {
"spatialReference": {
"wkid": 102100
},
"xmin": -939400,
"ymin": 6756000,
"xmax": -890400,
"ymax": 6785500
},
"name": "Cork Harbour"
}, {
"extent": {
"spatialReference": {
"wkid": 102100
},
"xmin": -1123000,
"ymin": 6839100,
"xmax": -1074100,
"ymax": 6868600
},
"name": "Tralee Bay"
} ];
// Create the bookmark widget
bookmarks = new esri.dijit.Bookmarks({
map: map,
bookmarks: bookmarks_list
}, dojo.byId('bookmarks'));
//show map on load
dojo.ready(init);
home.startup();
</script>
My question is, how do I get the JavaScript "name" value e.g. Galway Bay and pass it to a c# function ? How do you related c# and JavaScript? I am new to this so I would appreciated any advice thanks
As you've mentioned C# and JavaScript my guess is you're hosting your application in a .Net environment. However, the JavaScript API runs client side only so I'm not sure what you want to use C# to actually do? If it is that you want the server side to do something in response to something happening on the client, then you'd probably want to call a web server running on your server and supply it any client side properties. I use the .Net Web API for this.
You probably want to read up a bit more on:
the ESRI JavaScript API (https://developers.arcgis.com/javascript/),
the dojo request module for calling a webservice (http://dojotoolkit.org/documentation/tutorials/1.10/ajax/)
the ASP.Net Web API (http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api).
One other thing: I note you are using older Dojo syntax (pre v1.7) which is an easy mistake to make given that ESRI and even Dojo themselves haven't updated all their tutorials to the 1.7+ syntax. But if you are starting a new project I would make sense to use the new syntax from the start. The dojo site has another tutorial about the differences (same link as above, just go up a level).
Create an event handler for a mouse click on a bookmark. In the event handler, send an Ajax request to your C# based default.apx page or Url passing in the bookmark name as a querystring.
Here is an example. I couldn't get the bookmark event click to pass any data, so I used Jquery. I also added a 1 second delay to ensure the bookmarks finished loading.
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script>
setTimeout(function () {
$("#bookmarks .esriBookmarkLabel").click(function () {
$.get("default.aspx?bookmarkName=" + $(this).html(), function (data) {
$(".result").html(data);
});
});
},1000);
</script>

OAuthException Facebook C# SDK ie9

I am using the following code in my facebook application. The when loading the application in facebook has no problem in chrome/firefox/ie8. When it runs in IE9 it is reporting that OAuthException has been thrown.
public string GetFacebookId() {
if (!FacebookWebContext.Current.IsAuthorized())
return string.Empty;
var client = new FacebookWebClient();
dynamic me = client.Get("me");
return me.id;
}
(OAuthException) An active access token must be used to query
information about the current user.
any suggestions would be appreciated.
thanks.
EDIT:
window.fbAsyncInit = function () {
FB.init({
appId: '#(Facebook.FacebookApplication.Current.AppId)', // App ID
//channelURL: '//facebook.thefarmdigital.com.au/moccona/premium/FacebookChannel/', // Channel File
status: true, // check login status
cookie: true, // enable cookies to allow the server to access the session
oauth: true, // enable OAuth 2.0
xfbml: true // parse XFBML
});
FB.Canvas.setAutoGrow();
};
$(function () {
$('#custom_login').click(function () {
FB.getLoginStatus(function (response) {
if (response.authResponse) {
//should never get here as controller will pass to logged in page
} else {
FB.login(function (response) {
if (response.authResponse) {
window.location = '#(Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, ""))' + $('#custom_login').attr('href');
} else {
window.location = '#(Request.Url.AbsoluteUri.Replace(Request.Url.PathAndQuery, ""))' + $('#custom_login').attr('dataFail');
}
}, { scope: 'publish_stream' });
}
});
return false;
});
});
I'm not familiar with FB's C# SDK, but judging from the code you gave, it does not seem that you are doing any user authentication with FB. It might be that it works in Chrome and Firefox only because you are somehow already logged into your FB app in those browsers.

Categories

Resources