Skip to content

A framework-agnostic Go module for generating vCard files (.vcf) compatible with major contact managers (iOS, Android, Gmail, iCloud etc.)

License

Notifications You must be signed in to change notification settings

RumenDamyanov/go-vcard

go-vcard

CI CodeQL Dependabot codecov Go Report Card Go Reference License

A framework-agnostic Go module for generating vCard files (.vcf) compatible with major contact managers (iOS, Android, Gmail, iCloud, etc.). Inspired by php-vcard, this package works seamlessly with any Go web framework including Gin, Echo, Fiber, Chi, and standard net/http.

Features

β€’ Framework-agnostic: Use with Gin, Echo, Fiber, Chi, or standard net/http β€’ vCard 3.0/4.0 support: Generate standards-compliant vCard files β€’ Rich content: Supports names, emails, phones, addresses, organizations, photos, and more β€’ Modern Go: Type-safe, extensible, and robust (Go 1.22+) β€’ High test coverage: 90+% coverage with comprehensive test suite and CI/CD integration β€’ Easy integration: Simple API, drop-in for handlers/middleware β€’ Production ready: Used in production environments β€’ Multiple formats: File output and HTTP response generation β€’ Framework examples: Ready-to-use examples for popular Go web frameworks

Quick Links

β€’ πŸ“– Installation β€’ πŸš€ Usage Examples β€’ πŸ”§ Framework Adapters β€’ πŸ“š Documentation Wiki β€’ πŸ§ͺ Testing & Development β€’ 🀝 Contributing β€’ πŸ”’ Security Policy β€’ πŸ’ Support & Funding β€’ πŸ“„ License

Installation

go get go.rumenx.com/vcard

Usage

Basic Example (net/http)

package main

import (
    "net/http"
    "go.rumenx.com/vcard"
)

func vcardHandler(w http.ResponseWriter, r *http.Request) {
    // Create new vCard
    card := vcard.New()

    // Add contact information
    card.AddName("John", "Doe")
    card.AddEmail("john.doe@example.com")
    card.AddPhone("+1234567890")
    card.AddAddress("123 Main St", "Anytown", "CA", "12345", "USA")
    card.AddOrganization("Acme Corp")

    // Generate vCard content
    content, err := card.String()
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // Send as downloadable file
    w.Header().Set("Content-Type", "text/vcard")
    w.Header().Set("Content-Disposition", "attachment; filename=\"john_doe.vcf\"")
    w.Write([]byte(content))
}

func main() {
    http.HandleFunc("/vcard", vcardHandler)
    http.ListenAndServe(":8080", nil)
}

Advanced Features

card := vcard.New()

// Set vCard version (3.0 or 4.0)
card.SetVersion(vcard.Version40)

// Add comprehensive contact details
card.AddName("Jane", "Smith").
    AddMiddleName("Elizabeth").
    AddPrefix("Dr.").
    AddSuffix("PhD")

card.AddEmail("jane@company.com", vcard.EmailWork).
    AddEmail("jane.personal@gmail.com", vcard.EmailHome)

card.AddPhone("+1-555-123-4567", vcard.PhoneWork).
    AddPhone("+1-555-987-6543", vcard.PhoneHome).
    AddPhone("+1-555-555-5555", vcard.PhoneMobile)

// Add detailed address
card.AddAddress(
    "123 Business Ave",     // Street
    "Suite 100",            // Extended
    "Business City",        // City
    "CA",                   // Region
    "90210",               // Postal Code
    "United States",        // Country
    vcard.AddressWork,      // Type
)

// Add organization details
card.AddOrganization("Tech Corp Inc.").
    AddTitle("Senior Software Engineer").
    AddRole("Backend Developer")

// Add social/web presence
card.AddURL("https://janesmith.dev", vcard.URLWork).
    AddURL("https://linkedin.com/in/janesmith", vcard.URLSocial)

// Add photo (base64 encoded or URL)
card.AddPhoto("https://example.com/photo.jpg")

// Add custom properties
card.AddCustomProperty("X-CUSTOM-FIELD", "Custom Value")

// Save to file
err := card.SaveToFile("jane_smith.vcf")

Framework Adapters

Ready-to-use examples for popular Go web frameworks are available in the examples/ directory:

Framework Port Example Description
Gin 8080 gin-adapter Gin web framework integration
Echo 8081 echo-adapter Echo web framework integration
Fiber 8082 fiber-adapter Fiber web framework integration
Chi 8083 chi-adapter Chi web framework integration

Two Integration Approaches

1. Import Adapter Packages β€” For clean middleware integration:

go get go.rumenx.com/vcard/adapters/gin    # or echo, fiber, chi

2. Copy Example Applications β€” For quick start with full applications:

# Clone and run complete example servers
git clone https://github.com/rumendamyanov/go-vcard.git
cd go-vcard/examples/gin-adapter && go run main.go

Quick Start with Framework Examples

# Clone the repository
git clone https://github.com/rumendamyanov/go-vcard.git
cd go-vcard

# Run Gin example (port 8080)
cd examples/gin-adapter && go run main.go

# Run Echo example (port 8081)
cd examples/echo-adapter && go run main.go

# Run Fiber example (port 8082)
cd examples/fiber-adapter && go run main.go

# Run Chi example (port 8083)
cd examples/chi-adapter && go run main.go

Test the Examples

# Download vCard file
curl "http://localhost:8080/vcard/John/Doe?email=john@example.com" -o contact.vcf

# Get JSON response
curl "http://localhost:8080/contact-json?firstName=Jane&lastName=Smith&email=jane@example.com"

Integration Pattern Example

Each framework adapter follows the same pattern:

package main

import (
    "github.com/gin-gonic/gin"
    "go.rumenx.com/vcard"
    ginadapter "go.rumenx.com/vcard/adapters/gin"
)

func main() {
    r := gin.Default()

    r.GET("/contact/:name", ginadapter.VCard(func(c *gin.Context) *vcard.VCard {
        name := c.Param("name")

        card := vcard.New()
        card.AddName(name, "Doe")
        card.AddEmail(name + "@example.com")

        return card
    }))

    r.Run(":8080")
}

Fiber Example

package main

import (
    "github.com/gofiber/fiber/v2"
    "go.rumenx.com/vcard"
    fiberadapter "go.rumenx.com/vcard/adapters/fiber"
)

func main() {
    app := fiber.New()

    app.Get("/contact/:name", fiberadapter.VCard(func(c *fiber.Ctx) *vcard.VCard {
        name := c.Params("name")

        card := vcard.New()
        card.AddName(name, "Smith")
        card.AddPhone("+1234567890")

        return card
    }))

    app.Listen(":8080")
}

Echo Example

package main

import (
    "github.com/labstack/echo/v4"
    "go.rumenx.com/vcard"
    echoadapter "go.rumenx.com/vcard/adapters/echo"
)

func main() {
    e := echo.New()

    e.GET("/contact/:name", echoadapter.VCard(func(c echo.Context) *vcard.VCard {
        name := c.Param("name")

        card := vcard.New()
        card.AddName(name, "Johnson")
        card.AddEmail(name + "@company.com")

        return card
    }))

    e.Start(":8080")
}

Chi Example

package main

import (
    "net/http"
    "github.com/go-chi/chi/v5"
    "go.rumenx.com/vcard"
    chiadapter "go.rumenx.com/vcard/adapters/chi"
)

func main() {
    r := chi.NewRouter()

    r.Get("/contact/{name}", chiadapter.VCard(func(w http.ResponseWriter, r *http.Request) *vcard.VCard {
        name := chi.URLParam(r, "name")

        card := vcard.New()
        card.AddName(name, "Wilson")
        card.AddPhone("+1234567890")

        return card
    }))

    http.ListenAndServe(":8080", r)
}

Multiple Methods for Adding Information

Add() vs AddItem()

You can add vCard information using either individual methods or structured data:

Individual methods β€” Simple, type-safe, chainable:

// Recommended for most use cases
card.AddName("John", "Doe").
    AddEmail("john@example.com").
    AddPhone("+1234567890").
    AddAddress("123 Main St", "City", "State", "12345", "Country")

Structured data β€” Advanced, batch operations:

// Add contact info with detailed structure
contact := vcard.Contact{
    Name: vcard.Name{
        First:  "John",
        Last:   "Doe",
        Middle: "William",
        Prefix: "Mr.",
        Suffix: "Jr.",
    },
    Emails: []vcard.Email{
        {Address: "john@work.com", Type: vcard.EmailWork},
        {Address: "john@home.com", Type: vcard.EmailHome},
    },
    Phones: []vcard.Phone{
        {Number: "+1234567890", Type: vcard.PhoneWork},
        {Number: "+1987654321", Type: vcard.PhoneMobile},
    },
}

card.AddContact(contact)

Documentation

For comprehensive documentation and examples:

β€’ πŸ“š Quick Start Guide - Get up and running quickly β€’ πŸ”§ Basic Usage - Core functionality and examples β€’ πŸš€ Advanced Usage - Advanced features and customization β€’ πŸ”Œ Framework Integration - Integration with popular frameworks β€’ 🎯 Best Practices - Performance tips and recommendations β€’ 🀝 Contributing Guidelines - How to contribute to this project β€’ πŸ”’ Security Policy - Security guidelines and vulnerability reporting β€’ πŸ’ Funding & Support - Support and sponsorship information

Testing & Development

Running Tests

# Run all tests
go test ./...

# Run tests with coverage
go test -cover ./...

# Generate HTML coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html

Code Quality

# Run static analysis
go vet ./...

# Format code
go fmt ./...

# Run linter (if installed)
golangci-lint run

Contributing

We welcome contributions! Please see our Contributing Guidelines for details on:

β€’ Development setup β€’ Coding standards β€’ Testing requirements β€’ Pull request process

Security

If you discover a security vulnerability, please review our Security Policy for responsible disclosure guidelines.

Support

If you find this package helpful, consider:

β€’ ⭐ Starring the repository β€’ πŸ’ Supporting development β€’ πŸ› Reporting issues β€’ 🀝 Contributing improvements

License

MIT License


About

A framework-agnostic Go module for generating vCard files (.vcf) compatible with major contact managers (iOS, Android, Gmail, iCloud etc.)

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •