Cannot create an ad or ad creative via the facebook API - laravel

So I'm working on a project from work using the facebook API so we can build ads (yes I know you can do it from facebook ads manager but my company wants me to create our own interface). Anyways so I'm able to create campaigns and ad sets through the API but I cannot seem to have any luck with ads and or creatives.
{message: "Invalid parameter", exception: "FacebookAds\Http\Exception\AuthorizationException",…}
exception
:
"FacebookAds\Http\Exception\AuthorizationException"
file
:
"/Users/bradgoldsmith/Desktop/SquibLib/vendor/facebook/php-ads-sdk/src/FacebookAds/Http/Exception/RequestException.php"
line
:
144
message
:
"Invalid parameter"
trace
:
[{,…}, {,…},…]
That's the error I seem to get and from the looks it has something to do with Authorization but I'm able to create campaigns and ad sets so I figured I'm authorized. I'm just testing dummy data on a page that I am an admin on. Any advice or pointers in the right direction would be greatly appreciated.

So turns out the authorization issue has something to do with the fact that our app is still in review. I was able to however create a carousel ad/ad creative through their API with this bit of code, which I also got from their documentation. Anyways the code that worked for me is here:
$product1 = (new AdCreativeLinkDataChildAttachment())->setData(array(
AdCreativeLinkDataChildAttachmentFields::LINK =>
'https://www.link.com/product1',
AdCreativeLinkDataChildAttachmentFields::NAME => 'Product 1',
AdCreativeLinkDataChildAttachmentFields::DESCRIPTION => '$8.99',
AdCreativeLinkDataChildAttachmentFields::IMAGE_HASH => '<IMAGE_HASH>',
));
$product2 = (new AdCreativeLinkDataChildAttachment())->setData(array(
AdCreativeLinkDataChildAttachmentFields::LINK =>
'https://www.link.com/product2',
AdCreativeLinkDataChildAttachmentFields::NAME => 'Product 2',
AdCreativeLinkDataChildAttachmentFields::DESCRIPTION => '$9.99',
AdCreativeLinkDataChildAttachmentFields::IMAGE_HASH => '<IMAGE_HASH>',
));
$product3 = (new AdCreativeLinkDataChildAttachment())->setData(array(
AdCreativeLinkDataChildAttachmentFields::LINK =>
'https://www.link.com/product3',
AdCreativeLinkDataChildAttachmentFields::NAME => 'Product 3',
AdCreativeLinkDataChildAttachmentFields::DESCRIPTION => '$10.99',
AdCreativeLinkDataChildAttachmentFields::IMAGE_HASH => '<IMAGE_HASH>',
));
$link_data = new AdCreativeLinkData();
$link_data->setData(array(
AdCreativeLinkDataFields::LINK => '<URL>',
AdCreativeLinkDataFields::CHILD_ATTACHMENTS => array(
$product1, $product2, $product3,
),
));
$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
AdCreativeObjectStorySpecFields::PAGE_ID => <PAGE_ID>,
AdCreativeObjectStorySpecFields::LINK_DATA => $link_data,
));
$creative = new AdCreative(null, 'act_<AD_ACCOUNT_ID>');
$creative->setData(array(
AdCreativeFields::NAME => 'Sample Creative',
AdCreativeFields::OBJECT_STORY_SPEC => $object_story_spec,
));
$creative->create();

Related

Creating DataService for Quickbooks PHP API for Laravel

Good Day! so i was integrating Quickbooks PHP API, i finished installing the SDK via composer and i'm about to configure it
My question is where do i exactly put this code in Laravel
use QuickBooksOnline\API\DataService\DataService;
// Prep Data Services
$dataService = DataService::Configure(array(
'auth_mode' => 'oauth2',
'ClientID' => "Client ID from the app's keys tab",
'ClientSecret' => "Client Secret from the app's keys tab",
'RedirectURI' => "The redirect URI provided on the Redirect URIs part under keys tab",
'scope' => "com.intuit.quickbooks.accounting or com.intuit.quickbooks.payment",
'baseUrl' => "Development/Production"
));
Thank you

TYPO3 E-Mail Spam Protection

I’ve got a Problem with spam protection in TYPO3 v9.5 for a long time in my own template extension and custom content elements.
I would expect, that the E-Mail Links inserted via TypoLink in ckEditor would be transformed to name(at)domain.de in the frontend by using the following snippet in my Setup. But its simply is ignored:
config.spamProtectEmailAddresses = 2
config.spamProtectEmailAddresses_atSubst = <span>(at)</span>
I’ve set up a clean Installation with 9.5.15 and it just works. So I think it has something to do with my template-extension or my custom components with custom ckEditor config.
Can someone with a better understanding of TYPO3 please guide me to the right direction?
Here is my TCA for the Textfield:
'bodytext' => [
'exclude' => true,
'label' => 'Kontaktdaten',
'config' => [
'type' => 'text',
'cols' => 40,
'rows' => 3,
'softref' => 'rtehtmlarea_images,typolink_tag,email[subst],url',
],
'defaultExtras' => 'richtext:rte_transform[flag=rte_enabled|mode=ts_css]'
],
compare your TCA field configuration with the configuration of the field tt_content.bodytext
I guess you missed: config.softref = typolink_tag,images,email[subst],url

RealURL 2.2.1 remove segment/pagePath completly from generated URL

I have a problem regarding the new RealURL version 2.2.1. After upgrading to Typo3 7.6 we got the new RealURL version. The concept in the old version (6.2) was that the pagePath in the URL was completely empty.
For example if you the following tree is:
page1
-- page2
---- page3
the url for page3 was http://test.de/page3.html so the complete pagePath and subfolders were removed from the URL. In the old configuration we could get that effect if the pagePath segment in the realURL configuration was empty.
<?php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl'] = array(
'_DEFAULT' => array(
'init' => array(
'enableCHashCache' => true,
'appendMissingSlash' => 'ifNotFile,redirect',
'adminJumpToBackend' => false,
'enableUrlDecodeCache' => true,
'enableUrlEncodeCache' => true,
'emptyUrlReturnValue' => '/',
),
'fileName' => array(
'defaultToHTMLsuffixOnPrev' => 1,
'acceptHTMLsuffix' => 1,
),
'pagePath' => array(),
),
);
In the new version it isn't working anymore. I've tried a lot now to get the same state as before. But all i get is an URL with the complete path for example http://test.de/page1/page2/page3.html. This would destroy all URLs on Google. Does anyone know how i can fix that problem?
Go to your database and and set the field tx_realurl_exclude ("Exclude from speaking URL") to 1 for all pages (and pages_language_overlay) records.
Make sure every new page has set this value by default.

How to send push notification in Laravel using AWS SNS with default sound in Android and iOS device?

I have code like the below to send push notification. It is sent but with no sound on notification.
$sns = App::make('aws')->createClient('sns');
$sns->publish(array(
'TargetArn' => ‘arn:aws:sns:us-east-1:757730885501:endpoint/APNS/…..’,
       'Message' => ‘Test message’
));
Any suggestions please?!
Try this,
For iOS device, use like this
$apns_payload = json_encode(array("aps" => array("alert" => "This is a test message", "sound" => 'default')));
$message = json_encode(array( "default" => "This is a test message", "APNS" => $apns_payload));
For Android device, use like this
$gcm_payload = json_encode(array("data" => array("message" => "This is a test message", "sound" => 'default')));
$message = json_encode(array("default" => "This is a test message", "GCM" => $gcm_payload));
And finally, publish with your AWS SNS device ARN like below,
TargetArn gets changed based on device token and platform
If iOS,
$target_arn = "arn:aws:sns:us-east-1:757730885501:endpoint/APNS/.....";
If Android,
$target_arn = "arn:aws:sns:us-east-1:757730885501:app/GCM/.....";
$sns->publish(array(
'TargetArn' => $target_arn,
'Message' => $message,
'MessageStructure' => 'json'
));
If you need to play the default sound in the device, you can set it as default, or else you can also use like ‘sound’ => ‘doorbell.caf’.

How to use google-api-ruby-client with the Google Calendar API?

I've been reading the docs for the Google Calendar API and the google-api-ruby-client library, but I'm having a lot of trouble understanding them.
I have a Rails application that has a front end that lets users create objects called Events, and it saves them in a database on my server. What I would like is, after these Events are saved in the database, I want to call the Google Calendar API to create an event on a Google Calendar (that the server created, and only the server has access to modify that calendar).
I'm having lots of issues figuring out how to authenticate with the API using the ruby library. It doesn't make sense for me to use OAuth2 because I don't need to authorize anything with the user because I'm not interested in their data. I looked into Service Accounts (http://code.google.com/p/google-api-ruby-client/wiki/ServiceAccounts), but it looks like Google Calendars is not supported by Service Accounts.
Anyone have any ideas? This is the code I was experimenting with (using Service Accounts):
#client = Google::APIClient.new(:key => 'my_api_key')
path_to_key_file = '/somepath/aaaaaa-privatekey.p12'
passphrase = 'my_pass_phrase'
key = Google::APIClient::PKCS12.load_key(path_to_key_file, passphrase)
asserter = Google::APIClient::JWTAsserter.new(
'blah_blah#developer.gserviceaccount.com',
'https://www.googleapis.com/auth/calendar',
key)
# To request an access token, call authorize:
#client.authorization = asserter.authorize()
calendar = #client.discovered_api('calendar', 'v3')
event = {
'summary' => 'Appointment',
'location' => 'Somewhere',
'start' => {
'dateTime' => '2012-06-03T10:00:00.000-07:00'
},
'end' => {
'dateTime' => '2012-06-03T10:25:00.000-07:00'
},
'attendees' => [
{
'email' => 'attendeeEmail'
},
#...
]
}
result = #client.execute!(:api_method => calendar.events.insert,
:parameters => {'calendarId' => 'primary'},
:body => JSON.dump(event),
:headers => {'Content-Type' => 'application/json'})
Then of course I get this error message: Google::APIClient::ClientError (The user must be signed up for Google Calendar.) because the Service Account does not support Google Calendars.
I think you'll still need a real google user to host the calendar instance. But once you've got the calendar created under your identity, you can share it with the service account. In the sharing settings for the calendar, just use the email address of the service account (my service account ends with #developer.gserviceaccount.com). With the right sharing permissions, your service account can create/alter the event info, and not mess with your specific identity. From there, you can share the calendar with more people (or public) for their consumption of the mirrored events.
The other hitch I've run into is that it seems you can only authorize() the service account once per expiration period. You'll have to save the token you get and reuse it for the next hour, and then fetch a new one.
I don't know anything about Ruby. But it seems like understanding the underlying REST queries would help debug your problem. I've documented them here: http://www.tqis.com/eloquency/googlecalendar.htm
I was having trouble with this too and finally got a handle on it. The bottom line is that Google Calendar API v3 requires OAuth and you need to setup an App/Project through the Google Developer Console and then request OAuth permission on the target Google account. Once authorization is granted, you'll want to save the refresh token and use it on subsequent calls to get new access tokens (which expire!). I wrote a detailed blog post about this here: http://www.geekytidbits.com/google-calendar-api-from-ruby/ and this is my example script that should hopefully help you understand the flow:
#gem install 'google-api-client'
require 'google/api_client'
#Setup auth client
client_secrets = Google::APIClient::ClientSecrets.load #client_secrets.json must be present in current directory!
auth_client = client_secrets.to_authorization
auth_client.update!(
:scope => 'https://www.googleapis.com/auth/calendar',
:access_type => "offline", #will make refresh_token available
:approval_prompt =>'force',
:redirect_uri => 'http://www.myauthorizedredirecturl.com'
)
refresh_token_available = File.exist?('refresh_token.txt')
if !refresh_token_available
#OAuth URL - this is the url that will prompt a Google Account owner to give access to this app.
puts "Navigate browser to: '#{auth_client.authorization_uri.to_s}' and copy/paste auth code after redirect."
#Once the authorization_uri (above) is followed and authorization is given, a redirect will be made
#to http://www.myauthorizedredirecturl.com (defined above) and include the auth code in the request url.
print "Auth code: "
auth_client.code = gets
else
#If authorization has already been given and refresh token saved previously, simply set the refresh code here.
auth_client.refresh_token = File.read('refresh_token.txt')
end
#Now, get our access token which is what we will need to work with the API.
auth_client.fetch_access_token!
if !refresh_token_available
#Save refresh_token for next time
#Note: auth_client.refresh_token is only available the first time after OAuth permission is granted.
#If you need it again, the Google Account owner would have deauthorize your app and you would have to request access again.
#Therefore, it is important that the refresh token is saved after authenticating the first time!
File.open('refresh_token.txt', 'w') { |file| file.write(auth_client.refresh_token) }
refresh_token_available = true
end
api_client = Google::APIClient.new
cal = api_client.discovered_api('calendar', 'v3')
#Get Event List
puts "Getting list of events..."
list = api_client.execute(:api_method => cal.events.list,
:authorization => auth_client,
:parameters => {
'maxResults' => 20,
'timeMin' => '2014-06-18T03:12:24-00:00',
'q' => 'Meeting',
'calendarId' => 'primary'})
puts "Fetched #{list.data.items.count} events..."
#Update Event
puts "Updating first event from list..."
update_event = list.data.items[0]
update_event.description = "Updated Description here"
result = api_client.execute(:api_method => cal.events.update,
:authorization => auth_client,
:parameters => { 'calendarId' => 'primary', 'eventId' => update_event.id},
:headers => {'Content-Type' => 'application/json'},
:body_object => update_event)
puts "Done with update."
#Add New Event
puts "Inserting new event..."
new_event = cal.events.insert.request_schema.new
new_event.start = { 'date' => '2015-01-01' } #All day event
new_event.end = { 'date' => '2015-01-01' }
new_event.description = "Description here"
new_event.summary = "Summary here"
result = api_client.execute(:api_method => cal.events.insert,
:authorization => auth_client,
:parameters => { 'calendarId' => 'primary'},
:headers => {'Content-Type' => 'application/json'},
:body_object => new_event)
puts "Done with insert."

Resources