Rumah > hujung hadapan web > tutorial js > AWS JavaScript WordPress = Strategi Automasi Kandungan Seronok Menggunakan Kepintaran Buatan

AWS JavaScript WordPress = Strategi Automasi Kandungan Seronok Menggunakan Kepintaran Buatan

Susan Sarandon
Lepaskan: 2025-01-05 20:40:47
asal
736 orang telah melayarinya

Sebulan yang lalu, saya mula bekerjasama dalam projek tentang kandungan yang dijana AI untuk pelanggan yang memfokuskan pada sektor teknologi. Peranan saya kebanyakannya tertumpu pada menyediakan SSG menggunakan WordPress sebagai CMS Tanpa Kepala untuk Nuxt Front-end.

Pelanggan pernah menulis artikel beberapa kali seminggu tentang aliran atau situasi berbeza yang mempengaruhi sektor tersebut, dengan harapan dapat meningkatkan trafik ke tapak dan pengeluaran artikelnya, dia memutuskan untuk menggunakan AI untuk menjana artikel untuknya.

Selepas beberapa lama, dengan gesaan yang betul, pelanggan mempunyai cebisan maklumat yang hampir dengan padanan tepat artikel tulisan manusia, adalah sangat sukar untuk mengesan bahawa ia adalah buatan mesin.

Ada kalanya selepas saya beralih menggunakan ciri yang berbeza, saya akan terus ditanya satu perkara khusus.

Eh, bolehkah anda mengemas kini imej yang ditampilkan untuk artikel ini?

Selepas 2 minggu mengemas kini Siaran setiap hari, saya mengalami detik eureka yang kecil.

AWS   JavaScript   WordPress = Fun Content Automation Strategies Using Artificial Intelligence

Mengapa saya tidak mengautomasikan penjanaan imej yang ditampilkan untuk artikel ini menggunakan Kecerdasan Buatan?

Kami sudah mengautomasikan penulisan siaran, mengapa tidak mengautomasikan imej yang ditampilkan?

Pada masa lapang saya, saya sedang bereksperimen dengan LLM generatif pada komputer saya jadi saya mempunyai idea yang kukuh tentang lebih kurang cara menangani usaha sampingan ini. Saya menghantar mesej kepada pelanggan yang memperincikan masalahnya, apa yang saya mahu lakukan dan apa yang akan menjadi kelebihan dan tanpa perlu meyakinkan, saya mendapat lampu hijau untuk mengusahakan ciri ini dan segera saya pergi dengan langkah pertama saya.

1. Seni bina bagaimana penyelesaian akan kelihatan.

Memandangkan saya mempunyai sedikit pendedahan untuk menjalankan model secara tempatan, saya tahu dengan serta-merta adalah tidak mungkin untuk mengehoskan sendiri model tersebut. Dengan dibuang itu saya mula bermain-main dengan API yang menghasilkan imej berdasarkan gesaan teks.

Imej yang ditampilkan terdiri daripada 2 bahagian: grafik terdiri utama dan slogan yang menarik.

Grafik yang digubah ialah beberapa elemen yang berkaitan dengan artikel, disusun dengan cara yang baik dengan kemudian beberapa warna dan tekstur dengan beberapa mod campuran digunakan untuk mencapai beberapa kesan mewah berikutan penjenamaan.

Tagline pendek, 8-12 patah perkataan ayat dengan bayang-bayang yang ringkas di bawahnya.

Berdasarkan ujian saya, saya menyedari bahawa mengikuti laluan AI untuk penjanaan imej tidak praktikal. Kualiti imej tidak memenuhi jangkaan, dan proses itu terlalu memakan masa untuk membenarkan penggunaannya. Memandangkan ini akan dijalankan sebagai fungsi AWS Lambda, di mana masa pelaksanaan secara langsung memberi kesan kepada kos.

Dengan itu dibuang, saya menggunakan Pelan B: menumbuk imej dan aset reka bentuk bersama-sama menggunakan API Kanvas JavaScript.

Melihat secara mendalam, kami mempunyai terutamanya 5 gaya siaran ringkas, dan sekitar 4 jenis tekstur dan 3 daripadanya menggunakan penjajaran, gaya dan kedudukan teks yang sama. Selepas membuat beberapa matematik saya fikir:

Hmm, Jika saya mengambil 3 imej ini, ambil 8 tekstur dan bermain dengan mod campuran, saya boleh mendapatkan sekitar post 24 variasi

Memandangkan 3 jenis siaran tersebut mempunyai gaya teks yang sama, ia boleh dikatakan satu templat.

Dengan penyelesaian itu, saya berpindah ke Penjana Tagline. Saya ingin mencipta slogan berdasarkan kandungan dan tajuk artikel. Saya memutuskan untuk menggunakan API ChatGPT memandangkan syarikat sudah membayar untuknya dan selepas beberapa percubaan dan pengubahsuaian gesaan, saya mempunyai MVP yang sangat baik untuk penjana slogan saya.

Dengan 2 bahagian tugasan yang paling sukar diselesaikan, saya meluangkan sedikit masa di Figma menyusun rajah untuk seni bina akhir perkhidmatan saya.

AWS   JavaScript   WordPress = Fun Content Automation Strategies Using Artificial Intelligence

2. Mengekodkan lambda saya

Rancangannya adalah untuk mencipta fungsi Lambda yang mampu menganalisis kandungan siaran, menjana slogan dan memasang imej yang ditampilkan—semuanya disepadukan dengan lancar dengan WordPress.

Saya akan memberikan beberapa kod tetapi cukup untuk menyampaikan idea keseluruhan kepada ke.

Menganalisis kandungan

Fungsi Lambda bermula dengan mengekstrak parameter yang diperlukan daripada muatan acara masuk:

const { title: request_title, content, backend, app_password} = JSON.parse(event.body);

  • tajuk dan kandungan: Ini menyediakan konteks artikel.
  • belakang: URL belakang WordPress untuk muat naik imej.
  • app_password: Token pengesahan yang akan saya gunakan untuk memuat naik sebagai pengguna saya menggunakan Wordpress Rest API.

Menjana Tagline

Tugas utama pertama fungsi ini ialah menjana slogan menggunakan fungsi analyzeContent, yang menggunakan API OpenAI untuk mencipta slogan yang layak klik berdasarkan tajuk dan kandungan artikel.

Fungsi kami mengambil tajuk dan kandungan siaran tetapi mengembalikan slogan, sentimen siaran untuk mengetahui sama ada siaran adalah pendapat yang positif, negatif atau neutral dan simbol syarikat pilihan daripada syarikat indeks S&P.

const { slogan, sentimen, syarikat } = menunggu analisisKandungan({ tajuk: request_title, kandungan });

Langkah ini adalah kritikal, kerana slogan secara langsung mempengaruhi estetika imej.

Mencipta Imej Pilihan

Seterusnya, fungsi generateImage bermula:

let buffer;

buffer = await generateImage({
    title: tagline,
    company_logo: company_logo,
    sentiment: sentiment,
});

Salin selepas log masuk
Salin selepas log masuk

Fungsi ini mengendalikan:

  • Mereka bentuk gubahan.
  • Melapisi tekstur, warna dan elemen penjenamaan.
  • Menggunakan kesan dan mencipta tajuk.

Berikut ialah pecahan langkah demi langkah tentang cara ia berfungsi:

Fungsi generateImage bermula dengan menyediakan kanvas kosong, menentukan dimensinya dan menyediakannya untuk mengendalikan semua elemen reka bentuk.

let buffer;

buffer = await generateImage({
    title: tagline,
    company_logo: company_logo,
    sentiment: sentiment,
});

Salin selepas log masuk
Salin selepas log masuk

Dari situ, imej latar belakang rawak dimuatkan daripada koleksi aset yang telah ditetapkan. Imej ini disusun mengikut penjenamaan berorientasikan teknologi sambil membenarkan kepelbagaian yang mencukupi merentas siaran. Imej latar belakang dipilih secara rawak berdasarkan sentimennya.

Untuk memastikan setiap imej latar belakang kelihatan hebat, saya mengira dimensinya secara dinamik berdasarkan nisbah bidang. Ini mengelakkan herotan sambil mengekalkan keseimbangan visual.

Menambah Tagline

Slogan itu pendek tetapi berdasarkan beberapa peraturan, ayat yang memberi impak ini dibahagikan kepada bahagian yang boleh diurus dan digayakan secara dinamik untuk memastikan ia sentiasa boleh dibaca, tanpa mengira panjang atau saiz kanvas berdasarkan bilangan perkataan untuk baris, panjang perkataan, dsb. .

const COLOURS = {
        BLUE: "#33b8e1",
        BLACK: "#000000",
    }

    const __filename = fileURLToPath(import.meta.url);
    const __dirname = path.dirname(__filename);
    const images_path = path.join(__dirname, 'images/');
    const files_length = fs.readdirSync(images_path).length;
    const images_folder = process.env.ENVIRONMENT === "local"
        ? "./images/" : "/var/task/images/";


    registerFont("/var/task/fonts/open-sans.bold.ttf", { family: "OpenSansBold" });
    registerFont("/var/task/fonts/open-sans.regular.ttf", { family: "OpenSans" });


    console.log("1. Created canvas");

    const canvas = createCanvas(1118, 806);

    let image = await loadImage(`${images_folder}/${Math.floor(Math.random() * (files_length - 1 + 1)) + 1}.jpg`);


    let textBlockHeight = 0;

    console.log("2. Image loaded");

    const canvasWidth = canvas.width;
    const canvasHeight = canvas.height;
    const aspectRatio = image.width / image.height;


    console.log("3. Defined ASPECT RATIO",)

    let drawWidth, drawHeight;
    if (image.width > image.height) {
        // Landscape orientation: fit by width
        drawWidth = canvasWidth;
        drawHeight = canvasWidth / aspectRatio;
    } else {
        // Portrait orientation: fit by height
        drawHeight = canvasHeight;
        drawWidth = canvasHeight * aspectRatio;
    }

    // Center the image
    const x = (canvasWidth - drawWidth) / 2;
    const y = (canvasHeight - drawHeight) / 2;
    const ctx = canvas.getContext("2d");
    console.log("4. Centered Image")
    ctx.drawImage(image, x, y, drawWidth, drawHeight);

Salin selepas log masuk

Akhir sekali, kanvas ditukar menjadi penimbal PNG.

console.log("4.1 Text splitting");
if (splitText.length === 1) {

    const isItWiderThanHalf = ctx.measureText(splitText[0]).width > ((canvasWidth / 2) + 160);
    const wordCount = splitText[0].split(" ").length;

    if (isItWiderThanHalf && wordCount > 4) {

        const refactored_line = splitText[0].split(" ").reduce((acc, curr, i) => {
            if (i % 3 === 0) {
                acc.push([curr]);
            } else {
                acc[acc.length - 1].push(curr);
            }
            return acc;
        }, []).map((item) => item.join(" "));

        refactored_line[1] = "[s]" + refactored_line[1] + "[s]";

        splitText = refactored_line

    }
}

let tagline = splitText.filter(item => item !== '' && item !== '[br]' && item !== '[s]' && item !== '[/s]' && item !== '[s]');
let headlineSentences = [];
let lineCounter = {
    total: 0,
    reduced_line_counter: 0,
    reduced_lines_indexes: []
}

console.log("4.2 Tagline Preparation", tagline);

for (let i = 0; i < tagline.length; i++) {
    let line = tagline[i];

    if (line.includes("[s]") || line.includes("[/s]")) {

        const finalLine = line.split(/(\[s\]|\[\/s\])/).filter(item => item !== '' && item !== '[s]' && item !== '[/s]');

        const lineWidth = ctx.measureText(finalLine[0]).width
        const halfOfWidth = canvasWidth / 2;

        if (lineWidth > halfOfWidth && finalLine[0]) {

            let splitted_text = finalLine[0].split(" ").reduce((acc, curr, i) => {

                const modulus = finalLine[0].split(" ").length >= 5 ? 3 : 2;
                if (i % modulus === 0) {
                    acc.push([curr]);
                } else {
                    acc[acc.length - 1].push(curr);
                }
                return acc;
            }, []);

            let splitted_text_arr = []

            splitted_text.forEach((item, _) => {
                let lineText = item.join(" ");

                item = lineText

                splitted_text_arr.push(item)
            })

            headlineSentences[i] = splitted_text_arr[0] + '/s/'

            if (splitted_text_arr[1]) {
                headlineSentences.splice(i + 1, 0, splitted_text_arr[1] + '/s/')
            }
        } else {
            headlineSentences.push("/s/" + finalLine[0] + "/s/")
        }


    } else {
        headlineSentences.push(line)
    }
}

console.log("5. Drawing text on canvas", headlineSentences);

const headlineSentencesLength = headlineSentences.length;
let textHeightAccumulator = 0;

for (let i = 0; i < headlineSentencesLength; i++) {
    headlineSentences = headlineSentences.filter(item => item !== '/s/');
    const nextLine = headlineSentences[i + 1];
    if (nextLine && /^\s*$/.test(nextLine)) {
        headlineSentences.splice(i + 1, 1);
    }

    let line = headlineSentences[i];

    if (!line) continue;
    let lineText = line.trim();

    let textY;

    ctx.font = " 72px OpenSans";

    const cleanedUpLine = lineText.includes('/s/') ? lineText.replace(/\s+/g, ' ') : lineText;
    const lineWidth = ctx.measureText(cleanedUpLine).width
    const halfOfWidth = canvasWidth / 2;

    lineCounter.total += 1

    const isLineTooLong = lineWidth > (halfOfWidth + 50);

    if (isLineTooLong) {

        if (lineText.includes(':')) {
            const split_line_arr = lineText.split(":")
            if (split_line_arr.length > 1) {
                lineText = split_line_arr[0] + ":";
                if (split_line_arr[1]) {
                    headlineSentences.splice(i + 1, 0, split_line_arr[1])
                }
            }
        }

        ctx.font = "52px OpenSans";

        lineCounter.reduced_line_counter += 1

        if (i === 0 && headlineSentencesLength === 2) {
            is2LinesAndPreviewsWasReduced = true
        }


        lineCounter.reduced_lines_indexes.push(i)

    } else {

        if (i === 0 && headlineSentencesLength === 2) {
            is2LinesAndPreviewsWasReduced = false
        }


    }

    if (lineText.includes("/s/")) {

        lineText = lineText.replace(/\/s\//g, "");

        if (headlineSentencesLength > (i + 1) && i < headlineSentencesLength - 1 && nextLine) {

            if (nextLine.slice(0, 2).includes("?") && nextLine.length < 3) {
                lineText += '?';
                headlineSentences.pop();
            }

            if (nextLine.slice(0, 2).includes(":")) {
                lineText += ':';
                headlineSentences[i + 1] = headlineSentences[i + 1].slice(2);
            }

        }

        let lineWidth = ctx.measureText(lineText).width


        let assignedSize;


        if (lineText.split(" ").length <= 2) {

            if (lineWidth > (canvasWidth / 2.35)) {

                ctx.font = "84px OpenSansBold";

                assignedSize = 80

            } else {

                ctx.font = "84px OpenSansBold";

                assignedSize = 84

            }
        } else {


            if (i === headlineSentencesLength - 1 && lineWidth < (canvasWidth / 2.5) && lineText.split(" ").length === 3) {

                ctx.font = "84px OpenSansBold";
                assignedSize = 84

            } else {

                lineCounter.reduced_line_counter += 1;

                ctx.font = "52px OpenSansBold";
                assignedSize = 52

            }

            lineCounter.reduced_lines_indexes.push(i)

        }

        lineWidth = ctx.measureText(lineText).width



        if (lineWidth > (canvasWidth / 2) + 120) {

            if (assignedSize === 84) {
                ctx.font = "72px OpenSansBold";
            } else if (assignedSize === 80) {
                ctx.font = "64px OpenSansBold";

                textHeightAccumulator += 8
            } else {
                ctx.font = "52px OpenSansBold";
            }
        }



    } else {

        const textWidth = ctx.measureText(lineText).width


        if (textWidth > (canvasWidth / 2)) {
            ctx.font = "44px OpenSans";
            textHeightAccumulator += 12
        } else if (i === headlineSentencesLength - 1) {
            textHeightAccumulator += 12
        }

    }

    ctx.fillStyle = "white";
    ctx.textAlign = "center";

    const textHeight = ctx.measureText(lineText).emHeightAscent;

    textHeightAccumulator += textHeight;

    if (headlineSentencesLength == 3) {
        textY = (canvasHeight / 3)
    } else if (headlineSentencesLength == 4) {
        textY = (canvasHeight / 3.5)
    } else {
        textY = 300
    }

    textY += textHeightAccumulator;

    const words = lineText.split(' ');
    console.log("words", words, lineText, headlineSentences)
    const capitalizedWords = words.map(word => {
        if (word.length > 0) return word[0].toUpperCase() + word.slice(1)
        return word
    });
    const capitalizedLineText = capitalizedWords.join(' ');

    ctx.fillText(capitalizedLineText, canvasWidth / 2, textY);

}

Salin selepas log masuk

Akhirnya!!! Memuat naik Imej ke WordPress

Selepas berjaya menjana penimbal imej, fungsi uploadImageToWordpress dipanggil.

Fungsi ini mengendalikan beban berat menghantar imej ke WordPress menggunakan API REST dengan Mengekodkan Imej untuk WordPress.

Fungsi ini menyediakan slogan terlebih dahulu untuk digunakan sebagai nama fail dengan membersihkan ruang dan aksara khas:

const buffer = canvas.toBuffer("image/png");
return buffer;
Salin selepas log masuk

Penimbal imej kemudiannya ditukar menjadi objek Blob untuk menjadikannya serasi dengan API WordPress:

fail const = new Blob([buffer], { type: "image/png" });

Menyediakan Permintaan API Menggunakan imej dan slogan yang dikodkan, fungsi membina objek FormData dan saya menambah metadata pilihan, seperti alt_text untuk kebolehaksesan dan kapsyen untuk konteks.

const createSlug = (string) => {
    return string.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
};

const image_name = createSlug(tagline);
Salin selepas log masuk

Untuk pengesahan, nama pengguna dan kata laluan aplikasi dikodkan dalam Base64 dan disertakan dalam pengepala permintaan:

formData.append("file", file, image_name + ".png");
formData.append("alt_text", `${tagline} image`);
formData.append("caption", "Uploaded via API");
Salin selepas log masuk

Menghantar Imej Permintaan POST dibuat ke titik akhir media WordPress dengan data dan pengepala yang disediakan dan selepas menunggu balasan, saya mengesahkan kejayaan atau kesilapan.

const credentials = `${username}:${app_password}`;
const base64Encoded = Buffer.from(credentials).toString("base64");

Salin selepas log masuk

Jika berjaya, saya mengembalikan respons media yang sama dalam lambda.

Beginilah rupa lambda saya pada akhirnya.

const response = await fetch(`${wordpress_url}wp-json/wp/v2/media`, {
    method: "POST",
    headers: {
        Authorization: "Basic " + base64Encoded,
        contentType: "multipart/form-data",
    },
    body: formData,
});

if (!response.ok) {
    const errorText = await response.text();
    throw new Error(`Error uploading image: ${response.statusText}, Details: ${errorText}`);
}

Salin selepas log masuk

Ini adalah contoh imej yang dihasilkan oleh skrip saya. Ia tidak digunakan dalam pengeluaran, hanya dibuat dengan aset generik untuk contoh ini.

AWS   JavaScript   WordPress = Fun Content Automation Strategies Using Artificial Intelligence

Kesudahannya

Suatu masa telah berlalu dan semua orang gembira kerana kita tidak lagi mempunyai artikel yang tidak bergambar atau kelihatan kosong, bahawa imej adalah padanan yang rapat dengan yang dihasilkan oleh pereka, pereka gembira kerana dia hanya memberi tumpuan kepada mereka bentuk untuk usaha pemasaran lain di seluruh syarikat.

Tetapi masalah baru timbul: kadangkala pelanggan tidak menyukai Imej yang dihasilkan dan dia akan meminta saya memutarkan skrip saya untuk menjana yang baharu untuk siaran tertentu.

Ini membawa saya ke sidequest saya yang seterusnya: Pemalam Wordpress untuk Menjana Imej Pilihan Secara Manual menggunakan Kepintaran Buatan untuk Siaran Khusus

Atas ialah kandungan terperinci AWS JavaScript WordPress = Strategi Automasi Kandungan Seronok Menggunakan Kepintaran Buatan. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan