I have my application is hosted in FaceBook as a tab and I want to get the page ID when my application is being added to be stored in my logic.
How can I get the page ID, I know it is stored in the URL but when I tried to get it from the page as a server variable, I am not getting it even my application is configured as iFrame ? But this is a standard way to get the parent URL.
C#:
string t= request.serverVariables("HTTP_REFERER");
//doesn't get FB page url even if your app is configured as iframe ?!! #csharpsdk #facebook devs
Any help ?
Thanks a lot.
Here is how I do it:
if (FacebookWebContext.Current.SignedRequest != null)
{
dynamic data = FacebookWebContext.Current.SignedRequest.Data;
if (data.page != null)
{
var pageId = (String)data.page.id;
var isUserAdmin = (Boolean)data.page.admin;
var userLikesPage = (Boolean)data.page.liked;
}
else
{
// not on a page
}
}
The Page ID is not stored in the URL; it is posted to your page within the signed_request form parameter. See this Facebook developer blog post for more details.
You can use the FacebookSignedRequest.Parse method within the Facebook C# SDK to parse the signed request (using your app secret). Once you have done this you can extract the Page ID from the Page JSON object as follows:
string signedRequest = Request.Form["signed_request"];
var DecodedSignedRequest = FacebookSignedRequest.Parse(FacebookContext.Current.AppSecret, SignedRequest);
dynamic SignedRequestData = DecodedSignedRequest.Data;
var RawRequestData = (IDictionary<string, object>)SignedRequestData;
if (RawRequestData.ContainsKey("page") == true)
{
Facebook.JsonObject RawPageData = (Facebook.JsonObject)RawRequestData["page"];
if (RawPageData.ContainsKey("id") == true)
currentFacebookPageID = (string)RawPageData["id"];
}
Hope this helps.
Here's the same solution as Andy Sinclairs's in VB that worked for me:
Dim pageId as Int64 = 0
Dim signed_request As String = Request.Form("signed_request")
Dim req = FacebookSignedRequest.Parse(AppSettings("FacebookSecret"), signed_request)
Dim data As IDictionary(Of String, Object) = req.Data
If data.ContainsKey("page") Then
Dim RawPageData As Facebook.JsonObject = data("page")
If RawPageData.ContainsKey("id") Then
pageId = RawPageData("id")
End If
End If
Related
I'm developing a blog website (using Umbraco) where it also can share its blog page to Facebook automatically after the page has been published. I have created a Facebook app and used Facebook SDK for .NET in order to that and it works but one small problem is that when the link is shared for the first time, it looks ugly. No image, no title and no description, just url. I have to publish the second time to get the proper link. Heres what I've done so far:-
Programmatically use the scrape API using Facebook SDK for .NET. I even tried to loop through the scrape API 10x to test if it work but doesn't.
Supply the necessary Open Graph Tag in the header of the shared page.
og:title
og:description
og:image
og:image:width
og:image:height
og:type
og:fb_id
og:site_name
I'm using Umbraco ContentService Events to invoke the Facebook API functions:-
public class PublishEventHandler : ApplicationEventHandler
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
ContentService.Published += ContentServicePublished;
}
private void ContentServicePublished(IPublishingStrategy sender, PublishEventArgs<IContent> args)
{
foreach (var node in args.PublishedEntities)
{
foreach (var item in node.Properties)
{
//check property alias and its value
if (item.Alias == "autoPost" && (int)item.Value == 1)
{
var fbClient = new FacebookAuthClient();
var pageToken = fbClient.GetPageToken();
var url = umbraco.library.NiceUrlWithDomain(node.Id);
fbClient.ScrapePage(url, pageToken);
fbClient.SharePostOnPage(url, pageToken);
}
}
}
}
}
Scrape API function:-
public void ScrapePage(string url, string pageToken)
{
var scrapeResult = new FacebookClient(pageToken)
{
Version = "v2.9"
};
var response = scrapeResult.Post(new { id = url, scrape = "true" });
LogHelper.Info(this.GetType(), "|SCRAPE| " + response.ToString());
}
Share API function:-
public void SharePostOnPage(string url, string pageToken)
{
if (pageToken != null)
{
var result = new FacebookClient(pageToken)
{
Version = "v2.9"
};
var response = result.Post("/" + AuthConfig.facebookPageId + "/feed", new { link = url, scrape = "true" });
LogHelper.Info(this.GetType(), "|SHARE| " + response.ToString());
}
}
One more thing I want to add is when I checked the response for the scrape in the log. I only get the id and url but when I used the Graph API Explorer in https://developers.facebook.com I got the whole information of the page (id,url,title,description,etc..) and yes I've been Googling and researching for a week now for this problem before deciding to post this.
I can successfully post to Facebook, however the posts are not public that everyone can see, only the primary page admin. Even after manually going through each post and "approving" them they are still not publicly available. I posted the question to Facebook and got a thank you for posting a question but no answer.
I created a Facebook app then using Facebook Graph API I got some access tokens for the app and made the access token permanent.
I can post using the Facebook SDK for .Net but again on the primary page admin can see the posts and nothing will make them visible.
Here is the access token info:
App ID 435958876564133 : RROADSus
Profile ID 830833833664593 : RROADSus
User ID
596954487156779 : Janel Xxxxx
User last installed this app via API N/A
Issued 1487528725 (about a month ago)
Expires Never
Valid True
Origin Web
Scopes manage_pages, publish_pages, pages_manage_cta, publish_actions, public_profile
Here is the code in the class to post to Facebook:
public static void postGotRV_FB(string Msg, string Picture, string Link, string Caption, string Desc)
{
string fb_Token = ConfigurationManager.AppSettings["fb:PermToken"];
FacebookClient client = new FacebookClient(fb_Token);
dynamic messagePost = new ExpandoObject();
messagePost.access_token = fb_Token;
messagePost.message = Msg.ToString().Trim();
if (string.IsNullOrEmpty(Picture) == false)
{
Picture = Picture.Replace("../", "http://www.RROADS.us/");
messagePost.source = Picture;
}
if (string.IsNullOrEmpty(Link) == false)
messagePost.link = Link.ToString().Trim();
if (string.IsNullOrEmpty(Caption) == false)
messagePost.caption = Caption.ToString().Trim();
if (string.IsNullOrEmpty(Desc) == false)
messagePost.description = Desc;
var result = client.Post("/830833833664593/feed", messagePost);
}
Here is the code I am calling to test the function off a button keypress:
protected void Unnamed1_Click(object sender, EventArgs e)
{
//string image = "Got-RV.png";
string image = "../Images/RROADS.png";
string Msg = "Hello From RROADS.us";
string Link = "http://www.RROADS.us";
string Caption = "Image Caption";
string Desc = "This is my test Description";
SocialMedia.postGotRV_FB(Msg, image, Link, Caption, Desc);
}
The post appears when you view the page as admin :
Hello From RROADS.us
<< IMAGE IS HERE >>
The Heart of Your Adventure
This is my test Description
IMAGE CAPTION
But when you view the page as anyone else this post does not appear.
What am I missing?
Thank you in advance!
Doing a project in Umbraco, and i've encountered problems in one case that when calling node.NiceUrl I get # as the result. What is weird though is that if i debug it somehow it resolves into the correct url.
var pages = Pages.Select((item, index) => new
{
Url = item.NiceUrl,
Selected = item.Id == currentPage.Id,
Index = index
}).ToList();
Where Pages is obtained from:
CurrentPage.Parent.ChildrenAsList
If I do it this way, it works, but I don't know why.
Url = new Node(item.Id).NiceUrl,
I've encountered this error and it was because the id belonged to a media node.
Media is treated differently to other content and there's no easy way of getting the url because different types of media store the url in different ways depending on context. That's why the NiceUrl function doesn't work for media (according to the umbraco developers).
My specific scenario was using images that had been selected using a media picker. I got the url via the following code. I wrapped it up in an extension method so you can consume it from a template in a convenient way.
public static string GetMediaPropertyUrl(this IPublishedContent thisContent, string alias, UmbracoHelper umbracoHelper = null)
{
string url = "";
if (umbracoHelper == null)
umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
var property = thisContent.GetProperty(alias);
string nodeID = property != null ? property.Value.ToString() : "";
if (!string.IsNullOrWhiteSpace(nodeID))
{
//get the media via the umbraco helper
var media = umbracoHelper.TypedMedia(nodeID);
//if we got the media, return the url property
if (media != null)
url = media.Url;
}
return url;
}
Try like this
Url = umbraco.library.NiceUrl(Item.Id);
I'm trying to create a simple iFrame custom tab on my fan page. I'm using the Facebook C# SDK and I need to read the signed_request value that Facebook passes to my iFrame page.
I can print the signed_request encoded value so I know its showing up, but when I try to decode it with the Facebook C# SDK I'm getting an error. I'm using .NET 4.0 and dynamics.
Here's my code:
signedRequestString contains the Request value with the signed_param passed from Facebook.
var result = FacebookSignedRequest.Parse(FacebookContext.Current.AppSecret, signedRequestString);
dynamic signedRequestJson = result.Data;
dynamic page = signedRequestJson.page;
And the error I receive:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Cannot perform runtime binding on a null reference at CallSite.Target(Closure , CallSite , Object ) at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0) at DecodeSignedRequest(String signedRequestString)
Any thoughts why I would be getting a null? I setup my web.config properly (I think), but I'm guessing I'm missing an initialization step or something.
It's easier to use FacebookWebContext.Current.SignedRequest.
You can then access the information about the page:
if (FacebookWebContext.Current.SignedRequest != null)
{
dynamic data = FacebookWebContext.Current.SignedRequest.Data;
if (data.page != null)
{
var pageId = (String)data.page.id;
var isUserAdmin = (Boolean)data.page.admin;
var userLikesPage = (Boolean)data.page.liked;
}
else
{
// not on a page
}
}
You need to cast your signedRequestJson object to an IDictionary key/value pair before you can grab the page data.
You can do this as follows:
dynamic signedRequestJson = result.Data;
var RawRequestData = (IDictionary<string, object>)signedRequestJson;
You can then access the page data using the JSON keys (assuming you are referencing the Newtonsoft.Json.dll library):
Facebook.JsonObject RawPageData = (Facebook.JsonObject)RawRequestData["page"];
currentFacebookPageID = (string)RawPageData["id"];
Hope this helps.
I am using this. I hope it works for you:
Facebook.FacebookConfigurationSection s = new FacebookConfigurationSection();
s.AppId = 'ApplicationID';
s.AppSecret = 'ApplicationSecret';
FacebookWebContext wc = new FacebookWebContext(s);
dynamic da = wc.SignedRequest.Data;
dynamic page = da.page;
string pageid = page.id;
bool isLiked = page.liked;
bool isAdmin = page.admin;
I have a search page on my .NET 3.5 Web Forms site that redirects a user to an external site based on the user's search parameters. I would redirect to: http://www.site.com/search.aspx?searchterm=Hello.
But now they are changing the site so that the search parameter is passed as a POST parameter, and not in the query string. So the page is expecting "searchterm".
So not only do I need to redirect to the external page, I have to post data to the page as well. I have no idea how to do this and I don't know where to start.
Is this something I can do in Web Forms without some glitchy workaround? Or maybe it can be done using jQuery?
Most browsers will explicitely deny this. Doing a cross server post like this would lead to security issues.
You can create simple JavaScript function for execute POST redirect to external page (dynamicaly generate and initilaze form object and submit it).
For example (values pattern: a=1&b=2&c=3 ...):
function bind(pageURL, values) {
var form=document.createElement('form');
form.action= pageURL;
form.target='_blank';
form.style.display = 'none';
form.method = 'POST';
var valuesSplit = node.get_value().toString().split("&");
for (var i = 0; i < valuesSplit.length - 1; i++) {
var p = valuesSplit[i];
var ps = p.split('=');
addParam(form, ps[0], ps[1]);
}
document.body.appendChild(form);
form.submit();
}
function addParam(form,key,value){
var input= document.createElement('input');
input.name=key;
input.value=value;
form.appendChild(input);
}