File size: 2,804 Bytes
1501522
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
<?php

namespace App\Services;

use Illuminate\Support\Str;

class SocialContentGeneratorService
{
    public function __construct(private OpenAiChatService $openAiChatService)
    {
    }

    public function generate(string $topic, string $platformHint = 'multi-platform', string $tone = 'friendly-professional'): array
    {
        $messages = [
            [
                'role' => 'system',
                'content' => 'Kamu adalah social media strategist. Selalu jawab valid JSON tanpa markdown dengan schema: {"title":"...","caption":"...","hashtags":["..."],"cta":"..."}. Gunakan Bahasa Indonesia.',
            ],
            [
                'role' => 'user',
                'content' => "Buat konten untuk {$platformHint}. Tone: {$tone}. Topik: {$topic}. Caption maksimal 480 karakter. Hashtag 6-10 item relevan tanpa spasi.",
            ],
        ];

        $raw = $this->openAiChatService->reply($messages);
        $clean = trim($raw);

        if (str_starts_with($clean, '```')) {
            $clean = preg_replace('/^```(?:json)?\s*|\s*```$/m', '', $clean) ?? $clean;
            $clean = trim($clean);
        }

        $decoded = json_decode($clean, true);
        if (! is_array($decoded)) {
            $decoded = json_decode($this->extractJsonObject($clean) ?? '', true);
        }

        if (! is_array($decoded)) {
            return [
                'title' => Str::limit($topic, 80),
                'caption' => Str::limit($raw !== '' ? $raw : $topic, 500),
                'hashtags' => ['#konten', '#bisnis', '#digitalmarketing'],
                'cta' => 'Follow untuk konten berikutnya.',
                'raw' => $raw,
            ];
        }

        $hashtags = collect($decoded['hashtags'] ?? [])
            ->map(fn ($item) => trim((string) $item))
            ->filter()
            ->take(10)
            ->map(fn ($item) => str_starts_with($item, '#') ? $item : '#'.$item)
            ->unique()
            ->values()
            ->all();

        $caption = trim((string) ($decoded['caption'] ?? ''));
        if ($caption === '') {
            $caption = Str::limit($raw !== '' ? $raw : $topic, 500);
        }

        return [
            'title' => trim((string) ($decoded['title'] ?? Str::limit($topic, 80))),
            'caption' => $caption,
            'hashtags' => $hashtags,
            'cta' => trim((string) ($decoded['cta'] ?? 'Follow untuk konten berikutnya.')),
            'raw' => $raw,
        ];
    }

    private function extractJsonObject(string $content): ?string
    {
        $start = strpos($content, '{');
        $end = strrpos($content, '}');

        if ($start === false || $end === false || $end <= $start) {
            return null;
        }

        return substr($content, $start, $end - $start + 1);
    }
}