我在更新广告创意网址标签时遇到了问题。
我知道我们无法更新现有广告素材的网址标记。
因此,我尝试使用已修改的网址标记克隆现有网址,并尝试删除旧网址,但删除了创建问题,现在我收到了此错误。
您无法删除此广告素材,因为它当前正在使用中 现有广告组
尝试将广告状态更改为“已删除”,但这也不起作用。此外,尝试将广告状态更改为“已暂停”,但根本没有运气。即使API也不会更新广告状态。
任何人,请指导我如何解决这个问题?或者我可以通过其他任何方式更新广告创意网址标记?
我正在使用PHP SDK并遵循此FB documentation。 我拥有我的应用程序所需的所有权限,并且它们也被FB批准。
答案 0 :(得分:0)
这就是我正在做的工作,仍然有几个问题,但这可以解决大多数类型的广告:
public function appendAdSetIdsToCreatives($fbAccountId, $adsetIds, $creativeIds, $fullSync = false, $dryRun = false)
{
$urlTagArray = [];
$attempts = 0;
Cursor::setDefaultUseImplicitFetch(true);
$account = new AdAccount('act_' . $fbAccountId);
$params['limit'] = 1000;
$params[AdFields::EFFECTIVE_STATUS] = array(AdEffectiveStatusValues::ACTIVE, AdEffectiveStatusValues::PENDING_BILLING_INFO, AdEffectiveStatusValues::PENDING_REVIEW, AdEffectiveStatusValues::PREAPPROVED);
if (!$fullSync) {
$params['updated_since'] = Carbon::now()->subDay()->timestamp;
}
if (!empty($adsetIds)) {
$params[AdFields::ADSET_ID] = $adsetIds;
}
$updateCount = 0;
$skipCount = 0;
$exception = null;
do {
try {
$cursor = $account->getAds(array(AdFields::ID, AdFields::NAME, AdFields::ADSET_ID, AdFields::CREATIVE, AdFields::STATUS, AdFields::EFFECTIVE_STATUS), $params);
foreach ($cursor as $ad) {
//If adset specified in command, ignore if ad not belongs to specified adset
if (!empty($adsetIds) && !in_array($ad->adset_id, $adsetIds)) {
continue;
}
foreach ($ad->creative as $creativeId) {
if(!empty($creativeIds) && !in_array($creativeId, $creativeIds)) {
continue;
}
$creativeParams = ['id' => $creativeId];
$creativeCursor = $ad->getAdCreatives(array(
AdCreativeFields::ACCOUNT_ID,
AdCreativeFields::ACTOR_ID,
AdCreativeFields::ADLABELS,
AdCreativeFields::APPLINK_TREATMENT,
AdCreativeFields::BODY,
AdCreativeFields::CALL_TO_ACTION_TYPE,
AdCreativeFields::EFFECTIVE_INSTAGRAM_STORY_ID,
AdCreativeFields::EFFECTIVE_OBJECT_STORY_ID,
AdCreativeFields::ID,
AdCreativeFields::IMAGE_CROPS,
AdCreativeFields::IMAGE_HASH,
AdCreativeFields::IMAGE_URL,
AdCreativeFields::INSTAGRAM_ACTOR_ID,
AdCreativeFields::INSTAGRAM_PERMALINK_URL,
AdCreativeFields::INSTAGRAM_STORY_ID,
AdCreativeFields::LINK_OG_ID,
AdCreativeFields::LINK_URL,
AdCreativeFields::NAME,
AdCreativeFields::OBJECT_ID,
AdCreativeFields::OBJECT_STORY_ID,
AdCreativeFields::OBJECT_STORY_SPEC,
AdCreativeFields::OBJECT_TYPE,
AdCreativeFields::OBJECT_URL,
AdCreativeFields::PLATFORM_CUSTOMIZATIONS,
AdCreativeFields::PRODUCT_SET_ID,
AdCreativeFields::STATUS,
AdCreativeFields::TEMPLATE_URL,
AdCreativeFields::TEMPLATE_URL_SPEC,
AdCreativeFields::THUMBNAIL_URL,
AdCreativeFields::TITLE,
AdCreativeFields::URL_TAGS,
AdCreativeFields::USE_PAGE_ACTOR_OVERRIDE,
AdCreativeFields::VIDEO_ID,
AdCreativeFields::CALL_TO_ACTION,
AdCreativeFields::DYNAMIC_AD_VOICE,
AdCreativeFields::IMAGE_FILE
), array($creativeParams));
foreach ($creativeCursor as $adCreative) {
Log::info("Ad Account Id: " . $fbAccountId . " AdSet Id: " . $ad->adset_id . " STATUS: " . $ad->status . " E STATUS: " . $ad->effective_status . " Ad Id: " . $ad->id . " Ad Name: " . $ad->name . " Ad Creative Id: " . $adCreative->id . " Url Tags: " . $adCreative->url_tags);
if ($this->isValidCampaignObject($ad->adset_id)){
if (isset($adCreative->{ AdCreativeFields::URL_TAGS })) {
if ($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC} == null ){
parse_str($adCreative->url_tags, $urlTagArray);
if (!array_key_exists('asid', $urlTagArray)) {
$updateCount++;
$urlTagArray['asid'] = $ad->adset_id;
ksort($urlTagArray);
$adCreative->{ AdCreativeFields::URL_TAGS } = http_build_query($urlTagArray);
ksort($urlTagArray);
parse_str($adCreative->url_tags, $urlTagArray);
if (!$dryRun) {
$this->replaceAdCreative($ad, $adCreative);
}
} else {
$skipCount++;
Log::info("Skipping [Key Exists] " . " Ad Account Id: " . $fbAccountId . " AdSet Id: " . $ad->adset_id . " STATUS: " . $ad->status . " E STATUS: " . $ad->effective_status . " Ad Id: " . $ad->id . " Ad Name: " . $ad->name . " Ad Creative Id: " . $adCreative->id . " Url Tags: " . $adCreative->url_tags);
}
}
else {
$skipCount++;
Log::info("Skipping [ObjectStorySpec] " . " Ad Account Id: " . $fbAccountId . " AdSet Id: " . $ad->adset_id . " STATUS: " . $ad->status . " E STATUS: " . $ad->effective_status . " Ad Id: " . $ad->id . " Ad Name: " . $ad->name . " Ad Creative Id: " . $adCreative->id . " Url Tags: " . $adCreative->url_tags);
}
}
else {
$skipCount++;
Log::info("Skipping [Missing URL Tag] " . " Ad Account Id: " . $fbAccountId . " AdSet Id: " . $ad->adset_id . " STATUS: " . $ad->status . " E STATUS: " . $ad->effective_status . " Ad Id: " . $ad->id . " Ad Name: " . $ad->name . " Ad Creative Id: " . $adCreative->id . " Url Tags: " . $adCreative->url_tags);
}
}
else{
$skipCount++;
Log::info("Skipping [Invalid Campaign Objective] " . " Ad Account Id: " . $fbAccountId . " AdSet Id: " . $ad->adset_id . " STATUS: " . $ad->status . " E STATUS: " . $ad->effective_status . " Ad Id: " . $ad->id . " Ad Name: " . $ad->name . " Ad Creative Id: " . $adCreative->id . " Url Tags: " . $adCreative->url_tags);
}
}
}
}
break;
} catch (\Exception $e) {
$exception = $e;
$updateCount = 0;
$skipCount = 0;
$attempts++;
Log::error("Sync Ad Url Tag Error for Account[" . $fbAccountId . "] Code:" . $e->getCode() . " Message:" . $e->getMessage() . PHP_EOL . $e->getTraceAsString());
Log::warning("Sleeping for " . ($attempts * 30) . " seconds...");
sleep($attempts * 30);
continue;
}
} while ($attempts < env('COMMAND_RETRY_LIMIT', 3));
if ($attempts >= env('COMMAND_RETRY_LIMIT', 3)) {
throw $exception;
}
Log::info("Ad Account Id: " . $fbAccountId . " Updated AdSets: " . $updateCount . " Skipped AdSets: " . $skipCount);
return (object)['updateCount' => $updateCount, 'skipCount' => $skipCount];
}
&#39; replaceAdCreative&#39;方法:
private function replaceAdCreative($ad, $adCreative)
{
$newAdCreative = new AdCreative(null);
if ($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC} != null ){
$adCreativeObjectStorySpecField = null;
if (ISSET($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[AdCreativeObjectStorySpecFields::VIDEO_DATA]))
{
$adCreativeObjectStorySpecField = adCreativeObjectStorySpecFields::VIDEO_DATA;
}
else if (ISSET($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[adCreativeObjectStorySpecFields::LINK_DATA]))
{
$adCreativeObjectStorySpecField = adCreativeObjectStorySpecFields::LINK_DATA;
}
else if (ISSET($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[adCreativeObjectStorySpecFields::PHOTO_DATA]))
{
$adCreativeObjectStorySpecField = adCreativeObjectStorySpecFields::PHOTO_DATA;
}
else if (ISSET($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[adCreativeObjectStorySpecFields::TEMPLATE_DATA]))
{
$adCreativeObjectStorySpecField = adCreativeObjectStorySpecFields::TEMPLATE_DATA;
}
if ($adCreativeObjectStorySpecField != null){
if (ISSET($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[$adCreativeObjectStorySpecField]->{AdCreativeFields::IMAGE_URL}) &&
ISSET($adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[$adCreativeObjectStorySpecField]->{AdCreativeFields::IMAGE_HASH}))
$adCreative->{AdCreativeFields::OBJECT_STORY_SPEC}[$adCreativeObjectStorySpecField][AdCreativeFields::IMAGE_URL] = NULL;
//@TODO this is not working!!!^^^^
}
}
$newAdCreative->setData(array(
AdCreativeFields::ACCOUNT_ID => $ad->account_id,
AdCreativeFields::ACTOR_ID => $adCreative->actor_id,
AdCreativeFields::ADLABELS => $adCreative->adlabels,
AdCreativeFields::APPLINK_TREATMENT => $adCreative->applink_treatment,
AdCreativeFields::BODY => $adCreative->body,
AdCreativeFields::CALL_TO_ACTION_TYPE => $adCreative->call_to_action_type,
AdCreativeFields::EFFECTIVE_INSTAGRAM_STORY_ID => $adCreative->effective_instagram_story_id,
AdCreativeFields::EFFECTIVE_OBJECT_STORY_ID => $adCreative->effective_object_story_id,
AdCreativeFields::ID => $adCreative->id,
AdCreativeFields::IMAGE_CROPS => $adCreative->image_crops,
AdCreativeFields::IMAGE_HASH => $adCreative->image_hash,
AdCreativeFields::IMAGE_URL => $adCreative->image_url,
AdCreativeFields::INSTAGRAM_ACTOR_ID => $adCreative->instagram_actor_id,
AdCreativeFields::INSTAGRAM_PERMALINK_URL => $adCreative->instagram_permalink_url,
AdCreativeFields::INSTAGRAM_STORY_ID => $adCreative->instagram_story_id,
AdCreativeFields::LINK_OG_ID => $adCreative->link_og_id,
AdCreativeFields::LINK_URL => $adCreative->link_url,
AdCreativeFields::NAME => $adCreative->name,
AdCreativeFields::OBJECT_ID => $adCreative->object_id,
AdCreativeFields::OBJECT_STORY_ID => $adCreative->object_story_id,
AdCreativeFields::OBJECT_STORY_SPEC => $adCreative->object_story_spec,
AdCreativeFields::OBJECT_TYPE => $adCreative->object_type,
AdCreativeFields::OBJECT_URL => $adCreative->object_url,
AdCreativeFields::PLATFORM_CUSTOMIZATIONS => $adCreative->platform_customizations,
AdCreativeFields::PRODUCT_SET_ID => $adCreative->product_set_id,
AdCreativeFields::STATUS => $adCreative->status,
AdCreativeFields::TEMPLATE_URL => $adCreative->template_url,
AdCreativeFields::TEMPLATE_URL_SPEC => $adCreative->template_url_spec,
AdCreativeFields::THUMBNAIL_URL => $adCreative->thumbnail_url,
AdCreativeFields::TITLE => $adCreative->title,
AdCreativeFields::URL_TAGS => $adCreative->url_tags,
AdCreativeFields::USE_PAGE_ACTOR_OVERRIDE => $adCreative->use_page_actor_override,
AdCreativeFields::VIDEO_ID => $adCreative->video_id,
AdCreativeFields::CALL_TO_ACTION => $adCreative->call_to_action,
AdCreativeFields::DYNAMIC_AD_VOICE => $adCreative->dynamic_ad_voice,
AdCreativeFields::IMAGE_FILE => $adCreative->image_file,
));
Log::info("Old Creative Id: " . $adCreative->id . " Old Creative Creative Id: " . $adCreative->creative_id);
$ad->creative = $newAdCreative;
try{
$adCreativeResponse = $ad->update();
}
catch (RequestException $e){
$errorMsg = $this->requestExceptionToString($e);
Log::error($errorMsg);
throw new \Exception($errorMsg);
}
Log::info("New Creative Id: " . $adCreativeResponse->creative->id . " New Creative Creative Id: " . $adCreativeResponse->creative->creative_id);
Log::info("Updated: " . " Ad Account Id: " . $ad->account_id . " AdSet Id: " . $ad->adset_id . " Ad Id: " . $ad->id . " Ad Name: " . $ad->name . " Ad Creative Id: " . $adCreativeResponse->creative->id . " Url Tags: " . $adCreativeResponse->creative->url_tags);
}
答案 1 :(得分:0)
我通过以下步骤成功完成了这项工作
以下是我用来解决此问题的PHP代码。
import { Component } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
interface AppState {
foo: boolean;
}
@Component(
selector: 'foo-component',
template: `<p>{{ ( foo$ | async ) ? "it's foo!" : "nope, not foo" }}</p>`
)
export class FooComponent {
private foo$: Observable<boolean>;
constructor(private store: Store<AppState>) {
this.foo$ = store.pipe(select('foo'));
}
}
完成。