### Quick Start Workflow for Threads API Go Client Examples Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This snippet outlines a quick start workflow for using the Threads API Go client examples. It sequentially runs the authentication, post creation, and insights examples to demonstrate a typical usage pattern. Ensure you have completed the setup and environment variable configuration first. ```bash # 1. Authenticate first cd authentication && go run main.go # 2. Create posts cd ../post-creation && go run main.go # 3. Check analytics cd ../insights && go run main.go ``` -------------------------------- ### Run Existing Token Example for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This example shows how to use the Threads API Go client with an existing access token, bypassing the OAuth flow. It demonstrates direct token usage, validation, and immediate client setup. Navigate to the `existing-token` directory and run `go run main.go` to execute. ```bash cd existing-token && go run main.go ``` -------------------------------- ### Install Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Command to install the library using the Go package manager. ```bash go get github.com/tirthpatell/threads-go ``` -------------------------------- ### Setup Development Environment for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/CONTRIBUTING.md Commands to clone the repository, install dependencies, configure environment variables for API authentication, and execute test suites. ```bash git clone https://github.com/tirthpatell/threads-go.git cd threads-go go mod download export THREADS_CLIENT_ID="your-client-id" export THREADS_CLIENT_SECRET="your-client-secret" export THREADS_REDIRECT_URI="your-redirect-uri" export THREADS_ACCESS_TOKEN="your-token" go test -short ./... go test -short -race ./... go test ./tests/integration/... ``` -------------------------------- ### Run Post Creation Example for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This example covers creating various types of posts using the Threads API Go client, including text, image, video, carousel, quote, reposts, and GIF posts. It also supports advanced options like ghost posts and reply controls. Navigate to the `post-creation` directory and run `go run main.go` to execute. ```bash cd post-creation && go run main.go ``` -------------------------------- ### Setup Environment Variables for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This snippet demonstrates how to copy an environment template and populate it with necessary credentials for the Threads API Go client. It requires setting THREADS_CLIENT_ID, THREADS_CLIENT_SECRET, and THREADS_REDIRECT_URI. The `source .env` command loads these variables into the current shell session. ```bash # Copy environment template cp .env.example .env # Add your credentials to .env THREADS_CLIENT_ID=your_app_id_here THREADS_CLIENT_SECRET=your_app_secret_here THREADS_REDIRECT_URI=https://your-domain.com/callback # Load environment source .env ``` -------------------------------- ### Run Authentication Example for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This example demonstrates the complete OAuth 2.0 flow for the Threads API Go client, including token management. It covers authorization URL generation, code exchange for tokens, conversion to long-lived tokens, and token storage/validation. Navigate to the `authentication` directory and run `go run main.go` to execute. ```bash cd authentication && go run main.go ``` -------------------------------- ### Run Insights and Analytics Example for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This example shows how to access performance metrics for posts and accounts using the Threads API Go client. It includes retrieving publishing quotas, follower demographics, and applying time-based filtering. Navigate to the `insights` directory and run `go run main.go` to execute. ```bash cd insights && go run main.go ``` -------------------------------- ### Run Reply Management Example for Threads API Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/examples/README.md This example demonstrates how to handle conversations and replies using the Threads API Go client. Functionalities include creating and retrieving replies, conversation threading, reply moderation (hide/unhide), reply approvals, and pagination/sorting. Navigate to the `reply-management` directory and run `go run main.go` to execute. ```bash cd reply-management && go run main.go ``` -------------------------------- ### Manage Posts and Content Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Examples for creating, retrieving, and deleting posts on the Threads platform. ```go // Create different post types textPost, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "Hello Threads!", }) imagePost, err := client.CreateImagePost(ctx, &threads.ImagePostContent{ Text: "Check this out!", ImageURL: "https://example.com/image.jpg", }) // Get posts post, err := client.GetPost(ctx, threads.PostID("123")) posts, err := client.GetUserPosts(ctx, threads.UserID("456"), &threads.PaginationOptions{Limit: 25}) // Delete post err = client.DeletePost(ctx, threads.PostID("123")) ``` -------------------------------- ### Implement Go Validation Logic Source: https://github.com/tirthpatell/threads-go/blob/main/CONTRIBUTING.md An example of a Go function demonstrating proper error handling and input validation following project style guidelines. ```go func validatePostContent(content *PostContent) error { if content.Text == "" { return NewValidationError(400, "Text required", "Post text cannot be empty", "text") } return nil } ``` -------------------------------- ### Iterating Through Posts, Replies, and Search Results with Pagination in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Demonstrates how to use iterators to handle pagination for large datasets of posts, replies, and search results in Go. The iterators automatically manage fetching subsequent pages of data. Includes an example of collecting all results at once. Requires an initialized Threads client and context. ```go // Posts iterator userID := threads.ConvertToUserID("user_id") iterator := threads.NewPostIterator(client, userID, &threads.PostsOptions{ Limit: 25, }) for iterator.HasNext() { response, err := iterator.Next(ctx) if err != nil { log.Fatal(err) } for _, post := range response.Data { fmt.Printf("Post: %s\n", post.Text) } } // Replies iterator replyIterator := threads.NewReplyIterator(client, threads.PostID("123"), &threads.RepliesOptions{ Limit: 50, }) // Search iterator searchIterator := threads.NewSearchIterator(client, "golang", "keyword", &threads.SearchOptions{ Limit: 25, }) // Collect all results at once allPosts, err := iterator.Collect(ctx) ``` -------------------------------- ### GET /keyword-search Source: https://context7.com/tirthpatell/threads-go/llms.txt Searches for public Threads posts based on keywords, tags, or specific filters such as media type and author. ```APIDOC ## GET /keyword-search ### Description Searches for public Threads posts by keyword with various filtering options including search type (top/recent), search mode (tag), media type, and author username. ### Method GET ### Endpoint /keyword-search ### Parameters #### Query Parameters - **query** (string) - Required - The keyword or tag to search for. - **limit** (int) - Optional - Maximum number of results to return. - **searchType** (string) - Optional - Filter by 'top' or 'recent' posts. - **searchMode** (string) - Optional - Filter by 'tag' mode. - **mediaType** (string) - Optional - Filter by 'image' or 'video'. - **authorUsername** (string) - Optional - Filter posts by a specific author. ### Request Example { "query": "golang", "limit": 25 } ### Response #### Success Response (200) - **data** (array) - List of post objects containing Username and Text. #### Response Example { "data": [ { "username": "example_user", "text": "Learning golang is fun!" } ] } ``` -------------------------------- ### Handling Typed Errors from the Threads API Client in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Demonstrates how to handle various typed errors returned by the Threads API client in Go. Includes examples for authentication errors, rate limit errors (with retry logic), validation errors, and transient errors. Covers common error types provided by the library. ```go switch { case threads.IsAuthenticationError(err): // Handle authentication issues case threads.IsRateLimitError(err): rateLimitErr := err.(*threads.RateLimitError) time.Sleep(rateLimitErr.RetryAfter) case threads.IsValidationError(err): validationErr := err.(*threads.ValidationError) log.Printf("Invalid %s: %s", validationErr.Field, err.Error()) case threads.IsTransientError(err): // Safe to retry — transient API error } ``` -------------------------------- ### Get User Posts with Pagination using threads-go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves posts made by a specific user, supporting pagination to fetch posts in batches. Requires an authenticated client and a user ID. Returns a paginated response containing a list of posts and cursor information for fetching subsequent pages. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() userID := threads.UserID("user-id-here") posts, err := client.GetUserPosts(ctx, userID, &threads.PaginationOptions{ Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d posts\n", len(posts.Data)) for _, post := range posts.Data { fmt.Printf("- %s: %s\n", post.ID, post.Text[:min(50, len(post.Text))]) } // Get next page using cursor if posts.Paging.Cursors != nil && posts.Paging.Cursors.After != "" { nextPage, err := client.GetUserPosts(ctx, userID, &threads.PaginationOptions{ Limit: 25, After: posts.Paging.Cursors.After, }) if err != nil { log.Fatal(err) } fmt.Printf("Next page has %d posts\n", len(nextPage.Data)) } } func min(a, b int) int { if a < b { return a } return b } ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Setting up credentials via environment variables and initializing the client automatically. ```bash export THREADS_CLIENT_ID="your-client-id" export THREADS_CLIENT_SECRET="your-client-secret" export THREADS_REDIRECT_URI="your-redirect-uri" export THREADS_ACCESS_TOKEN="your-access-token" ``` ```go client, err := threads.NewClientFromEnv() ``` -------------------------------- ### Initialize Threads Client Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Demonstrates how to initialize the client using an existing access token or via the full OAuth 2.0 flow. ```go client, err := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "your-redirect-uri", }) // Create a post post, err := client.CreateTextPost(context.Background(), &threads.TextPostContent{ Text: "Hello Threads!", }) ``` ```go config := &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "your-redirect-uri", Scopes: []string{"threads_basic", "threads_content_publish"}, } client, err := threads.NewClient(config) // Get authorization URL authURL := client.GetAuthURL(config.Scopes) // Exchange authorization code for token ctx := context.Background() err = client.ExchangeCodeForToken(ctx, "auth-code-from-callback") err = client.GetLongLivedToken(ctx) ``` -------------------------------- ### Initialize Threads API Client Source: https://context7.com/tirthpatell/threads-go/llms.txt Demonstrates how to instantiate the Threads API client using either a direct access token or environment variables. These methods ensure the client is properly configured for API requests. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, err := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) if err != nil { log.Fatal(err) } me, err := client.GetMe(context.Background()) if err != nil { log.Fatal(err) } fmt.Printf("Authenticated as: %s\n", me.Username) } ``` ```go package main import ( "context" "log" "os" "github.com/tirthpatell/threads-go" ) func main() { os.Setenv("THREADS_CLIENT_ID", "your-client-id") os.Setenv("THREADS_CLIENT_SECRET", "your-client-secret") os.Setenv("THREADS_REDIRECT_URI", "https://yourapp.com/callback") os.Setenv("THREADS_ACCESS_TOKEN", "your-access-token") client, err := threads.NewClientFromEnv() if err != nil { log.Fatal(err) } ctx := context.Background() me, err := client.GetMe(ctx) if err != nil { log.Fatal(err) } log.Printf("Connected as: %s", me.Username) } ``` -------------------------------- ### GET /locations Source: https://context7.com/tirthpatell/threads-go/llms.txt Searches for geographical locations by query string or latitude and longitude coordinates. ```APIDOC ## GET /locations ### Description Searches for locations by query string or coordinates for use in location-tagged posts. ### Method GET ### Endpoint /locations ### Parameters #### Query Parameters - **query** (string) - Optional - The location name to search for. - **lat** (float) - Optional - Latitude coordinate. - **lng** (float) - Optional - Longitude coordinate. ### Request Example { "query": "New York" } ### Response #### Success Response (200) - **data** (array) - List of location objects containing ID, Name, City, Country, Latitude, and Longitude. #### Response Example { "data": [ { "id": "12345", "name": "New York", "city": "New York", "country": "USA", "latitude": 40.7128, "longitude": -74.0060 } ] } ``` -------------------------------- ### Running Unit and Integration Tests for Threads Go Client Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Provides instructions for running tests for the Threads Go client library. Includes commands for executing unit tests and integration tests, the latter requiring a valid access token to be set as an environment variable. ```bash # Unit tests go test ./... # Integration tests (requires valid credentials) export THREADS_ACCESS_TOKEN="your-token" go test ./tests/integration/... ``` -------------------------------- ### Get Location Details using threads-go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves comprehensive location information such as address, city, and coordinates. Requires a valid LocationID and an authenticated client instance. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() locationID := threads.LocationID("location-id-here") location, err := client.GetLocation(ctx, locationID) if err != nil { log.Fatal(err) } fmt.Printf("Name: %s\n", location.Name) fmt.Printf("Address: %s\n", location.Address) fmt.Printf("City: %s\n", location.City) fmt.Printf("Country: %s\n", location.Country) fmt.Printf("Postal Code: %s\n", location.PostalCode) fmt.Printf("Coordinates: %f, %f\n", location.Latitude, location.Longitude) } ``` -------------------------------- ### Constructing Threads Posts with ContainerBuilder Source: https://context7.com/tirthpatell/threads-go/llms.txt Demonstrates the use of the fluent ContainerBuilder API to create various post configurations, including standard text posts, media posts with spoilers, carousel items, and posts with specific reply controls or GIF attachments. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { // Build a text post with multiple options builder := threads.NewContainerBuilder(). SetMediaType("TEXT"). SetText("Hello from the fluent builder!"). SetReplyControl(threads.ReplyControlFollowersOnly). SetTopicTag("golang"). SetLocationID("location-id") params := builder.Build() fmt.Printf("Built parameters: %v\n", params) // Build a post with text spoilers spoilerBuilder := threads.NewContainerBuilder(). SetMediaType("TEXT"). SetText("This contains a secret: the answer is 42"). SetTextEntities([]threads.TextEntity{ { EntityType: "SPOILER", Offset: 25, // Start of "the answer is 42" Length: 17, // Length of "the answer is 42" }, }) spoilerParams := spoilerBuilder.Build() fmt.Printf("Spoiler parameters: %v\n", spoilerParams) // Build an image post with alt text and spoiler media imageBuilder := threads.NewContainerBuilder(). SetMediaType("IMAGE"). SetImageURL("https://example.com/image.jpg"). SetText("Check out this image"). SetAltText("A beautiful landscape photo"). SetIsSpoilerMedia(true) imageParams := imageBuilder.Build() fmt.Printf("Image parameters: %v\n", imageParams) // Build a carousel item carouselItemBuilder := threads.NewContainerBuilder(). SetMediaType("IMAGE"). SetImageURL("https://example.com/carousel-item.jpg"). SetIsCarouselItem(true). SetAltText("Carousel image") carouselItemParams := carouselItemBuilder.Build() fmt.Printf("Carousel item parameters: %v\n", carouselItemParams) // Build a post with GIF attachment gifBuilder := threads.NewContainerBuilder(). SetMediaType("TEXT"). SetText("Check out this GIF!"). SetGIFAttachment(&threads.GIFAttachment{ GIFID: "giphy-id", Provider: threads.GIFProviderGiphy, }) gifParams := gifBuilder.Build() fmt.Printf("GIF parameters: %v\n", gifParams) // Build a ghost post ghostBuilder := threads.NewContainerBuilder(). SetMediaType("TEXT"). SetText("This will disappear!"). SetIsGhostPost(true) ghostParams := ghostBuilder.Build() fmt.Printf("Ghost post parameters: %v\n", ghostParams) // Build a post with reply approvals enabled approvalBuilder := threads.NewContainerBuilder(). SetMediaType("TEXT"). SetText("Reply approvals are enabled on this post"). SetEnableReplyApprovals(true) approvalParams := approvalBuilder.Build() fmt.Printf("Reply approval parameters: %v\n", approvalParams) } ``` -------------------------------- ### Get Account Insights using threads-go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves account-level analytics including follower counts and demographics. Supports date ranges and specific metric breakdowns like country or age. ```go package main import ( "context" "fmt" "log" "time" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() userID := threads.UserID("user-id-here") // Get lifetime account insights insights, err := client.GetAccountInsights(ctx, userID, []string{ "views", "likes", "replies", "reposts", "followers_count", }, "lifetime") if err != nil { log.Fatal(err) } for _, insight := range insights.Data { fmt.Printf("%s: ", insight.Name) if insight.TotalValue != nil { fmt.Printf("%d\n", insight.TotalValue.Value) } else if len(insight.Values) > 0 { fmt.Printf("%d\n", insight.Values[0].Value) } } // Get account insights with date range since := time.Now().AddDate(0, 0, -30) // Last 30 days until := time.Now() rangeInsights, err := client.GetAccountInsightsWithOptions(ctx, userID, &threads.AccountInsightsOptions{ Metrics: []threads.AccountInsightMetric{ threads.AccountInsightViews, threads.AccountInsightLikes, }, Period: threads.InsightPeriodDay, Since: &since, Until: &until, }) if err != nil { log.Fatal(err) } for _, insight := range rangeInsights.Data { fmt.Printf("%s over last 30 days:\n", insight.Title) for _, value := range insight.Values { fmt.Printf(" %s: %d\n", value.EndTime, value.Value) } } // Get follower demographics demographics, err := client.GetAccountInsightsWithOptions(ctx, userID, &threads.AccountInsightsOptions{ Metrics: []threads.AccountInsightMetric{threads.AccountInsightFollowerDemographics}, Breakdown: "country", // country, city, age, or gender }) if err != nil { log.Fatal(err) } fmt.Println("Follower demographics by country:") for _, insight := range demographics.Data { fmt.Printf(" %s\n", insight.Description) } } ``` -------------------------------- ### Get User Profile by ID using Threads Go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves profile information for a specific user by their ID. This function requires the user ID as input and returns their username and biography. Ensure the client is authenticated. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() userID := threads.UserID("user-id-here") user, err := client.GetUser(ctx, userID) if err != nil { log.Fatal(err) } fmt.Printf("Username: @%s\n", user.Username) fmt.Printf("Bio: %s\n", user.Biography) } ``` -------------------------------- ### Get Post Insights using threads-go Source: https://context7.com/tirthpatell/threads-go/llms.txt Fetches engagement metrics for a specific post, including views, likes, and replies. Supports both basic metric retrieval and advanced options like specifying time periods. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() postID := threads.PostID("post-id-here") // Get basic insights insights, err := client.GetPostInsights(ctx, postID, []string{ "views", "likes", "replies", "reposts", "quotes", "shares", }) if err != nil { log.Fatal(err) } for _, insight := range insights.Data { fmt.Printf("%s: ", insight.Name) if len(insight.Values) > 0 { fmt.Printf("%d\n", insight.Values[0].Value) } } // Get insights with advanced options advancedInsights, err := client.GetPostInsightsWithOptions(ctx, postID, &threads.PostInsightsOptions{ Metrics: []threads.PostInsightMetric{ threads.PostInsightViews, threads.PostInsightLikes, threads.PostInsightReplies, }, Period: threads.InsightPeriodLifetime, }) if err != nil { log.Fatal(err) } for _, insight := range advancedInsights.Data { fmt.Printf("%s (%s): %v\n", insight.Title, insight.Period, insight.Values) } } ``` -------------------------------- ### Client Initialization Source: https://context7.com/tirthpatell/threads-go/llms.txt Methods to initialize the Threads API client using either an existing access token or environment variables. ```APIDOC ## Client Initialization ### Description Initializes the Threads API client to interact with Meta's platform. Supports manual token injection or environment-based configuration. ### Methods - `NewClientWithToken(token string, config *Config)`: Initializes client with a specific token. - `NewClientFromEnv()`: Initializes client using `THREADS_CLIENT_ID`, `THREADS_CLIENT_SECRET`, and `THREADS_REDIRECT_URI`. ### Request Example ```go client, err := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ``` ``` -------------------------------- ### Advanced Post Creation with Container Builder in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Illustrates using the fluent `ContainerBuilder` for advanced post creation in Go. This builder allows setting various post properties like media type, text, reply controls, topic tags, and location IDs before building the post parameters. Requires the `threads` package. ```go builder := threads.NewContainerBuilder(). SetMediaType("TEXT"). SetText("Hello from the builder!"). SetReplyControl(threads.ReplyControlFollowersOnly). SetTopicTag("golang"). SetLocationID("location-id") params := builder.Build() ``` -------------------------------- ### Get Single Post by ID with threads-go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves detailed information about a specific Threads post using its unique ID. Requires an authenticated client. Returns a Post object containing metadata such as text, author, media type, and timestamp. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() postID := threads.PostID("12345678901234567") post, err := client.GetPost(ctx, postID) if err != nil { log.Fatal(err) } fmt.Printf("Post ID: %s\n", post.ID) fmt.Printf("Text: %s\n", post.Text) fmt.Printf("Author: %s\n", post.Username) fmt.Printf("Media Type: %s\n", post.MediaType) fmt.Printf("Permalink: %s\n", post.Permalink) fmt.Printf("Timestamp: %v\n", post.Timestamp) fmt.Printf("Has Replies: %v\n", post.HasReplies) fmt.Printf("Is Quote Post: %v\n", post.IsQuotePost) } ``` -------------------------------- ### Get User Ghost Posts with Pagination using threads-go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves auto-expiring ghost posts from a specific user, with support for pagination. Requires an authenticated client and a user ID. Returns a paginated response containing ghost posts and their expiration timestamps. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() userID := threads.UserID("user-id-here") ghosts, err := client.GetUserGhostPosts(ctx, userID, &threads.PaginationOptions{ Limit: 10, }) if err != nil { log.Fatal(err) } for _, post := range ghosts.Data { fmt.Printf("Ghost post %s expires at: %v\n", post.ID, post.GhostPostExpirationTimestamp) } } ``` -------------------------------- ### Create Text Posts with Go Source: https://context7.com/tirthpatell/threads-go/llms.txt Shows how to create text-based posts on Threads, including support for links, polls, GIFs, and topic tags. It utilizes the TextPostContent struct to configure post metadata. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() // Simple text post post, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "Hello Threads from Go!", }) if err != nil { log.Fatal(err) } fmt.Printf("Created post: %s\n", post.Permalink) // Text post with link attachment postWithLink, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "Check out this amazing article", LinkAttachment: "https://example.com/article", }) if err != nil { log.Fatal(err) } fmt.Printf("Post with link: %s\n", postWithLink.ID) // Text post with poll pollPost, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "What's your favorite programming language?", PollAttachment: &threads.PollAttachment{ OptionA: "Go", OptionB: "Python", OptionC: "JavaScript", OptionD: "Rust", }, }) if err != nil { log.Fatal(err) } fmt.Printf("Poll post: %s\n", pollPost.ID) // Text post with GIF (GIPHY) gifPost, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "This is how I feel about Go!", GIFAttachment: &threads.GIFAttachment{ GIFID: "giphy-gif-id-here", Provider: threads.GIFProviderGiphy, }, }) if err != nil { log.Fatal(err) } fmt.Printf("GIF post: %s\n", gifPost.ID) // Text post with topic tag and reply control taggedPost, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "Excited about #golang development!", TopicTag: "golang", ReplyControl: threads.ReplyControlFollowersOnly, }) if err != nil { log.Fatal(err) } fmt.Printf("Tagged post: %s\n", taggedPost.ID) } ``` -------------------------------- ### Get Authenticated User Profile using Threads Go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves the profile information of the currently authenticated user. This function requires valid user authentication credentials. It returns user details such as ID, username, name, biography, profile picture URL, and verification status. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() me, err := client.GetMe(ctx) if err != nil { log.Fatal(err) } fmt.Printf("User ID: %s\n", me.ID) fmt.Printf("Username: %s\n", me.Username) fmt.Printf("Name: %s\n", me.Name) fmt.Printf("Biography: %s\n", me.Biography) fmt.Printf("Profile Picture: %s\n", me.ProfilePicURL) fmt.Printf("Verified: %v\n", me.IsVerified) } ``` -------------------------------- ### Create Video Post with Threads API (Go) Source: https://context7.com/tirthpatell/threads-go/llms.txt Demonstrates how to create a new video post on Threads using the CreateVideoPost method. It requires a valid access token and a publicly accessible video URL. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() post, err := client.CreateVideoPost(ctx, &threads.VideoPostContent{ Text: "Check out this tutorial!", VideoURL: "https://example.com/video.mp4", AltText: "A Go programming tutorial video", }) if err != nil { log.Fatal(err) } fmt.Printf("Created video post: %s\n", post.Permalink) fmt.Printf("Media URL: %s\n", post.MediaURL) } ``` -------------------------------- ### Create Image Posts with Go Source: https://context7.com/tirthpatell/threads-go/llms.txt Demonstrates creating image-based posts on Threads using the ImagePostContent struct. Supports captions, alt text, topic tags, and spoiler flags. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() post, err := client.CreateImagePost(ctx, &threads.ImagePostContent{ Text: "Beautiful sunset!", ImageURL: "https://example.com/sunset.jpg", AltText: "A colorful sunset over the ocean", TopicTag: "photography", }) if err != nil { log.Fatal(err) } fmt.Printf("Created image post: %s\n", post.Permalink) fmt.Printf("Post ID: %s\n", post.ID) // Image post with spoiler spoilerPost, err := client.CreateImagePost(ctx, &threads.ImagePostContent{ Text: "Movie spoiler ahead!", ImageURL: "https://example.com/movie-scene.jpg", IsSpoilerMedia: true, }) if err != nil { log.Fatal(err) } fmt.Printf("Spoiler image post: %s\n", spoilerPost.ID) } ``` -------------------------------- ### Get Posts from Public Profile using Threads Go Source: https://context7.com/tirthpatell/threads-go/llms.txt Retrieves posts from a public profile by username. This function takes the username and optional `PostsOptions` (like `Limit`) as input. It returns a list of posts, displaying their ID and a truncated version of their text content. Ensure the client is authenticated. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() posts, err := client.GetPublicProfilePosts(ctx, "username", &threads.PostsOptions{ Limit: 10, }) if err != nil { log.Fatal(err) } for _, post := range posts.Data { fmt.Printf("Post: %s - %s\n", post.ID, post.Text[:min(50, len(post.Text))]) } } func min(a, b int) int { if a < b { return a } return b } ``` -------------------------------- ### Search Posts by Keyword, Media Type, and Topic Tag in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Demonstrates how to search for posts using the Threads API client in Go. Supports searching by keyword, filtering by media type (image, text, video), and searching by topic tag. Requires an initialized Threads client and context. ```go // Search posts by keyword results, err := client.KeywordSearch(ctx, "golang", &threads.SearchOptions{Limit: 25}) // Search posts filtered by media type imageResults, err := client.KeywordSearch(ctx, "nature", &threads.SearchOptions{ MediaType: threads.MediaTypeImage, // Filter for IMAGE posts only (TEXT, IMAGE, or VIDEO) Limit: 25, }) // Search posts by topic tag tagResults, err := client.KeywordSearch(ctx, "#technology", &threads.SearchOptions{ SearchMode: threads.SearchModeTag, Limit: 25, }) ``` -------------------------------- ### Create and Retrieve Ghost Posts in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Demonstrates how to create auto-expiring 'ghost' posts and retrieve a user's existing ghost posts using the Threads API client in Go. Requires an initialized Threads client and context. ```go // Create a ghost post (auto-expiring) ghost, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "This will disappear!", IsGhostPost: true, }) // Retrieve a user's ghost posts ghosts, err := client.GetUserGhostPosts(ctx, userID, nil) ``` -------------------------------- ### Implement OAuth 2.0 Authentication Flow Source: https://context7.com/tirthpatell/threads-go/llms.txt Covers the process of generating an authorization URL to redirect users and exchanging the resulting authorization code for an access token. It also demonstrates upgrading to a long-lived token. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { config := &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", Scopes: []string{ "threads_basic", "threads_content_publish", "threads_manage_insights", "threads_manage_replies", "threads_read_replies", }, } client, err := threads.NewClient(config) if err != nil { log.Fatal(err) } authURL := client.GetAuthURL(config.Scopes) fmt.Printf("Redirect user to: %s\n", authURL) } ``` ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { config := &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", Scopes: []string{"threads_basic", "threads_content_publish"}, } client, _ := threads.NewClient(config) ctx := context.Background() authCode := "code-from-callback-url" err := client.ExchangeCodeForToken(ctx, authCode) if err != nil { log.Fatal(err) } err = client.GetLongLivedToken(ctx) if err != nil { log.Fatal(err) } tokenInfo := client.GetTokenInfo() fmt.Printf("Token expires at: %v\n", tokenInfo.ExpiresAt) fmt.Printf("User ID: %s\n", tokenInfo.UserID) } ``` -------------------------------- ### POST /CreateQuotePost Source: https://context7.com/tirthpatell/threads-go/llms.txt Creates a quote post that references another post with custom commentary. ```APIDOC ## POST /CreateQuotePost ### Description Creates a quote post that references another post with your own commentary. ### Method POST ### Endpoint CreateQuotePost ### Parameters #### Path Parameters - **original-post-id** (string) - Required - The ID of the post being quoted. ### Request Body - **Text** (string) - Required - Commentary text. - **ImageURL** (string) - Optional - URL for an image to accompany the quote. ### Request Example { "Text": "This is so true!", "ImageURL": "https://example.com/chart.png" } ### Response #### Success Response (200) - **Permalink** (string) - The URL of the quote post. - **ID** (string) - The unique ID of the quote post. #### Response Example { "ID": "quote_123", "Permalink": "https://threads.net/@user/post/quote_123" } ``` -------------------------------- ### Keyword Search Posts by Keyword - Go Source: https://context7.com/tirthpatell/threads-go/llms.txt Searches for public Threads posts by keyword with options for search type (top, recent), search mode (tag), media type, and author username. Requires a client initialized with an access token and configuration. ```go package main import ( "context" "fmt" "log" "github.com/tirthpatell/threads-go" ) func main() { client, _ := threads.NewClientWithToken("your-access-token", &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", }) ctx := context.Background() // Basic keyword search results, err := client.KeywordSearch(ctx, "golang", &threads.SearchOptions{ Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d posts about golang\n", len(results.Data)) // Search for top results (most popular) topResults, err := client.KeywordSearch(ctx, "programming", &threads.SearchOptions{ SearchType: threads.SearchTypeTop, Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d top posts\n", len(topResults.Data)) // Search for recent results recentResults, err := client.KeywordSearch(ctx, "news", &threads.SearchOptions{ SearchType: threads.SearchTypeRecent, Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d recent posts\n", len(recentResults.Data)) // Search by topic tag tagResults, err := client.KeywordSearch(ctx, "#technology", &threads.SearchOptions{ SearchMode: threads.SearchModeTag, Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d posts with #technology tag\n", len(tagResults.Data)) // Search filtered by media type imageResults, err := client.KeywordSearch(ctx, "nature", &threads.SearchOptions{ MediaType: threads.MediaTypeImage, Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d image posts about nature\n", len(imageResults.Data)) // Search by specific author authorResults, err := client.KeywordSearch(ctx, "announcement", &threads.SearchOptions{ AuthorUsername: "username", Limit: 25, }) if err != nil { log.Fatal(err) } fmt.Printf("Found %d posts from @username\n", len(authorResults.Data)) // Print results for _, post := range results.Data { fmt.Printf("@%s: %s\n", post.Username, post.Text) } } ``` -------------------------------- ### Retrieve User and Profile Information Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Methods for fetching authenticated user details and public profile information. ```go // Get user info me, err := client.GetMe(ctx) user, err := client.GetUser(ctx, threads.UserID("123")) // Public profiles publicUser, err := client.LookupPublicProfile(ctx, "@username") posts, err := client.GetPublicProfilePosts(ctx, "username", nil) ``` -------------------------------- ### Threads API Client Configuration in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Shows the basic configuration structure for the Threads API client in Go, including essential fields like client ID, secret, redirect URI, and scopes. Also demonstrates setting HTTP timeout and debug mode. For advanced options, refer to the GoDoc documentation. ```go config := &threads.Config{ ClientID: "your-client-id", ClientSecret: "your-client-secret", RedirectURI: "https://yourapp.com/callback", Scopes: []string{"threads_basic", "threads_content_publish"}, HTTPTimeout: 30 * time.Second, Debug: false, } ``` -------------------------------- ### POST /CreateVideoPost Source: https://context7.com/tirthpatell/threads-go/llms.txt Creates a new video post on Threads by uploading a video URL and associated metadata. ```APIDOC ## POST /CreateVideoPost ### Description Creates a new video post on Threads. The video is uploaded and processed asynchronously. ### Method POST ### Endpoint CreateVideoPost ### Request Body - **Text** (string) - Required - The caption for the video. - **VideoURL** (string) - Required - The URL of the video to be uploaded. - **AltText** (string) - Optional - Accessibility text for the video. ### Request Example { "Text": "Check out this tutorial!", "VideoURL": "https://example.com/video.mp4", "AltText": "A Go programming tutorial video" } ### Response #### Success Response (200) - **Permalink** (string) - The URL of the created post. - **MediaURL** (string) - The URL of the processed media. #### Response Example { "Permalink": "https://threads.net/@user/post/123", "MediaURL": "https://cdn.threads.net/video/123.mp4" } ``` -------------------------------- ### Write Table-Driven Tests in Go Source: https://github.com/tirthpatell/threads-go/blob/main/CONTRIBUTING.md Demonstrates the standard Go testing pattern using table-driven tests to validate client functionality. ```go func TestClient_CreateTextPost(t *testing.T) { tests := []struct { name string content *TextPostContent wantErr bool }{ {"valid post", &TextPostContent{Text: "Hello"}, false}, {"empty text", &TextPostContent{Text: ""}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Test implementation }) } } ``` -------------------------------- ### Create a Post with a GIF Attachment in Go Source: https://github.com/tirthpatell/threads-go/blob/main/README.md Illustrates how to create a text post with a GIF attachment using the GIPHY provider via the Threads API client in Go. Note that Tenor support is deprecated. Requires an initialized Threads client and context. ```go // Create a post with a GIF attachment (GIPHY) gifPost, err := client.CreateTextPost(ctx, &threads.TextPostContent{ Text: "Check out this GIF!", GIFAttachment: &threads.GIFAttachment{ GIFID: "giphy-gif-id", Provider: threads.GIFProviderGiphy, }, }) ```