Contact Extractor
Extracts structured contact information from free-form text. Shows how to handle missing fields.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type ContactInfo struct {
Name string `json:"name"`
Email string `json:"email"`
Company string `json:"company"`
Role string `json:"role"`
}
func extract(input string) ContactInfo {
body, _ := json.Marshal(map[string]any{
"model": "llama3.2",
"messages": []Message{
{Role: "system", Content: `Extract contact information from the text.
Return JSON: {"name": "string", "email": "string", "company": "string", "role": "string"}
Use empty string for missing fields. Return only the JSON.`},
{Role: "user", Content: input},
},
"stream": false,
"format": "json",
})
resp, err := http.Post("http://localhost:11434/api/chat", "application/json", bytes.NewReader(body))
if err != nil {
fmt.Println("Error:", err)
return ContactInfo{}
}
defer resp.Body.Close()
data, _ := io.ReadAll(resp.Body)
var apiResp struct {
Message struct {
Content string `json:"content"`
} `json:"message"`
}
json.Unmarshal(data, &apiResp)
var contact ContactInfo
json.Unmarshal([]byte(apiResp.Message.Content), &contact)
return contact
}
func main() {
inputs := []string{
"Hi, I'm Sarah Chen, CTO at Dataflow Labs. Reach me at [email protected]",
"Send the report to [email protected] when it's ready.",
"Our new intern Alex starts on Monday.",
}
for _, input := range inputs {
c := extract(input)
fmt.Printf("Name: %-15s Role: %-10s Company: %-15s Email: %s\n",
field(c.Name), field(c.Role), field(c.Company), field(c.Email))
}
// Name: Sarah Chen Role: CTO Company: Dataflow Labs Email: [email protected]
// Name: (missing) Role: (missing) Company: Acme Email: [email protected]
// Name: Alex Role: Intern Company: (missing) Email: (missing)
}
func field(s string) string {
if s == "" {
return "(missing)"
}
return s
}