1import { Actor } from 'apify';
2import { v4 as uuidv4 } from 'uuid';
3
4
5class AITool {
6 constructor() {
7 this.promptTemplate = `
8#CONTEXT:
9You are an expert marketing strategist and wordsmith tasked with helping businesses differentiate themselves in their market by crafting powerful, memorable taglines that highlight their unique selling propositions (USPs). Your goal is to generate taglines for various businesses, analyze their strengths and weaknesses, and provide impact and memorability scores for each.
10
11#ROLE:
12As a master marketing strategist and wordsmith, your role is to leverage your expertise in crafting strategic, impactful language to create taglines that effectively position businesses in their respective markets. You should approach each business with a keen understanding of their target audience, key USPs, and the emotional triggers that will resonate with their customers.
13
14#RESPONSE GUIDELINES:
15Your response should be organized in a table format with the following columns:
16- Business Name
17- Target Audience
18- Key USP
19- Emotional Trigger
20- Proposed Tagline
21- Impact Score (1-10)
22- Memorability Score (1-10)
23
24For each proposed tagline, provide a brief analysis of its strengths and weaknesses using the following format:
25✅ tagline_strength
26❌ tagline_weakness
27
28Focus on creating taglines that are concise, memorable, and effectively communicate each business's unique value proposition. Use your understanding of the target audience and emotional triggers to craft language that will resonate with potential customers.
29
30#TAGLINE CRITERIA:
311. Taglines should be short, punchy, and memorable. Aim for no more than 8 words.
322. Focus on highlighting the key USP and emotional trigger for each business.
333. Use language that will resonate with the target audience.
344. Avoid generic or cliched phrases that could apply to any business.
355. Ensure each tagline is distinct and effectively differentiates the business from its competitors.
36
37#INFORMATION ABOUT ME:
38- Businesses to generate taglines for: [LIST BUSINESSES]
39
40#RESPONSE FORMAT:
41| Business Name | Target Audience | Key USP | Emotional Trigger | Proposed Tagline | Impact Score (1-10) | Memorability Score (1-10) |
42|---------------|-----------------|---------|------------------|------------------|---------------------|---------------------------|
43| name | audience | usp | trigger | tagline | impact_score | memorability_score |
44
45✅ tagline_strength
46❌ tagline_weakness
47 `;
48
49 }
50
51 async run(input) {
52
53 const {
54 yourBusiness,
55 } = input;
56
57
58 const prompt = this.promptTemplate
59 .replace('[LIST BUSINESSES]', yourBusiness);
60
61 const url = 'https://openrouter.ai/api/v1/chat/completions';
62 const options = {
63 method: 'POST',
64 headers: { Authorization: 'Bearer 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', 'Content-Type': 'application/json' },
65 body: JSON.stringify({
66 model: "deepseek/deepseek-r1:free",
67 messages: [
68 {
69 role: "user",
70 content: prompt
71 }
72 ]
73 })
74 };
75
76 try {
77 console.log('start processing...');
78 const response = await fetch(url, options);
79 const data = await response.json();
80 const content = data.choices[0].message.content;
81
82 if (!content) {
83 throw new Error('No content returned from the API, Please try again.');
84 }
85
86
87 const timestamp = generateTimestamp();
88 const baseFilename = `tagline-${timestamp}`;
89
90
91 const fileUrls = {};
92
93
94 const markdownBuffer = Buffer.from(content, 'utf-8');
95 const markdownKey = await Actor.setValue(
96 `${baseFilename}.md`,
97 markdownBuffer,
98 { contentType: 'text/markdown' }
99 );
100 fileUrls.markdown = `https://api.apify.com/v2/key-value-stores/${Actor.getEnv().defaultKeyValueStoreId}/records/${baseFilename}.md`;
101
102
103 const marked = await import('marked');
104 const htmlContent = `
105 <!DOCTYPE html>
106 <html>
107 <head>
108 <meta charset="UTF-8">
109 <title>Analysis Report</title>
110 <style>
111 body { font-family: Arial, sans-serif; margin: 40px; }
112 table { border-collapse: collapse; width: 100%; }
113 th, td { border: 1px solid #ddd; padding: 8px; }
114 th { background-color: #f2f2f2; }
115 </style>
116 </head>
117 <body>
118 ${marked.parse(content)}
119 </body>
120 </html>
121 `;
122 const htmlBuffer = Buffer.from(htmlContent, 'utf-8');
123 const htmlKey = await Actor.setValue(
124 `${baseFilename}.html`,
125 htmlBuffer,
126 { contentType: 'text/html' }
127 );
128 fileUrls.html = `https://api.apify.com/v2/key-value-stores/${Actor.getEnv().defaultKeyValueStoreId}/records/${baseFilename}.html`;
129
130
131 const puppeteer = await import('puppeteer');
132 const browser = await puppeteer.launch({
133 args: [
134 '--no-sandbox',
135 '--disable-setuid-sandbox',
136 '--disable-dev-shm-usage',
137 '--disable-gpu'
138 ],
139 headless: true
140 });
141 const page = await browser.newPage();
142 await page.setContent(htmlContent);
143 const pdfBuffer = await page.pdf({
144 format: 'A4',
145 margin: { top: '2cm', right: '2cm', bottom: '2cm', left: '2cm' }
146 });
147 await browser.close();
148
149 const pdfKey = await Actor.setValue(
150 `${baseFilename}.pdf`,
151 pdfBuffer,
152 { contentType: 'application/pdf' }
153 );
154 fileUrls.pdf = `https://api.apify.com/v2/key-value-stores/${Actor.getEnv().defaultKeyValueStoreId}/records/${baseFilename}.pdf`;
155
156
157 let chargeResult = await charge();
158
159
160
161
162 if (chargeResult.success) {
163
164 await Actor.pushData({
165 input: {
166 yourBusiness
167 },
168 htmlFile: fileUrls.html,
169 pdfFile: fileUrls.pdf,
170 markdownFile: fileUrls.markdown
171 });
172 console.log('Process completed successfully.');
173 } else {
174 console.log('Charge failed.');
175 }
176
177 } catch (error) {
178 console.error(error);
179 }
180 }
181
182}
183
184
185
186
187function generateTimestamp() {
188 const now = new Date();
189 const year = now.getFullYear();
190 const month = String(now.getMonth() + 1).padStart(2, '0');
191 const day = String(now.getDate()).padStart(2, '0');
192 const hours = String(now.getHours()).padStart(2, '0');
193 const minutes = String(now.getMinutes()).padStart(2, '0');
194 const seconds = String(now.getSeconds()).padStart(2, '0');
195 const timestamp = `${year}-${month}-${day}-${hours}-${minutes}-${seconds}`;
196 return timestamp;
197}
198
199
200
201
202
203async function charge() {
204
205 let runId = Actor.getEnv().actorRunId;
206 let token = Actor.getEnv().token;
207 const myHeaders = new Headers();
208 myHeaders.append("Content-Type", "application/json");
209 myHeaders.append("Authorization", `Bearer ${token}`);
210 myHeaders.append("idempotency-key", uuidv4());
211
212 const raw = JSON.stringify({
213 "eventName": "per-result",
214 "eventCount": 1,
215 "count": 1
216 });
217
218 const requestOptions = {
219 method: "POST",
220 headers: myHeaders,
221 body: raw,
222 redirect: "follow"
223 };
224
225 try {
226 const response = await fetch(`https://api.apify.com/v2/actor-runs/${runId}/charge`, requestOptions);
227 const result = await response.json();
228 if (result?.error?.message) {
229 if (result?.error?.type !== 'cannot-charge-non-pay-per-event-actor' && result?.error?.type !== 'user-or-token-not-found') {
230 console.log(result?.error);
231 return { success: false };
232 } else {
233 return { success: true };
234 }
235 } else {
236 return { success: true };
237 }
238 } catch (error) {
239 console.error(error);
240 return { success: false };
241 }
242}
243
244
245await Actor.init();
246
247Actor.main(async () => {
248 const input = await Actor.getInput();
249
250
251
252 const crawler = new AITool();
253 await crawler.run(input);
254});