ai

Andrew Perpetua — เรียนรู้เกี่ยวกับ Facebook Ads

Andrew Perpetua — เรียนรู้เกี่ยวกับ Facebook Ads

Andrew Perpetua และ Facebook Ads

Andrew Perpetua — เรียนรู้เกี่ยวกับ Facebook Ads

Andrew Perpetua เป็นผู้เชี่ยวชาญ Facebook Ads เคยทำงานที่ Meta ดูแล Ads Products มีประสบการณ์มากกว่า 10 ปี Performance Marketing แชร์ความรู้ผ่าน Blog และ Social Media

เนื้อหาเกี่ยวข้อง — ทำความเข้าใจ Gain คืออะไร — ทุกสิ่งที่ต้องรู้ในปี 2026

แนวคิดหลักของ Andrew Perpetua คือใช้ Data-driven Approach ทดสอบ Creative อย่างเป็นระบบ ให้ Algorithm ทำงาน ไม่ Over-optimize ด้วยมือ

แนะนำเพิ่มเติม — อ่านเพิ่มเติมที่ SiamCafeBook

เนื้อหาเกี่ยวข้อง — WordPress WooCommerce Shift Left Security —

เนื้อหาเกี่ยวข้อง — บทความที่เกี่ยวข้อง: Python Click CLI Container Orchestration

Campaign Structure และ Setup

# === Facebook Ads Campaign Structure ===

# ใช้ Facebook Marketing API (Python SDK)

# pip install facebook-business



# campaign_structure.py

from dataclasses import dataclass, field

from typing import List, Dict, Optional

from enum import Enum



class CampaignObjective(Enum):

    CONVERSIONS = "OUTCOME_SALES"

    LEADS = "OUTCOME_LEADS"

    TRAFFIC = "OUTCOME_TRAFFIC"

    AWARENESS = "OUTCOME_AWARENESS"

    ENGAGEMENT = "OUTCOME_ENGAGEMENT"



class BidStrategy(Enum):

    LOWEST_COST = "LOWEST_COST_WITHOUT_CAP"

    COST_CAP = "COST_CAP"

    BID_CAP = "BID_CAP"

    ROAS_TARGET = "MINIMUM_ROAS"



@dataclass

class AdCreative:

    name: str

    headline: str

    description: str

    cta: str  # SHOP_NOW, LEARN_MORE, SIGN_UP

    image_url: Optional[str] = None

    video_url: Optional[str] = None

    format: str = "single_image"  # single_image, video, carousel



@dataclass

class AdSetConfig:

    name: str

    targeting: Dict

    budget_daily: float

    optimization_goal: str  # CONVERSIONS, LANDING_PAGE_VIEWS, LINK_CLICKS

    bid_strategy: BidStrategy = BidStrategy.LOWEST_COST

    creatives: List[AdCreative] = field(default_factory=list)



@dataclass

class CampaignConfig:

    name: str

    objective: CampaignObjective

    budget_daily: float

    use_cbo: bool = True  # Campaign Budget Optimization

    ad_sets: List[AdSetConfig] = field(default_factory=list)



class FacebookAdsManager:

    """Facebook Ads Campaign Manager"""



    def __init__(self, account_id, access_token):

        self.account_id = account_id

        self.token = access_token



    def create_campaign(self, config: CampaignConfig):

        """สร้าง Campaign"""

        # Facebook Marketing API call

        # campaign = AdAccount(account_id).create_campaign(params={

        #     'name': config.name,

        #     'objective': config.objective.value,

        #     'special_ad_categories': [],

        #     'campaign_budget_optimization': config.use_cbo,

        #     'daily_budget': int(config.budget_daily * 100),

        #     'bid_strategy': 'LOWEST_COST_WITHOUT_CAP',

        # })

        print(f"Campaign: {config.name}")

        print(f"  Objective: {config.objective.value}")

        print(f"  Budget: /day")

        print(f"  CBO: {config.use_cbo}")

        return config



    def create_targeting(self, countries, age_min=18, age_max=65,

                        genders=None, interests=None, lookalike=None):

        """สร้าง Targeting"""

        targeting = {

            "geo_locations": {"countries": countries},

            "age_min": age_min,

            "age_max": age_max,

        }

        if genders:

            targeting["genders"] = genders

        if interests:

            targeting["flexible_spec"] = [{"interests": interests}]

        if lookalike:

            targeting["custom_audiences"] = [{"id": lookalike}]

        return targeting



# ตัวอย่าง Campaign Structure

manager = FacebookAdsManager("act_123456", "token")



# Broad Targeting Campaign

broad = CampaignConfig(

    name="[CBO] Broad - Conversions",

    objective=CampaignObjective.CONVERSIONS,

    budget_daily=50.0,

    use_cbo=True,

    ad_sets=[

        AdSetConfig(

            name="Broad 25-55 TH",

            targeting={"countries": ["TH"], "age_min": 25, "age_max": 55},

            budget_daily=0,

            optimization_goal="CONVERSIONS",

            creatives=[

                AdCreative("Image Ad 1", "สินค้าลดราคา 50%", "ช้อปเลย", "SHOP_NOW",

                          format="single_image"),

                AdCreative("Video Ad 1", "รีวิวสินค้ายอดนิยม", "ดูเลย", "SHOP_NOW",

                          format="video"),

            ],

        ),

    ],

)



manager.create_campaign(broad)

print(f"  Ad Sets: {len(broad.ad_sets)}")

for adset in broad.ad_sets:

    print(f"    {adset.name}: {len(adset.creatives)} creatives")

Performance Optimization

# ads_optimizer.py — Facebook Ads Performance Optimization

import random

from dataclasses import dataclass

from typing import List, Dict

from datetime import datetime, timedelta



@dataclass

class AdMetrics:

    ad_name: str

    impressions: int

    clicks: int

    conversions: int

    spend: float

    revenue: float



    @property

    def ctr(self):

        return self.clicks / self.impressions * 100 if self.impressions > 0 else 0



    @property

    def cpc(self):

        return self.spend / self.clicks if self.clicks > 0 else 0



    @property

    def cpa(self):

        return self.spend / self.conversions if self.conversions > 0 else 0



    @property

    def roas(self):

        return self.revenue / self.spend if self.spend > 0 else 0



class AdsOptimizer:

    """Facebook Ads Optimization Engine"""



    def __init__(self):

        self.ads: List[AdMetrics] = []

        self.rules: List[Dict] = []



    def add_ad(self, metrics: AdMetrics):

        self.ads.append(metrics)



    def add_rule(self, name, metric, operator, threshold, action):

        self.rules.append({

            "name": name, "metric": metric,

            "operator": operator, "threshold": threshold,

            "action": action,

        })



    def evaluate_rules(self):

        """ประเมิน Optimization Rules"""

        print(f"\n{'='*55}")

        print(f"Ads Optimization Report")

        print(f"{'='*55}")



        actions = []

        for ad in self.ads:

            for rule in self.rules:

                value = getattr(ad, rule["metric"], None)

                if value is None:

                    continue



                triggered = False

                if rule["operator"] == ">" and value > rule["threshold"]:

                    triggered = True

                elif rule["operator"] == "<" and value < rule["threshold"]:

                    triggered = True



                if triggered:

                    actions.append({

                        "ad": ad.ad_name,

                        "rule": rule["name"],

                        "value": value,

                        "action": rule["action"],

                    })



        if actions:

            print(f"\n  Actions ({len(actions)}):")

            for a in actions:

                print(f"    {a['ad']}: {a['rule']} "

                      f"(value={a['value']:.2f}) -> {a['action']}")

        else:

            print(f"\n  No actions needed")



    def performance_report(self):

        """Performance Report"""

        print(f"\n  Ad Performance:")

        total_spend = sum(a.spend for a in self.ads)

        total_revenue = sum(a.revenue for a in self.ads)



        for ad in sorted(self.ads, key=lambda a: a.roas, reverse=True):

            print(f"    {ad.ad_name:<25} "

                  f"ROAS:{ad.roas:.1f}x "

                  f"CPA: "

                  f"CTR:{ad.ctr:.1f}% "

                  f"Conv:{ad.conversions}")



        print(f"\n  Total: Spend= "

              f"Revenue= "

              f"ROAS={total_revenue/total_spend:.1f}x" if total_spend > 0 else "")



# ตัวอย่าง

optimizer = AdsOptimizer()



ads = [

    AdMetrics("Image Ad - Product A", 50000, 1200, 45, 300, 2700),

    AdMetrics("Video Ad - Review", 80000, 2400, 72, 500, 5400),

    AdMetrics("Carousel - Collection", 30000, 600, 15, 200, 900),

    AdMetrics("UGC Video - Testimonial", 60000, 1800, 90, 400, 6300),

    AdMetrics("Static - Discount 50%", 40000, 800, 8, 250, 400),

]



for ad in ads:

    optimizer.add_ad(ad)



# Optimization Rules

optimizer.add_rule("High CPA", "cpa", ">", 20, "Pause or reduce budget")

optimizer.add_rule("Low ROAS", "roas", "<", 2.0, "Review creative/targeting")

optimizer.add_rule("Low CTR", "ctr", "<", 1.0, "Refresh creative")



optimizer.performance_report()

optimizer.evaluate_rules()

Creative Testing Framework

# creative_testing.py — A/B Testing Framework สำหรับ Ad Creatives

from dataclasses import dataclass

from typing import List

import random

import math



@dataclass

class CreativeVariant:

    name: str

    format: str  # image, video, carousel

    hook: str

    impressions: int = 0

    conversions: int = 0

    spend: float = 0



    @property

    def cvr(self):

        return self.conversions / self.impressions if self.impressions > 0 else 0



class CreativeTestingFramework:

    """Creative Testing Framework ตามแนวคิด Andrew Perpetua"""



    def __init__(self):

        self.variants: List[CreativeVariant] = []

        self.min_impressions = 1000  # Minimum สำหรับ Statistical Significance



    def add_variant(self, variant: CreativeVariant):

        self.variants.append(variant)



    def is_significant(self, v1: CreativeVariant, v2: CreativeVariant):

        """ตรวจสอบ Statistical Significance"""

        if v1.impressions < self.min_impressions or v2.impressions < self.min_impressions:

            return False, "Need more data"



        p1 = v1.cvr

        p2 = v2.cvr

        n1 = v1.impressions

        n2 = v2.impressions



        if p1 == 0 and p2 == 0:

            return False, "No conversions"



        p_pool = (v1.conversions + v2.conversions) / (n1 + n2)

        if p_pool == 0 or p_pool == 1:

            return False, "Cannot calculate"



        se = math.sqrt(p_pool * (1 - p_pool) * (1/n1 + 1/n2))

        if se == 0:

            return False, "SE is zero"



        z = abs(p1 - p2) / se

        return z > 1.96, f"z={z:.2f} (need >1.96)"



    def testing_report(self):

        """Creative Testing Report"""

        print(f"\n{'='*55}")

        print(f"Creative Testing Report")

        print(f"{'='*55}")



        # Sort by CVR

        sorted_variants = sorted(self.variants, key=lambda v: v.cvr, reverse=True)



        winner = sorted_variants[0] if sorted_variants else None



        for v in sorted_variants:

            is_winner = " *WINNER*" if v == winner else ""

            print(f"  {v.name:<30} "

                  f"CVR:{v.cvr*100:.2f}% "

                  f"Conv:{v.conversions} "

                  f"Imp:{v.impressions:,}{is_winner}")



        # Statistical Significance

        if len(sorted_variants) >= 2:

            sig, msg = self.is_significant(sorted_variants[0], sorted_variants[1])

            print(f"\n  Significance: {'YES' if sig else 'NO'} ({msg})")



        # Recommendations

        print(f"\n  Testing Framework (Andrew Perpetua):")

        print(f"    1. ทดสอบ 3-5 Creatives ต่อ Ad Set")

        print(f"    2. รอ 1,000+ Impressions ก่อนตัดสินใจ")

        print(f"    3. ดู CVR ไม่ใช่แค่ CTR")

        print(f"    4. Winner takes all — Scale winner, kill losers")

        print(f"    5. ทดสอบ Creative ใหม่ทุก 2 สัปดาห์")



# ตัวอย่าง

framework = CreativeTestingFramework()



variants = [

    CreativeVariant("UGC Video - Unboxing", "video", "ลองเปิดกล่อง!", 15000, 120, 300),

    CreativeVariant("Studio Photo - Product", "image", "สินค้าขายดี", 12000, 72, 240),

    CreativeVariant("Carousel - Features", "carousel", "5 เหตุผลที่ต้องมี", 10000, 50, 200),

    CreativeVariant("Meme Style - Humor", "image", "เมื่อเพื่อนเห็นของ", 8000, 40, 160),

    CreativeVariant("Before/After", "image", "ก่อน vs หลัง", 11000, 88, 220),

]



for v in variants:

    framework.add_variant(v)



framework.testing_report()

เคล็ดลับจาก Andrew Perpetua

Andrew Perpetua — เรียนรู้เกี่ยวกับ Facebook Ads
  • Broad Targeting: ให้ Algorithm หา Audience เอง อย่า Narrow มากเกินไป
  • CBO: ใช้ Campaign Budget Optimization ให้ Facebook จัดสรร Budget อัตโนมัติ
  • Creative First: Creative สำคัญที่สุด ทดสอบหลาย Format (Video, Image, UGC)
  • ROAS Focus: วัดผลด้วย ROAS ไม่ใช่แค่ CTR หรือ CPC
  • Scale Gradually: เพิ่ม Budget 20% ต่อสัปดาห์ อย่าเพิ่มทีเดียวมาก
  • Advantage+: ใช้ Advantage+ Shopping Campaigns สำหรับ E-commerce

Andrew Perpetua คือใคร

ผู้เชี่ยวชาญ Facebook Ads Digital Marketing เคยทำงานที่ Meta Product Marketing Manager ดูแล Ads Products ประสบการณ์ 10+ ปี Performance Marketing แชร์ความรู้ Blog Social Media

แนะนำเพิ่มเติม — คอร์สเทรด Forex ที่ iCafeForex

เนื้อหาเกี่ยวข้อง — PagerDuty Incident Machine Learning Pipeline

XM Legend · เทรดเดอร์ & ผู้สอน Forex 13 ปี

ผู้ก่อตั้ง SiamCafe ตั้งแต่ปี 1997 · เทรดเดอร์สาย Forex มากกว่า 13 ปี ได้รับการยกย่องเป็น XM Legend · แบ่งปันความรู้ Forex, ไอที, AI และการเทรด จากประสบการณ์จริงในตลาดจริง