Go

Set up Pingback in your Go app with the pingback-go SDK.

Installation

go get github.com/runpingback/pingback-go

Setup

Create a Pingback client and mount the handler on your HTTP server:

package main

import (
    "net/http"
    "os"

    pingback "github.com/runpingback/pingback-go"
)

func main() {
    pb := pingback.New(
        os.Getenv("PINGBACK_API_KEY"),
        os.Getenv("PINGBACK_CRON_SECRET"),
    )

    // Define functions here...

    http.Handle("/api/pingback", pb.Handler())
    http.ListenAndServe(":8080", nil)
}

Defining Functions

Register cron jobs with pb.Cron() and background tasks with pb.Task(). Handlers return (any, error) — the return value becomes the execution result:

pb.Cron("send-emails", "*/15 * * * *", func(ctx *pingback.Context) (any, error) {
    pending := getPendingEmails()
    for _, email := range pending {
        ctx.Task("send-email", map[string]string{"id": email.ID})
    }
    ctx.Log("Dispatched emails", "count", len(pending))
    return map[string]int{"dispatched": len(pending)}, nil
}, pingback.WithRetries(3), pingback.WithTimeout("60s"))

pb.Task("send-email", func(ctx *pingback.Context) (any, error) {
    var p struct{ ID string `json:"id"` }
    json.Unmarshal(ctx.Payload, &p)
    err := sendEmail(p.ID)
    ctx.Log("Sent email", "id", p.ID)
    return nil, err
}, pingback.WithRetries(2), pingback.WithTimeout("15s"))

Structured Logging

The context provides structured logging with key-value metadata:

ctx.Log("message")                         // info
ctx.Log("message", "key", "value")         // info with metadata
ctx.Warn("slow query", "ms", 2500)         // warning
ctx.Error("failed", "code", "E001")        // error
ctx.Debug("cache stats", "hits", 847)      // debug

Programmatic Triggering

Trigger tasks from anywhere in your code using pb.Trigger():

execID, err := pb.Trigger(context.Background(), "send-email", map[string]string{
    "to": "user@example.com",
})

Fan-Out

Dispatch background tasks from within a cron handler using ctx.Task(). Each task runs independently with its own retries and timeout:

pb.Cron("process-orders", "0 * * * *", func(ctx *pingback.Context) (any, error) {
    orders := getUnprocessedOrders()
    for _, order := range orders {
        ctx.Task("fulfill-order", map[string]string{"orderId": order.ID})
    }
    ctx.Log("Dispatched orders", "count", len(orders))
    return map[string]int{"dispatched": len(orders)}, nil
}, pingback.WithRetries(3), pingback.WithTimeout("120s"))

Configuration

pb := pingback.New(
    apiKey,
    cronSecret,
    pingback.WithPlatformURL("https://api.pingback.lol"),  // default
    pingback.WithBaseURL("https://myapp.com"),
)

Function Options

OptionDefaultDescription
WithRetries(n)0Retry up to n times on failure.
WithTimeout("30s")30sExecution timeout.
WithConcurrency(n)1Max concurrent runs.

Environment Variables

PINGBACK_API_KEY=pb_live_your_api_key_here
PINGBACK_CRON_SECRET=your_cron_secret_here

How It Works

1. Register cron jobs and tasks with pb.Cron() and pb.Task().

2. Mount the handler with http.Handle("/api/pingback", pb.Handler()).

3. On the first request, the SDK registers your functions with the Pingback platform.

4. The platform sends HMAC-signed HTTP requests to your handler on schedule.

5. The handler verifies the signature, executes the function, and returns results with logs.