Init with working version

Basic demo for Tally X AutoIxpert integration to showcase setup in
Go due to impossibility of open-sourcing n8n setup.
This commit is contained in:
rkmpa
2026-03-14 22:45:37 +01:00
commit 20acd6d77a
10 changed files with 791 additions and 0 deletions

75
pkg/models/ixpert.go Normal file
View File

@@ -0,0 +1,75 @@
package models
import "time"
type ClaimRequest struct {
Type string `json:"type"`
Labels []string `json:"labels"`
Accident Accident `json:"accident"`
Car Car `json:"car"`
Claimant Claimant `json:"claimant"`
}
type Accident struct {
Location string `json:"location"`
Circumstances string `json:"circumstances"`
Time time.Time `json:"time"`
}
type Car struct {
LicensePlate string `json:"license_plate"`
}
type Claimant struct {
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
City string `json:"city"`
Zip string `json:"zip"`
StreetAndHousenumberOrLockbox string `json:"street_and_housenumber_or_lockbox"`
Phone string `json:"phone"`
Email string `json:"email"`
}
type ClaimResponse struct {
Document Document `json:"report"`
}
type Document struct {
ID string `json:"id"`
}
type ImageMetaRequestWrapper struct {
Photos []ImageMetaRequest `json:"photos"`
}
type ImageMetaRequest struct {
Title string `json:"title"`
Description string `json:"description"`
OriginalName string `json:"original_name"`
Mimetype string `json:"mimetype"`
Size int64 `json:"size"`
Width int `json:"width"`
Height int `json:"height"`
IncludedInReport bool `json:"included_in_report"`
}
type ImageMetaResponse struct {
Photos []PhotoID `json:"photos"`
Errors []any `json:"errors"` // empty array in example, keep flexible
}
type PhotoID struct {
ID string `json:"id"`
Title string `json:"title"`
}
type UploadURLResponse struct {
UploadURLs []UploadURL `json:"upload_urls"`
Errors []any `json:"errors"`
}
type UploadURL struct {
PhotoID string `json:"photo_id"`
UploadURL string `json:"upload_url"`
ExpiresIn int `json:"expires_in"`
}

52
pkg/models/report.go Normal file
View File

@@ -0,0 +1,52 @@
package models
import (
"strconv"
"time"
)
type CrashReport struct {
EventID string
SubmissionID string
FirstName string
LastName string
Street string
Postcode int
City string
Phone string
Email string
LicensePlate string
CrashDate time.Time
CrashLocation string
CrashDescription string
CrashOpponent string
Images []string
}
func (r CrashReport) ToClaimRequest() ClaimRequest {
return ClaimRequest{
Type: "liability",
Labels: []string{"vTyXeQFryVNA"}, // add to be reviewed label for specific customer
Accident: Accident{
Location: r.CrashLocation,
Circumstances: r.CrashDescription,
Time: r.CrashDate,
},
Car: Car{
LicensePlate: r.LicensePlate,
},
Claimant: Claimant{
FirstName: r.FirstName,
LastName: r.LastName,
City: r.City,
Zip: strconv.Itoa(r.Postcode),
StreetAndHousenumberOrLockbox: r.Street,
Phone: r.Phone,
Email: r.Email,
},
}
}

156
pkg/models/tally.go Normal file
View File

@@ -0,0 +1,156 @@
package models
import (
"encoding/json"
"time"
)
type Webhook struct {
EventID string `json:"eventId"`
CreatedAt time.Time `json:"createdAt"`
Data Data `json:"data"`
}
type Data struct {
ResponseID string `json:"responseId"`
SubmissionID string `json:"submissionId"`
RespondentID string `json:"respondentId"`
FormID string `json:"formId"`
FormName string `json:"formName"`
CreatedAt time.Time `json:"createdAt"`
Fields []Field `json:"fields"`
}
type Field struct {
Key string `json:"key"`
Label string `json:"label"`
Type string `json:"type"`
Value json.RawMessage `json:"value"`
Options []Option `json:"options,omitempty"`
}
type Option struct {
ID string `json:"id"`
Text string `json:"text"`
}
type File struct {
ID string `json:"id"`
Name string `json:"name"`
URL string `json:"url"`
MimeType string `json:"mimeType"`
Size int64 `json:"size"`
}
func (d Data) FieldMap() map[string]Field {
m := make(map[string]Field, len(d.Fields))
for _, f := range d.Fields {
m[f.Key] = f
}
return m
}
func GetString(m map[string]Field, key string) (string, bool) {
f, ok := m[key]
if !ok {
return "", false
}
var s string
if err := json.Unmarshal(f.Value, &s); err != nil {
return "", false
}
return s, true
}
func GetInt(m map[string]Field, key string) (int, bool) {
f, ok := m[key]
if !ok {
return 0, false
}
var n int
if err := json.Unmarshal(f.Value, &n); err != nil {
// some systems send numbers as float64 in JSON; handle that too
var nf float64
if err2 := json.Unmarshal(f.Value, &nf); err2 != nil {
return 0, false
}
return int(nf), true
}
return n, true
}
func GetStringSlice(m map[string]Field, key string) ([]string, bool) {
f, ok := m[key]
if !ok {
return nil, false
}
var s []string
if err := json.Unmarshal(f.Value, &s); err != nil {
return nil, false
}
return s, true
}
func GetFiles(m map[string]Field, key string) ([]File, bool) {
f, ok := m[key]
if !ok {
return nil, false
}
var files []File
if err := json.Unmarshal(f.Value, &files); err != nil {
return nil, false
}
return files, true
}
func (w Webhook) ToCrashReport() CrashReport {
fm := w.Data.FieldMap()
eventID := w.EventID
submissionID := w.Data.SubmissionID
firstName, _ := GetString(fm, "question_LdEGVy")
lastName, _ := GetString(fm, "question_pL0A51")
street, _ := GetString(fm, "question_1rbKOg")
postcode, _ := GetInt(fm, "question_MArOPl")
city, _ := GetString(fm, "question_J2VRGr")
phone, _ := GetString(fm, "question_g5QAgP")
email, _ := GetString(fm, "question_yl0yg8")
licensePlate, _ := GetString(fm, "question_XeRG9P")
licenseFiles, _ := GetFiles(fm, "question_8dJk2l")
crashDate, _ := GetString(fm, "question_0EbMG9")
crashLocation, _ := GetString(fm, "question_zK0zgk")
crashDescription, _ := GetString(fm, "question_5dlkrN")
crashImages, _ := GetFiles(fm, "question_dYZAgr")
images := make([]string, 0)
for _, f := range licenseFiles {
images = append(images, f.URL)
}
for _, f := range crashImages {
images = append(images, f.URL)
}
crashDateParsed, _ := time.Parse("2006-01-02", crashDate)
return CrashReport{
EventID: eventID,
SubmissionID: submissionID,
FirstName: firstName,
LastName: lastName,
Street: street,
Postcode: postcode,
City: city,
Phone: phone,
Email: email,
LicensePlate: licensePlate,
CrashLocation: crashLocation,
CrashDescription: crashDescription,
Images: images,
CrashDate: crashDateParsed,
}
}