Create Ads from published page post in Facebook - ruby-on-rails

I want to create Ads by using Facebook Published page post. For this process, I'm able to get all Published Posts of a Page through graph API (page_id/posts). Also, I can create ad creative along with the Post_Id. However, When I use this created ad_creative id in the Ad creation process, it through this error "Invalid parameter: Ad Creative Does Not Use Valid Link."
For Doc... references: https://developers.facebook.com/docs/marketing-api/reference/ad-creative#obtaining_pp Also for generating the ad, I used this method.
ad = ad_account.ads.create({
name: ' Ad* via Post',
adset_id: under_adset_id,
creative: {
creative_id: post_creative_id,
},
status: 'PAUSED',
})

Add 'link' field to request
creative: { creative_id: post_creative_id, link: "https://stackoverflow.com/"},

Related

Facebook Marketing API create Ad Creatives Error

I'm having issues creating Ad Creatives using:
gem 'facebookbusiness'
Facebook API version 13.0
I have successfully managed to upload Ad Images and to get the image URL and image hash in return.
The error happens when trying to create the Ad Creatives
creative = #ad_account.adcreatives.create({
title: 'My Page Like Ad',
body: 'Like My Page',
object_url: 'www.facebook.com',
link_url: 'www.facebook.com',
image_url: image[0]['url'],
image_hash: image[0]['hash'],
})
I get this error:
FacebookAds::ClientError in Admins::AdsController
Invalid parameter: Missing Image (fbtrace_id: Ao0FDSCOwt9ss_5W6CmNyhx)
you should special in field object_story_spec,not in image_hash
final AdCreativeObjectStorySpec objectStorySpec = new AdCreativeObjectStorySpec()
.setFieldVideoData(new AdCreativeVideoData()
.setFieldVideoId(video.getFieldId())
.setFieldImageHash(image.getFieldHash())
.setFieldCallToAction(callToAction))
.setFieldPageId(String.valueOf(page.getId()));
account.createAdCreative()
.setObjectStorySpec(objectStorySpec);

Is there a way to link the Google Identity Token to my company user in the database?

I'm setting up an action on google project which uses the OAuth & Google Sign In Linking Type.
Previously, I was using the userId that was sent in every request to look up the user in the database to see if there were accesstokens and refreshtokens available. But since userId is deprecated, I am looking for an alternative.
The user starts his/her dialog and then bumps into this piece of code:
app.intent('Give Color', async (conv, { color }) => {
conv.data[Fields.COLOR] = color;
if (conv.user.ref) {
await conv.user.ref.set({ [Fields.COLOR]: color });
conv.close(`I got ${color} as your favorite color.`);
return conv.close('Since you are signed in, I\'ll remember it next time.');
}
return conv.ask(new SignIn(`To save ${color} as your favorite color for next time`));
});
The "To continue, link Test App to your Google Account" on which the user selects the correct Google account.Then my /token endpoint is called on the OAuth server containing the Google ID Token (assertion) which holds all of the users data. I decode it, check in the database if the "sub" is already present, and I throw the following exception:
return res.status(401).send({ error: 'user_not_found' });
Then the normal OAuth procedure kicks in, where I deliver a token to Google. Sidenote: this is my own OAuth Server written in NodeJS. I am sure that the access- and refreshtoken are delivered to Google.
After token delivery, I get a new request on my action:
app.intent('Get Sign In', async (conv, params, signin) => {
if (signin.status !== 'OK') {
return conv.close('Let\'s try again next time.');
}
const color = conv.data[Fields.COLOR];
await conv.user.ref.set({ [Fields.COLOR]: color });
return conv.close(`I saved ${color} as your favorite color. `
+ 'Since you are signed in, I\'ll remember it next time.');
});
The signin.status has a value of "OK". But shouldn't the conv.user object contain the Google ID Token so that I can store the access- and refreshtoken along with this "sub" from the Google ID Token in my database? Or am I getting something wrong?
The content of the conv.user looks like this:
User {raw: Object, storage: Object, _id: undefined, locale: "en-BE", verification: "VERIFIED", …}
_id: undefined
[[StableObjectId]]: 7
access: Access {token: "ACCT-ATlbRmcpMI545WJFssRSlK1Jcza46NIB"}
entitlements: Array(0) []
id: undefined
last: Last {seen: Thu Aug 08 2019 10:53:17 GMT+0200 (Central Europea…}
locale: "en-BE"
name: Name {display: undefined, family: undefined, given: undefined}
permissions: Array(0) []
profile: Profile {token: undefined}
raw: Object {accessToken: "ACCT-ATlbRmcpMI545WJFssRSlK1Jcza46NIB", locale: "en-BE", lastSeen: "2019-08-08T08:53:17Z", …}
storage: Object {}
verification: "VERIFIED"
__proto__: Object {constructor: , _serialize: , _verifyProfile: , …}
conv.user.id is *DEPRECATED*: Use conv.user.storage to store data instead
It won't contain the Google ID of the user, because the user hasn't authorized that.
What they have authorized is whatever you've asked them to authorize via your OAuth server.
So you'll see the access token that your server has sent to the Assistant in conv.user.access, and you can then use this token to lookup who the user is in your database and take action accordingly.
If you specifically want their Google ID, you'll need to make sure that they use Google Sign-In on the same project as your Action (either through voice, a mobile app, or a webapp).
If you just need an ID so you can see when this user returns later, you can use the Google ID you get from Google Sign-In, or just generate an ID and store this in conv.user.storage.
Since I just want to have an ID, I will be using this:
If you just need an ID so you can see when this user returns later, you can use the Google ID you get from Google Sign-In, or just generate an ID and store this in conv.user.storage.
Thanks!

Allow access after sharing url

On a MVC 5 web site I would like visitors to be able to read the full version of a post only after they shared it on Facebook or Twitter.
I have seen this example in a few web sites ... What would be the best way to do this?
There is no real security issues here ... It is just a way to spread the word ...
My first idea would be to save a cookie with a post KEY (Guid) ... This key is not visible to the user so he will not know the value.
The problem is how do I know that he shared the url ... How do I get the confirmation?
Thank You,
Miguel
You get confirmation as follows, per the Facebook Developers Docs:
FB.ui(
{
method: 'feed',
name: 'Facebook Dialogs',
link: 'https://developers.facebook.com/docs/dialogs/',
picture: 'http://fbrell.com/f8.jpg',
caption: 'Reference Documentation',
description: 'Dialogs provide a simple, consistent interface for applications to interface with users.'
},
function(response) {
if (response && response.post_id) {
alert('Post was shared.'); //give access to article
} else {
alert('Post was not shared.'); //they chose not share... don't give access
}
});
I implemented this code almost verbatim in a .NET project (just replaced the alerts with my own functionality) where I gave users two entries into a contest if they shared the contest page (instead of one entry if they didn't share or did nothing).
As for Twitter, I've personally not implemented something similar, but your best bet is probably JavaScript Interfaces for Twitter for Websites.
I don't know about Facebook, but with Twitter a retweet is the same as a share. The statuses/retweeters/ids should work. If you have the id of the tweet, then you can hold a list of who retweeted it, updating as needed to get new ids.
https://dev.twitter.com/docs/api/1.1/get/statuses/retweeters/ids
If you don't want to write all of the code to authenticate and configure the endpoint, you could use a 3rd party library. Here's an example from my library, LINQ to Twitter v3.0 Beta:
ulong tweetID = 210591841312190464;
var status =
await
(from tweet in twitterCtx.Status
where tweet.Type == StatusType.Retweeters &&
tweet.ID == tweetID
select tweet)
.SingleOrDefaultAsync();
if (status != null && status.User != null)
status.Users.ForEach(
userID => Console.WriteLine("User ID: " + userID));
BTW, there's also a Facebook SDK for .NET.

Facebook UI call in ASP.NET MVC does not return the picture it should

Does anyone know why the picture attribute is not working in following Facebook UI call?
function postToWallUsingFBUi()
{
var data=
{
method: 'stream.publish',
message: "Posted using FB.ui and picture.",
display: 'iframe',
caption: "Caption",
name: "Name",
//ver 1 picture: 'http://www.somedomain.com/albums/s339/rockaja/fb-520.png',
//ver 2 picture: '#Url.Action("Action", "Controller", new { PageId = Model.PageTabId }, Request.Url.Scheme)',
picture: 'https://localhost/MyVirtualDirectory/Controller/Action/283659015078395',
link: "http://www.mydomain.com/", // Go here if user click the picture
description: "Description field",
actions: [{ name: 'action_links text!', link: 'http://www.mydomain.com' }]
}
FB.ui(data, onPostToWallCompleted);
}
As you can see the picture attribute uses a picture from localhost. If i paste this URL into the browsers's Address field, i get the picture as expected.
I also commented out other two versions:
version 1 is working properly as expected, but
version 2 is not working (this is an ASP.NET MVC call, but that fact does not affect the result).
May be it is due to the fact that i request a localhost-ed picture?!
I have never worked on FB API so take my suggestion with a pinch of salt.
Based on my understanding of how Facebook works, whatever pictures you share on user's wall go into FB's data store first and are always pulled from that store.
Here, The Facebook API may be downloading the picture from the URL you have provided and push it into it's own store before publishing it on user's walls. When you use a localhost url, then the call to download the picture would obviously fail.
There must be another version of the API where you should be able to send the picture content as byte array. If there is, then you can load the picture from disk yourself and send the byte array in the API

Facebook Graph Feed Post Not Including Message

I have the following snippet to post to a user's feed on Facebook:
require 'httparty'
token = "..."
message = "..."
url = URI.escape("https://graph.facebook.com/me/feed?access_token=#{token}")
response = HTTParty.post(url, body: { message: message })
This posts to the wall, but no message is included. Any ideas what's wrong?
Edit:
I tried changing out the message for a caption or description and both failed as well.
Solution is to change HTTParty from using body to query for posting form data:
require 'httparty'
token = "..."
message = "..."
url = URI.escape("https://graph.facebook.com/me/feed?access_token=#{token}")
response = HTTParty.post(url, query: { message: message })
Based on the link cited above, it appears message functionality has been completely removed from the feed connection since July 12.
This is a problem for my current app as it is specifically a public opinion site. Asking users to express their opinions authentically is an important part of our design and we'd like to give them the option to post that to their feeds on Facebook as well.
Per the Facebook terms of use IV.2, "You must not pre-fill any of the fields associated with the following products, unless the user manually generated the content earlier in the workflow." The new change appears to change the terms of service: in my use, I am specifically asking the user to generate the content earlier in the workflow, but I still can't use it to pre-fill the feed dialog.
Anyone have any ideas or insight?

Resources