Skip to content

Unofficial, Reverse-Engineered Golang client for Meta's Threads. Supports Read and Write.

License

Notifications You must be signed in to change notification settings

dwarvesf/go-threads

Repository files navigation

Dwarves Golang Threads API

Dwarves Foundation Dwarves Foundation Discord

Unofficial, Reverse-Engineered Golang client for Meta's Threads. Supports Read and Write.

Getting started

How to install Install the library with the following command using go module:

$ go get github.com/dwarvesf/go-threads

Examples Find examples of how to use the library in the examples folder:

ls examples
├── create_post
│   └── main.go
...

API

Disclaimer

The Threads API is a public API in the library, requiring no authorization. In contrast, the Instagram API, referred to as the private API, requires the Instagram username and password for interaction.

The public API offers read-only endpoints, while the private API provides both read and write endpoints. The private API is generally more stable as Instagram is a reliable product.

Using the public API reduces the risk of rate limits or account suspension. However, there is a trade-off between stability, bugs, rate limits, and suspension. The library allows for combining approaches, such as using the public API for read-only tasks and the private API for write operations. A retry mechanism can also be implemented, attempting the public API first and then falling back to the private API if necessary.

Initialization

To start using the GoThreads package, import the relevant class for communication with the Threads API and create an instance of the object.

For utilizing only the public API, use the following code snippet:

import (
    "github.com/dwarvesf/go-threads"
)

func main() {
    th := threads.NewThreads()
    th.GetThreadLikers(<thread_id>)

    // Using global instance
    threads.GetThreadLikers(<thread_id>)
}

If you intend to use the private API exclusively or both the private and public APIs, utilize the following code snippet:

package main

import (
	"fmt"

	"github.com/dwarvesf/go-threads"
)

func main() {
	cfg, err := threads.InitConfig(
		threads.WithDoLogin("instagram_username", "instagram_password"),
	)
	if err != nil {
		fmt.Println("unable init config", err)
		return
	}

	client, err := threads.NewPrivateAPIClient(cfg)
	if err != nil {
		fmt.Println("unable init API client", err)
		return
	}
}

Or the shorter syntax

package main

import (
	"fmt"

	"github.com/dwarvesf/go-threads"
	"github.com/dwarvesf/go-threads/model"
)

func main() {
	client, err := threads.InitAPIClient(
		threads.WithDoLogin("instagram_username", "instagram_password"),
	)
	if err != nil {
		fmt.Println("unable init API client", err)
		return
	}

	p, err := client.CreatePost(model.CreatePostRequest{Caption: "new post"})
	if err != nil {
		fmt.Println("unable create a post", err)
		return
	}
}

To mitigate the risk of blocking our users, an alternative initialization method can be implemented for the client. This method entails storing the API token and device token, which are subsequently utilized for initializing the API client.

package main

import (
	"fmt"

	"github.com/dwarvesf/go-threads"
	"github.com/dwarvesf/go-threads/model"
)

func main() {
	client, err := threads.InitAPIClient(
		threads.WithCridential("instagram_username", "instagram_password"),
		threads.WithAPIToken("device_id", "api_token"),
	)
	if err != nil {
		fmt.Println("unable init API client", err)
		return
	}

	p, err := client.CreatePost(model.CreatePostRequest{Caption: "new post"})
	if err != nil {
		fmt.Println("unable create a post", err)
		return
	}
}

Public API

Coming soon

Private API

Coming soon

Road map

  • Improve the perfomance
  • Listing API
  • Mutation API