Response is
2024/04/29 13:12:22 Analyzing text "indeed Ali"
Dumping Response:
(main.ResponseData) {
Choices: ([]main.Choice) <nil>
}
Error analyzing text: no response )
package main
import (
"bytes"
"encoding/csv"
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
"time"
"github.com/davecgh/go-spew/spew"
)
func main() {
// Open messages CSV file
messagesFile, err := os.Open("temp.csv")
if err != nil {
fmt.Println("Error opening messages file:", err)
return
}
defer messagesFile.Close()
// Create CSV reader
reader := csv.NewReader(messagesFile)
reader.Comma = ',' // Set the delimiter to comma
reader.TrimLeadingSpace = true
// Read existing outputs to avoid re-processing
existingEntries, err := readExistingEntries("output.csv")
if err != nil {
log.Fatalf("Error reading existing entries: %v", err)
}
// Read and process each record
header, err := reader.Read() // Read the header row
if err != nil {
fmt.Println("Error reading header from CSV:", err)
return
}
fmt.Println(strings.Join(header, ",")) // Print header
file, err := os.OpenFile("output.csv", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("failed creating file: %s", err)
}
defer file.Close()
writer := csv.NewWriter(file)
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
fmt.Println("Error reading record from CSV:", err)
continue
}
content := record[0] // Assuming content is in the first column
if strings.Contains(content, "Chat Rules") {
continue // Skip this message
}
if strings.Contains(content, "has left the chat") {
continue
}
if strings.Contains(content, "!rules") {
continue
}
if strings.HasPrefix(content, "!") {
continue
}
if strings.Contains(content, "has joined the chat") {
continue
}
if _, exists := existingEntries[content]; exists {
continue // Skip this message as it's already processed
}
if len(content) < 4 {
continue
}
// Check for blocked words in the content body
//if containsBlockedWord(content, blockedWords) {
response, err := analyzeText(content)
if err != nil {
fmt.Printf("Error analyzing text: %v %v\n", err)
time.Sleep(time.Second * 4)
continue
}
if len(response.Choices) > 0 {
messageS := response.Choices[0].Message.Content
message := strings.Split(messageS, ",")
if len(message) < 3 {
continue
}
//log.Println("debug message: ", messageS)
log.Printf("Content: %v Rating: %v Category: %v OffensiveWords: %v \n", content, message[0], message[2], message[1])
data := []string{
message[0], // Rating
message[2], // Category
message[1], // Swear word or word offensively found
content, // full content
}
if err := writer.Write(data); err != nil {
log.Fatalln("error writing record to csv:", err)
}
writer.Flush()
}
}
}
func containsBlockedWord(content string, blockedWords map[string]bool) bool {
words := strings.Fields(strings.ToLower(content))
for _, word := range words {
if _, found := blockedWords[word]; found {
return true
}
}
return false
}
func analyzeText(text string) (ResponseData, error) {
text = strings.Trim(text, " ")
log.Println("Analyzing text ", text)
var responseData ResponseData
if len(text) < 5 {
return responseData, nil
}
// Prepare the request body as JSON
requestBody, err := json.Marshal(RequestData{
Model: "gpt-4",
MaxTokens: 50,
//Stream: false,
Messages: []Message{
{
Role: "system",
Content: "Your task is to analyze messages and maintain a respectful and safe chatting environment. Rate the severity of the following text on a scale of 1-10, with descriptions for each level: 1 (None): No inappropriate content. 2-3 (Mild): Potentially disrespectful or slang but not offensive. 4-6 (Moderate): Clearly offensive language, but not hateful or targeted. 7-9 (Severe): Hateful language, threats, or targeted harassment. 10 (Extreme): Severe profanity, graphic content, or explicit threats. Identify any inappropriate content and categorize it into one or more of the following: Profanity (Mild/Moderate/Severe): Swear words of varying intensity. Derogatory (Specify type): Slurs or offensive terms targeting specific groups. Sexual (Suggestive/Explicit): Content of a sexual nature. Violence (Threat/Description): Threats or depictions of violence. Consider the context of the message, including the intent, target, and relationship between users. Response format: Severity rating (explanation), Category (explanation), [List of specific inappropriate words or phrases]. Examples of expected responses from you, keep the format of the response exactly like this. 1, None, (None), Hey there! How are you doing today? 2, Profanity, (Mild), [Damn]: That was a damn good game (not directed at anyone) 2, Profanity, (Mild), [Sucks]: This game sucks (not directed at anyone) 5, Derogatory, (Moderate), []: If you are not obese in USA you are auto in the top 20% of females (targeted towards women) 10, Derogatory, (Extreme), [N-word]: Get out of here, you [N-word]! (Hateful and targeted) 10, Profanity, (Extreme), [Fuck]: F off bro! (Directed at someone or anyone) 10, Sexual, (Extreme), [Boobies]: I like your boobies (Sexual) If I do not provide enough text just return it as 0 and none rating. Please analyze and rate the following text:",
},
{
Role: "user",
Content: fmt.Sprintf("%s", text),
},
},
})
if err != nil {
fmt.Println("Error preparing request:", err)
return responseData, err
}
// Create an HTTP client and request
client := &http.Client{Timeout: time.Minute * 1}
req, err := http.NewRequest("POST", "https://api.openai.com/v1/chat/completions", bytes.NewBuffer(requestBody))
//req, err := http.NewRequest("POST", "http://localhost:1234/v1/chat/completions", bytes.NewBuffer(requestBody))
if err != nil {
fmt.Println("Error creating request:", err)
return responseData, err
}
// Set headers
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Authorization", "Bearer sk-***********REMOVED*****FOR*SHARING*CODE")
// Send the request
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error sending request:", err)
return responseData, err
}
defer resp.Body.Close()
// Read and parse the response body
responseBody, err := io.ReadAll(resp.Body)
if err != nil {
fmt.Println("Error reading response:", err)
return responseData, err
}
err = json.Unmarshal(responseBody, &responseData)
if err != nil {
fmt.Println("Error parsing response:", err)
return responseData, err
}
spew.Dump(responseData)
if len(responseData.Choices) > 0 {
return responseData, nil
}
return responseData, fmt.Errorf("no response %v", len(responseData.Choices))
}
func readExistingEntries(filePath string) (map[string]bool, error) {
entries := make(map[string]bool)
file, err := os.Open(filePath)
if err != nil {
return nil, err
}
defer file.Close()
reader := csv.NewReader(file)
for {
record, err := reader.Read()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}
entries[record[3]] = true // Assuming full content is in the fourth column
}
return entries, nil
}
type RequestData struct {
Model string `json:"model"`
MaxTokens int `json:"max_tokens"`
Messages []Message `json:"messages"`
//Stream bool
}
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type ResponseData struct {
Choices []Choice `json:"choices"`
}
type Choice struct {
Message Message `json:"message"`
}
Thanks @RonaldGRuckus champ.