-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathopenai_title_shortener.js
134 lines (121 loc) · 4.95 KB
/
openai_title_shortener.js
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
let settings = input.config({
title: "Shorten Video Titles with AI",
description: `This script uses the OpenAI API to shorten YouTube video titles based on the video's title and description. The shortened title should include the key subject of the video within the first 30 characters.`,
items: [
input.config.text("openAiKey", {
label: "🗝️ OpenAI API Key",
description: "Enter your OpenAI API key",
}),
input.config.table("videoTable", {
label: "🎥 Video Table",
description: "Select the table containing your video records",
}),
input.config.view("view", {
parentTable: "videoTable",
label: "👁️ View",
description: "Select the view to limit the records processed",
}),
input.config.field("titleField", {
parentTable: "videoTable",
label: "📝 Title Field",
description: "Select the field containing the video titles",
}),
input.config.field("descriptionField", {
parentTable: "videoTable",
label: "📝 Description Field",
description: "Select the field containing the video descriptions",
}),
input.config.field("shortTitleField", {
parentTable: "videoTable",
label: "✂️ Short Title Field",
description: "Select the field where the shortened titles will be stored",
}),
input.config.field("checklistField", {
parentTable: "videoTable",
label: "✅ Checklist Field",
description: "Select the checklist field to set to TRUE after updating the title",
}),
input.config.select("model", {
label: "🤖 OpenAI Model",
description: "Select the OpenAI model to use",
options: [
{ label: "GPT-3.5 Turbo", value: "gpt-3.5-turbo" },
{ label: "GPT-4o Mini", value: "gpt-4o-mini" }
],
defaultValue: "gpt-3.5-turbo"
}),
],
});
let {
openAiKey,
videoTable,
titleField,
descriptionField,
shortTitleField,
checklistField,
view,
model
} = settings;
// Function to fetch the shortened title using the OpenAI API
async function fetchShortTitle(title, description) {
let messages = [
{
role: "system",
content: "You are a helpful assistant that shortens YouTube video titles."
},
{
role: "user",
content: `Based on the following YouTube video title and description, create a shorter title that includes the key subject of the video within the first 30 characters. Ensure the shortened title is clear, concise, in Title Case formatting, factual, and not hyperbolic (no ALL CAPS). The title does not need to include the name of the YouTube channel, just the subject of the video itself.\n\nTitle: ${title}\nDescription: ${description}\n\nShortened Title:`
}
];
let response = await fetch("https://api.openai.com/v1/chat/completions", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${openAiKey}`,
},
body: JSON.stringify({
model: model,
messages: messages,
max_tokens: 50,
}),
});
if (!response.ok) {
let errorText = await response.text();
console.error(`Failed to fetch from OpenAI API: ${response.statusText}`);
console.error(`Error response: ${errorText}`);
throw new Error(`Failed to fetch from OpenAI API: ${response.statusText}`);
}
let data = await response.json();
if (!data.choices) {
console.log("Unexpected response format:", data);
throw new Error("Unexpected response format from OpenAI API");
}
// Extract the shortened title from the API response
let shortTitle = data.choices[0].message.content.trim();
return shortTitle;
}
// Fetch records from the specified view
let query = await view.selectRecordsAsync({
fields: [titleField.id, descriptionField.id, shortTitleField.id, checklistField.id]
});
output.text(`Processing ${query.records.length} records from the ${view.name} view...`);
for (let record of query.records) {
let title = record.getCellValueAsString(titleField.id);
let description = record.getCellValueAsString(descriptionField.id);
if (!title && !description) continue;
let shortTitle;
try {
shortTitle = await fetchShortTitle(title, description);
} catch (error) {
output.text(`Error fetching short title for record ${record.id}: ${error.message}`);
continue;
}
if (!shortTitle) continue;
// Update the video record with the shortened title and set the checklist field to TRUE
await videoTable.updateRecordAsync(record.id, {
[shortTitleField.id]: shortTitle,
[checklistField.id]: true
});
}
output.text("Operation complete.");