diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 981a1e3..7bca50d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,19 +21,19 @@ jobs:
permissions:
contents: read
id-token: write
- runs-on: ${{ github.repository == 'stainless-sdks/post-for-me-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: |-
github.repository == 'stainless-sdks/post-for-me-go' &&
(github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Get GitHub OIDC Token
if: |-
github.repository == 'stainless-sdks/post-for-me-go' &&
!startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
- uses: actions/github-script@v8
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: core.setOutput('github_token', await core.getIDToken());
@@ -49,14 +49,14 @@ jobs:
lint:
timeout-minutes: 10
name: lint
- runs-on: ${{ github.repository == 'stainless-sdks/post-for-me-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup go
- uses: actions/setup-go@v5
+ uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: ./go.mod
@@ -65,13 +65,13 @@ jobs:
test:
timeout-minutes: 10
name: test
- runs-on: ${{ github.repository == 'stainless-sdks/post-for-me-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
+ runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Setup go
- uses: actions/setup-go@v5
+ uses: actions/setup-go@40f1582b2485089dde7abd97c1529aa768e1baff # v5.6.0
with:
go-version-file: ./go.mod
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index b386bef..fac1407 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.1.0-alpha.19"
+ ".": "0.1.0-alpha.20"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index 0a2314b..aedb62a 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 15
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/day-moon-development%2Fpost-for-me-d7bde21e6d3328e90ec781ff8e2629faeaae4bb5d8e0d350703326ec8aadf898.yml
-openapi_spec_hash: dcb2130480c4476fe08fcb080e369ce0
-config_hash: 0ec19602e41aea0526548245a59d4253
+configured_endpoints: 21
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/day-moon-development/post-for-me-04c0892827f2117f5c5f9695f01c32a90d82cbde12dbb395eaabe2ccee11fee0.yml
+openapi_spec_hash: 150dc8541a9a47afe9154eac3c8caa6d
+config_hash: 600d71be044aa28b6759ce7f55a86948
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 225535d..acc4b70 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,38 @@
# Changelog
+## 0.1.0-alpha.20 (2026-07-29)
+
+Full Changelog: [v0.1.0-alpha.19...v0.1.0-alpha.20](https://github.com/DayMoonDevelopment/post-for-me-go/compare/v0.1.0-alpha.19...v0.1.0-alpha.20)
+
+### Features
+
+* **api:** api update ([de55563](https://github.com/DayMoonDevelopment/post-for-me-go/commit/de5556350c3e468a0b1985c65d48e686811d45ef))
+* **api:** api update ([8ad0cf9](https://github.com/DayMoonDevelopment/post-for-me-go/commit/8ad0cf93b836982f56460a2f324bd9016cf6d57b))
+* **api:** api update ([595c7bd](https://github.com/DayMoonDevelopment/post-for-me-go/commit/595c7bd43f66ef41185419117b4d9acffe407a52))
+* **api:** api update ([5d6118a](https://github.com/DayMoonDevelopment/post-for-me-go/commit/5d6118a831eca768a8c85c04923fea174334dc26))
+* **api:** api update ([b336f84](https://github.com/DayMoonDevelopment/post-for-me-go/commit/b336f84678fa224fe754fd26e77435296dbac9a0))
+* **api:** api update ([c187a30](https://github.com/DayMoonDevelopment/post-for-me-go/commit/c187a30062131aeb2e0958259c4d5cac0e4a23ce))
+* **api:** api update ([e77c224](https://github.com/DayMoonDevelopment/post-for-me-go/commit/e77c22405255fd52a77decb1b57fe44536fa99ce))
+* **api:** api update ([54e435e](https://github.com/DayMoonDevelopment/post-for-me-go/commit/54e435e71a49af71d03b3b9c1081af90932868a5))
+* **api:** api update ([4b69dac](https://github.com/DayMoonDevelopment/post-for-me-go/commit/4b69daca7ab31f9323d2386e8c4f1f77dce2c8cb))
+* **api:** manual updates ([904cdd6](https://github.com/DayMoonDevelopment/post-for-me-go/commit/904cdd684a5a5ad7cd08e3e311a951242b805028))
+* **client:** optimize json encoder for internal types ([aec710d](https://github.com/DayMoonDevelopment/post-for-me-go/commit/aec710d5660db9fceeb7e13ffc5af30bd5427ae5))
+* **go:** add default http client with timeout ([2a04edf](https://github.com/DayMoonDevelopment/post-for-me-go/commit/2a04edfa9f61585467e6bc9e68fe89cd7dabe81d))
+* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([d5c3148](https://github.com/DayMoonDevelopment/post-for-me-go/commit/d5c31487694adfc71f1f53a87f4ef814dba2fd3c))
+* support setting headers via env ([d4a370c](https://github.com/DayMoonDevelopment/post-for-me-go/commit/d4a370c0c7b918de89fbd80aa63449c1cae37484))
+
+
+### Bug Fixes
+
+* **go:** avoid panic when http.DefaultTransport is wrapped ([67d16a2](https://github.com/DayMoonDevelopment/post-for-me-go/commit/67d16a2f154e64315c1e296c3bb881f6ce55b230))
+
+
+### Chores
+
+* avoid embedding reflect.Type for dead code elimination ([60bf831](https://github.com/DayMoonDevelopment/post-for-me-go/commit/60bf8313819046eeac502a21c45d69a278b9efb2))
+* **internal:** more robust bootstrap script ([d1d617b](https://github.com/DayMoonDevelopment/post-for-me-go/commit/d1d617ba64baefa88888fc8d77903dc9423c6031))
+* redact api-key headers in debug logs ([9c501f0](https://github.com/DayMoonDevelopment/post-for-me-go/commit/9c501f0b91e12b1bd1ccdda00b0caca913f2bccf))
+
## 0.1.0-alpha.19 (2026-04-11)
Full Changelog: [v0.1.0-alpha.18...v0.1.0-alpha.19](https://github.com/DayMoonDevelopment/post-for-me-go/compare/v0.1.0-alpha.18...v0.1.0-alpha.19)
diff --git a/README.md b/README.md
index fa819f6..0d59786 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@ Or to pin the version:
```sh
-go get -u 'github.com/DayMoonDevelopment/post-for-me-go@v0.1.0-alpha.19'
+go get -u 'github.com/DayMoonDevelopment/post-for-me-go@v0.1.0-alpha.20'
```
diff --git a/api.md b/api.md
index 4609d54..57570ca 100644
--- a/api.md
+++ b/api.md
@@ -12,6 +12,7 @@ Methods:
Params Types:
+- postforme.AccountConfigurationParam
- postforme.BlueskyConfigurationDtoParam
- postforme.CreateSocialPostParam
- postforme.FacebookConfigurationDtoParam
@@ -19,26 +20,31 @@ Params Types:
- postforme.LinkedinConfigurationDtoParam
- postforme.PinterestConfigurationDtoParam
- postforme.PlatformConfigurationsDtoParam
+- postforme.SocialPostMediaParam
- postforme.ThreadsConfigurationDtoParam
- postforme.TiktokConfigurationParam
- postforme.TwitterConfigurationDtoParam
+- postforme.TwitterPollParam
- postforme.YoutubeConfigurationDtoParam
Response Types:
+- postforme.AccountConfiguration
- postforme.BlueskyConfigurationDto
+- postforme.DeleteEntityResponse
- postforme.FacebookConfigurationDto
- postforme.InstagramConfigurationDto
- postforme.LinkedinConfigurationDto
- postforme.PinterestConfigurationDto
- postforme.PlatformConfigurationsDto
- postforme.SocialPost
+- postforme.SocialPostMedia
- postforme.ThreadsConfigurationDto
- postforme.TiktokConfiguration
- postforme.TwitterConfigurationDto
+- postforme.TwitterPoll
- postforme.YoutubeConfigurationDto
- postforme.SocialPostListResponse
-- postforme.SocialPostDeleteResponse
Methods:
@@ -46,7 +52,7 @@ Methods:
- client.SocialPosts.Get(ctx context.Context, id string) (\*postforme.SocialPost, error)
- client.SocialPosts.Update(ctx context.Context, id string, body postforme.SocialPostUpdateParams) (\*postforme.SocialPost, error)
- client.SocialPosts.List(ctx context.Context, query postforme.SocialPostListParams) (\*postforme.SocialPostListResponse, error)
-- client.SocialPosts.Delete(ctx context.Context, id string) (\*postforme.SocialPostDeleteResponse, error)
+- client.SocialPosts.Delete(ctx context.Context, id string) (\*postforme.DeleteEntityResponse, error)
# SocialPostResults
@@ -62,9 +68,14 @@ Methods:
# SocialAccounts
+Params Types:
+
+- postforme.SocialAccountMetadata
+
Response Types:
- postforme.SocialAccount
+- postforme.SocialAccountMetadata
- postforme.SocialAccountListResponse
- postforme.SocialAccountNewAuthURLResponse
- postforme.SocialAccountDisconnectResponse
@@ -82,9 +93,44 @@ Methods:
Response Types:
+- postforme.FacebookActivityByActionType
+- postforme.FacebookVideoRetentionGraph
+- postforme.FacebookVideoViewTimeByDemographic
+- postforme.PinterestMetricsWindow
- postforme.PlatformPost
+- postforme.TiktokBusinessVideoMetricPercentage
+- postforme.YoutubePostPlatformData
- postforme.SocialAccountFeedListResponse
Methods:
- client.SocialAccountFeeds.List(ctx context.Context, socialAccountID string, query postforme.SocialAccountFeedListParams) (\*postforme.SocialAccountFeedListResponse, error)
+
+# Webhooks
+
+Response Types:
+
+- postforme.Webhook
+- postforme.WebhookListResponse
+
+Methods:
+
+- client.Webhooks.New(ctx context.Context, body postforme.WebhookNewParams) (\*postforme.Webhook, error)
+- client.Webhooks.Get(ctx context.Context, id string) (\*postforme.Webhook, error)
+- client.Webhooks.Update(ctx context.Context, id string, body postforme.WebhookUpdateParams) (\*postforme.Webhook, error)
+- client.Webhooks.List(ctx context.Context, query postforme.WebhookListParams) (\*postforme.WebhookListResponse, error)
+- client.Webhooks.Delete(ctx context.Context, id string) (\*postforme.DeleteEntityResponse, error)
+
+# SocialPostPreviews
+
+Params Types:
+
+- postforme.CreateSocialPostPreviewParam
+
+Response Types:
+
+- postforme.SocialPostPreview
+
+Methods:
+
+- client.SocialPostPreviews.New(ctx context.Context, body postforme.SocialPostPreviewNewParams) (\*[]postforme.SocialPostPreview, error)
diff --git a/client.go b/client.go
index 84bd8dc..8c008fa 100644
--- a/client.go
+++ b/client.go
@@ -7,6 +7,7 @@ import (
"net/http"
"os"
"slices"
+ "strings"
"github.com/DayMoonDevelopment/post-for-me-go/internal/requestconfig"
"github.com/DayMoonDevelopment/post-for-me-go/option"
@@ -60,6 +61,9 @@ type Client struct {
// - Post information including caption, url, media, etc..
// - When passing **expand=metrics**, Metrics information including views, likes,
// follows, etc..
+ // - For **Facebook** feeds with **expand=metrics**, page size is capped by the
+ // server-side **FacebookFeedMetricsLimitCap** setting (default: **10**) to
+ // protect API memory usage.
//
// Note: Currently the following platforms are supported:
//
@@ -77,18 +81,61 @@ type Client struct {
// currently stopped giving permission for personal page analytics, we are on the
// waitlist for when they resume.
SocialAccountFeeds SocialAccountFeedService
+ // Webhooks enable you to subscribe to certain events. This involves Post for Me
+ // making a POST request to the URL of any webhooks you create. Only the events you
+ // subscribe to will be sent to your webhook URL.
+ //
+ // ## Payload
+ //
+ // When an event happens that your webhook is subscribed to, we will make a POST
+ // request with the following JSON body
+ //
+ // ```
+ //
+ // {
+ // "event_type": "",
+ // "data": {}
+ // }
+ //
+ // ```
+ //
+ // The event_type will be the event that triggered the webhook POST, data will be
+ // the resulting entity from the event
+ //
+ // ## Security
+ //
+ // To verify the POST to your webhook URL is from us we will include a secret in
+ // the header "Post-For-Me-Webhook-Secret". When you create a webhook you will
+ // receive the secret in the response.
+ //
+ // ## Retries
+ //
+ // If your server fails to respond with a 2XX code, requests to it will be retried
+ // with exponential backoff around 8 times over the course of just over a day.
+ Webhooks WebhookService
+ // Social Post Previews allow you to see what a Social Post will create for each
+ // account in the post.
+ SocialPostPreviews SocialPostPreviewService
}
// DefaultClientOptions read from the environment (POST_FOR_ME_API_KEY,
// POST_FOR_ME_BASE_URL). This should be used to initialize new clients.
func DefaultClientOptions() []option.RequestOption {
- defaults := []option.RequestOption{option.WithEnvironmentProduction()}
+ defaults := []option.RequestOption{option.WithHTTPClient(defaultHTTPClient()), option.WithEnvironmentProduction()}
if o, ok := os.LookupEnv("POST_FOR_ME_BASE_URL"); ok {
defaults = append(defaults, option.WithBaseURL(o))
}
if o, ok := os.LookupEnv("POST_FOR_ME_API_KEY"); ok {
defaults = append(defaults, option.WithAPIKey(o))
}
+ if o, ok := os.LookupEnv("POST_FOR_ME_CUSTOM_HEADERS"); ok {
+ for _, line := range strings.Split(o, "\n") {
+ colon := strings.Index(line, ":")
+ if colon >= 0 {
+ defaults = append(defaults, option.WithHeader(strings.TrimSpace(line[:colon]), strings.TrimSpace(line[colon+1:])))
+ }
+ }
+ }
return defaults
}
@@ -106,6 +153,8 @@ func NewClient(opts ...option.RequestOption) (r Client) {
r.SocialPostResults = NewSocialPostResultService(opts...)
r.SocialAccounts = NewSocialAccountService(opts...)
r.SocialAccountFeeds = NewSocialAccountFeedService(opts...)
+ r.Webhooks = NewWebhookService(opts...)
+ r.SocialPostPreviews = NewSocialPostPreviewService(opts...)
return
}
diff --git a/default_http_client.go b/default_http_client.go
new file mode 100644
index 0000000..14420df
--- /dev/null
+++ b/default_http_client.go
@@ -0,0 +1,30 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package postforme
+
+import (
+ "net/http"
+ "time"
+)
+
+// defaultResponseHeaderTimeout bounds the time between a fully written request
+// and the server's response headers. It does not apply to the response body,
+// so long-running streams are unaffected. Without this, a server that accepts
+// the connection but never responds would hang the request indefinitely.
+const defaultResponseHeaderTimeout = 10 * time.Minute
+
+// defaultHTTPClient returns an [*http.Client] used when the caller does not
+// supply one via [option.WithHTTPClient]. When [http.DefaultTransport] is the
+// stdlib [*http.Transport], it is cloned and a [http.Transport.ResponseHeaderTimeout]
+// is set so stuck connections fail fast instead of compounding across retries.
+// If [http.DefaultTransport] has been wrapped (for example by otelhttp for
+// distributed tracing), the wrapping is preserved and the header timeout is
+// skipped.
+func defaultHTTPClient() *http.Client {
+ if t, ok := http.DefaultTransport.(*http.Transport); ok {
+ t = t.Clone()
+ t.ResponseHeaderTimeout = defaultResponseHeaderTimeout
+ return &http.Client{Transport: t}
+ }
+ return &http.Client{Transport: http.DefaultTransport}
+}
diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go
index 51db3dd..e47e87a 100644
--- a/internal/apiform/encoder.go
+++ b/internal/apiform/encoder.go
@@ -58,7 +58,7 @@ type encoderField struct {
}
type encoderEntry struct {
- reflect.Type
+ typ reflect.Type
dateFormat string
arrayFmt string
root bool
@@ -76,7 +76,7 @@ func (e *encoder) marshal(value any, writer *multipart.Writer) error {
func (e *encoder) typeEncoder(t reflect.Type) encoderFunc {
entry := encoderEntry{
- Type: t,
+ typ: t,
dateFormat: e.dateFormat,
arrayFmt: e.arrayFmt,
root: e.root,
diff --git a/internal/apijson/decoder.go b/internal/apijson/decoder.go
index c8bd684..17b6fdf 100644
--- a/internal/apijson/decoder.go
+++ b/internal/apijson/decoder.go
@@ -80,7 +80,7 @@ type decoderField struct {
}
type decoderEntry struct {
- reflect.Type
+ typ reflect.Type
dateFormat string
root bool
}
@@ -108,7 +108,7 @@ func (d *decoderBuilder) unmarshalWithExactness(raw []byte, to any) (exactness,
func (d *decoderBuilder) typeDecoder(t reflect.Type) decoderFunc {
entry := decoderEntry{
- Type: t,
+ typ: t,
dateFormat: d.dateFormat,
root: d.root,
}
diff --git a/internal/apijson/encoder.go b/internal/apijson/encoder.go
index f3d6f2c..fc903de 100644
--- a/internal/apijson/encoder.go
+++ b/internal/apijson/encoder.go
@@ -46,7 +46,7 @@ type encoderField struct {
}
type encoderEntry struct {
- reflect.Type
+ typ reflect.Type
dateFormat string
root bool
}
@@ -63,7 +63,7 @@ func (e *encoder) marshal(value any) ([]byte, error) {
func (e *encoder) typeEncoder(t reflect.Type) encoderFunc {
entry := encoderEntry{
- Type: t,
+ typ: t,
dateFormat: e.dateFormat,
root: e.root,
}
diff --git a/internal/apiquery/encoder.go b/internal/apiquery/encoder.go
index 9a2627a..0388a42 100644
--- a/internal/apiquery/encoder.go
+++ b/internal/apiquery/encoder.go
@@ -29,7 +29,7 @@ type encoderField struct {
}
type encoderEntry struct {
- reflect.Type
+ typ reflect.Type
dateFormat string
root bool
settings QuerySettings
@@ -42,7 +42,7 @@ type Pair struct {
func (e *encoder) typeEncoder(t reflect.Type) encoderFunc {
entry := encoderEntry{
- Type: t,
+ typ: t,
dateFormat: e.dateFormat,
root: e.root,
settings: e.settings,
diff --git a/internal/encoding/json/encode.go b/internal/encoding/json/encode.go
index 12a3f8a..28a681a 100644
--- a/internal/encoding/json/encode.go
+++ b/internal/encoding/json/encode.go
@@ -173,15 +173,21 @@ import (
// JSON cannot represent cyclic data structures and Marshal does not
// handle them. Passing cyclic structures to Marshal will result in
// an error.
-func Marshal(v any) ([]byte, error) {
+// EDIT(begin): add optimization options
+func Marshal(v any, opts ...Option) ([]byte, error) {
+ // EDIT(end): add optimization options
e := newEncodeState()
defer encodeStatePool.Put(e)
- // SHIM(begin): don't escape HTML by default
- err := e.marshal(v, encOpts{escapeHTML: shims.EscapeHTMLByDefault})
+ // EDIT(begin): don't escape HTML by default, and apply options
+ encOpts := encOpts{escapeHTML: shims.EscapeHTMLByDefault}
+ if opts != nil {
+ encOpts = encOpts.apply(opts...)
+ }
+ err := e.marshal(v, encOpts)
// ORIGINAL:
// err := e.marshal(v, encOpts{escapeHTML: true})
- // SHIM(end)
+ // EDIT(end)
if err != nil {
return nil, err
}
@@ -352,6 +358,9 @@ type encOpts struct {
// EDIT(begin): save the timefmt
timefmt string
// EDIT(end)
+ // EDIT(begin): add optimization to skip compaction
+ skipCompaction bool
+ // EDIT(end)
}
type encoderFunc func(e *encodeState, v reflect.Value, opts encOpts)
@@ -483,7 +492,7 @@ func marshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
if err == nil {
e.Grow(len(b))
out := e.AvailableBuffer()
- out, err = appendCompact(out, b, opts.escapeHTML)
+ out, err = appendCompact(out, b, opts)
e.Buffer.Write(out)
}
if err != nil {
@@ -509,7 +518,7 @@ func addrMarshalerEncoder(e *encodeState, v reflect.Value, opts encOpts) {
if err == nil {
e.Grow(len(b))
out := e.AvailableBuffer()
- out, err = appendCompact(out, b, opts.escapeHTML)
+ out, err = appendCompact(out, b, opts)
e.Buffer.Write(out)
}
if err != nil {
diff --git a/internal/encoding/json/indent.go b/internal/encoding/json/indent.go
index 01bfdf6..c9d6ca5 100644
--- a/internal/encoding/json/indent.go
+++ b/internal/encoding/json/indent.go
@@ -4,7 +4,9 @@
package json
-import "bytes"
+import (
+ "bytes"
+)
// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029
// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029
@@ -41,12 +43,21 @@ func appendHTMLEscape(dst, src []byte) []byte {
func Compact(dst *bytes.Buffer, src []byte) error {
dst.Grow(len(src))
b := dst.AvailableBuffer()
- b, err := appendCompact(b, src, false)
+ b, err := appendCompact(b, src, encOpts{})
dst.Write(b)
return err
}
-func appendCompact(dst, src []byte, escape bool) ([]byte, error) {
+func appendCompact(dst, src []byte, opts encOpts) ([]byte, error) {
+ // EDIT(begin): optimize for skipCompaction
+ if opts.skipCompaction {
+ dst = append(dst, src...)
+ return dst, nil
+ }
+
+ escape := opts.escapeHTML
+ // EDIT(end)
+
origLen := len(dst)
scan := newScanner()
defer freeScanner(scan)
diff --git a/internal/encoding/json/opt.go b/internal/encoding/json/opt.go
new file mode 100644
index 0000000..fd6f8d2
--- /dev/null
+++ b/internal/encoding/json/opt.go
@@ -0,0 +1,24 @@
+// EDIT(begin): add custom options for JSON encoding
+package json
+
+type Option func(*encOpts)
+
+// Every time a sub-type of [json.Marshaler] is encountered,
+// skip a redundant and costly compaction step, trust it to self-compact.
+//
+// This is a divergence from the standard library behavior, and is only guaranteed
+// safe with SDK types.
+func WithSkipCompaction(b bool) Option {
+ return func(eos *encOpts) {
+ eos.skipCompaction = true
+ }
+}
+
+func (eos encOpts) apply(opts ...Option) encOpts {
+ for _, opt := range opts {
+ opt(&eos)
+ }
+ return eos
+}
+
+// EDIT(end)
diff --git a/internal/encoding/json/stream.go b/internal/encoding/json/stream.go
index e2d9470..652522c 100644
--- a/internal/encoding/json/stream.go
+++ b/internal/encoding/json/stream.go
@@ -6,7 +6,6 @@ package json
import (
"bytes"
- "errors"
"io"
)
@@ -253,30 +252,34 @@ func (enc *Encoder) SetEscapeHTML(on bool) {
enc.escapeHTML = on
}
-// RawMessage is a raw encoded JSON value.
-// It implements [Marshaler] and [Unmarshaler] and can
-// be used to delay JSON decoding or precompute a JSON encoding.
-type RawMessage []byte
-
-// MarshalJSON returns m as the JSON encoding of m.
-func (m RawMessage) MarshalJSON() ([]byte, error) {
- if m == nil {
- return []byte("null"), nil
- }
- return m, nil
-}
-
-// UnmarshalJSON sets *m to a copy of data.
-func (m *RawMessage) UnmarshalJSON(data []byte) error {
- if m == nil {
- return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
- }
- *m = append((*m)[0:0], data...)
- return nil
-}
-
-var _ Marshaler = (*RawMessage)(nil)
-var _ Unmarshaler = (*RawMessage)(nil)
+// EDIT(begin): remove RawMessage
+//
+// // RawMessage is a raw encoded JSON value.
+// // It implements [Marshaler] and [Unmarshaler] and can
+// // be used to delay JSON decoding or precompute a JSON encoding.
+// type RawMessage []byte
+//
+// // MarshalJSON returns m as the JSON encoding of m.
+// func (m RawMessage) MarshalJSON() ([]byte, error) {
+// if m == nil {
+// return []byte("null"), nil
+// }
+// return m, nil
+// }
+//
+// // UnmarshalJSON sets *m to a copy of data.
+// func (m *RawMessage) UnmarshalJSON(data []byte) error {
+// if m == nil {
+// return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
+// }
+// *m = append((*m)[0:0], data...)
+// return nil
+// }
+//
+// var _ Marshaler = (*RawMessage)(nil)
+// var _ Unmarshaler = (*RawMessage)(nil)
+//
+// EDIT(end)
// A Token holds a value of one of these types:
//
diff --git a/internal/encoding/json/time.go b/internal/encoding/json/time.go
index e20ee3e..6e08962 100644
--- a/internal/encoding/json/time.go
+++ b/internal/encoding/json/time.go
@@ -50,7 +50,7 @@ func timeMarshalEncoder(e *encodeState, v reflect.Value, opts encOpts) bool {
if b != nil {
e.Grow(len(b))
out := e.AvailableBuffer()
- out, _ = appendCompact(out, b, opts.escapeHTML)
+ out, _ = appendCompact(out, b, opts)
e.Buffer.Write(out)
return true
}
diff --git a/internal/version.go b/internal/version.go
index 296d72b..985cfb5 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.1.0-alpha.19" // x-release-please-version
+const PackageVersion = "0.1.0-alpha.20" // x-release-please-version
diff --git a/option/middleware.go b/option/middleware.go
index 8ec9dd6..4be0987 100644
--- a/option/middleware.go
+++ b/option/middleware.go
@@ -8,6 +8,10 @@ import (
"net/http/httputil"
)
+// sensitiveLogHeaders are redacted before request and response content is
+// written to the debug logger.
+var sensitiveLogHeaders = []string{"authorization", "api-key", "x-api-key", "cookie", "set-cookie"}
+
// WithDebugLog logs the HTTP request and response content.
// If the logger parameter is nil, it uses the default logger.
//
@@ -20,7 +24,7 @@ func WithDebugLog(logger *log.Logger) RequestOption {
logger = log.Default()
}
- if reqBytes, err := httputil.DumpRequest(req, true); err == nil {
+ if reqBytes, err := dumpRedactedRequest(req); err == nil {
logger.Printf("Request Content:\n%s\n", reqBytes)
}
@@ -29,10 +33,48 @@ func WithDebugLog(logger *log.Logger) RequestOption {
return resp, err
}
- if respBytes, err := httputil.DumpResponse(resp, true); err == nil {
+ if respBytes, err := dumpRedactedResponse(resp); err == nil {
logger.Printf("Response Content:\n%s\n", respBytes)
}
return resp, err
})
}
+
+// dumpRedactedRequest dumps req with sensitive headers replaced. The
+// original headers are restored via defer so a panic in DumpRequest cannot
+// leak the placeholder map into the live request sent downstream.
+func dumpRedactedRequest(req *http.Request) ([]byte, error) {
+ origHeaders := req.Header
+ req.Header = redactDebugHeaders(origHeaders)
+ defer func() { req.Header = origHeaders }()
+ return httputil.DumpRequest(req, true)
+}
+
+func dumpRedactedResponse(resp *http.Response) ([]byte, error) {
+ origHeaders := resp.Header
+ resp.Header = redactDebugHeaders(origHeaders)
+ defer func() { resp.Header = origHeaders }()
+ return httputil.DumpResponse(resp, true)
+}
+
+func redactDebugHeaders(headers http.Header) http.Header {
+ var redacted http.Header
+ for _, name := range sensitiveLogHeaders {
+ values := headers.Values(name)
+ if len(values) == 0 {
+ continue
+ }
+ if redacted == nil {
+ redacted = headers.Clone()
+ }
+ redacted.Del(name)
+ for range values {
+ redacted.Add(name, "***")
+ }
+ }
+ if redacted == nil {
+ return headers
+ }
+ return redacted
+}
diff --git a/packages/param/encoder.go b/packages/param/encoder.go
index 54af2cd..f879b4b 100644
--- a/packages/param/encoder.go
+++ b/packages/param/encoder.go
@@ -66,7 +66,7 @@ func MarshalWithExtras[T ParamStruct, R any](f T, underlying any, extras map[str
} else if ovr, ok := f.Overrides(); ok {
return shimjson.Marshal(ovr)
} else {
- return shimjson.Marshal(underlying)
+ return shimjson.Marshal(underlying, shimjson.WithSkipCompaction(true))
}
}
@@ -96,7 +96,7 @@ func MarshalUnion[T ParamStruct](metadata T, variants ...any) ([]byte, error) {
Err: fmt.Errorf("expected union to have only one present variant, got %d", nPresent),
}
}
- return shimjson.Marshal(variants[presentIdx])
+ return shimjson.Marshal(variants[presentIdx], shimjson.WithSkipCompaction(true))
}
// typeFor is shimmed from Go 1.23 "reflect" package
diff --git a/packages/param/encoder_test.go b/packages/param/encoder_test.go
index 6355b02..94516e9 100644
--- a/packages/param/encoder_test.go
+++ b/packages/param/encoder_test.go
@@ -1,10 +1,13 @@
package param_test
import (
+ "bytes"
"encoding/json"
+ "reflect"
"testing"
"time"
+ shimjson "github.com/DayMoonDevelopment/post-for-me-go/internal/encoding/json"
"github.com/DayMoonDevelopment/post-for-me-go/packages/param"
)
@@ -375,3 +378,176 @@ func TestNullStructUnion(t *testing.T) {
t.Fatalf("expected null, received %s", string(b))
}
}
+
+//
+// Compaction optimization
+//
+
+type NonCompactedDoubleParent struct {
+ Prop string `json:"prop"`
+ Parent NonCompactedParent `json:"parent"`
+
+ param.APIObject
+}
+
+type NonCompactedParent struct {
+ BadChild NonCompacted `json:"bad_child"`
+
+ param.APIObject
+}
+
+type NonCompacted struct {
+ Raw string
+
+ param.APIObject
+}
+
+func (a NonCompactedDoubleParent) MarshalJSON() ([]byte, error) {
+ type shadow NonCompactedDoubleParent
+ return param.MarshalObject(a, (*shadow)(&a))
+}
+
+func (a NonCompactedParent) MarshalJSON() ([]byte, error) {
+ type shadow NonCompactedParent
+ return param.MarshalObject(a, (*shadow)(&a))
+}
+
+func (a NonCompacted) MarshalJSON() ([]byte, error) {
+ if a.Raw == "" {
+ a.Raw = nonCompactedRaw
+ }
+ return []byte(a.Raw), nil
+}
+
+var nonCompactedRaw string = ` { "foo": "bar" } `
+
+func TestAppendCompactBroken(t *testing.T) {
+ tests := map[string]struct {
+ value json.Marshaler
+ }{
+ "red/illegal-json": {
+ NonCompacted{Raw: `{ "broken": "json" `},
+ },
+ "red/nested-with-illegal-json": {
+ NonCompactedParent{BadChild: NonCompacted{
+ Raw: `{ "broken": "json" `,
+ }},
+ },
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ v, err := json.Marshal(test.value)
+ if err == nil {
+ t.Fatal("expected error got", v)
+ }
+ })
+ }
+}
+
+// TestAppendCompact validates an optimization for internal SDK types to
+// avoid O(keys^2) iteration over each JSON object.
+//
+// It's possible to intentionally trigger this behavior as both a user and
+// SDK developer. However, the edge case is quite pathological and requires
+// calling [json.Marshaler.MarshalJSON] rather than [json.Marshal].
+func TestAppendCompact(t *testing.T) {
+
+ tests := map[string]struct {
+ value json.Marshaler
+ expected string
+ }{
+ //
+ // Non-compacted cases
+ //
+ // Note this is how to exploit the compacter to fail, you must call [json.Marshaler.MarshalJSON] rather than [json.Marshal].
+ // The type must also embed [param.APIObject] and return non-compacted JSON.
+ //
+
+ "no-compact/fails-compaction": {
+ NonCompacted{Raw: nonCompactedRaw},
+ nonCompactedRaw,
+ },
+ "no-compact/nested-with-bad-child": {
+ NonCompactedParent{BadChild: NonCompacted{
+ Raw: nonCompactedRaw,
+ }},
+ `{"bad_child":` + nonCompactedRaw + `}`,
+ },
+ "no-compact/double-nested-with-bad-child": {
+ NonCompactedDoubleParent{Prop: "1", Parent: NonCompactedParent{BadChild: NonCompacted{
+ Raw: nonCompactedRaw,
+ }}},
+ `{"prop":"1","parent":{"bad_child":` + nonCompactedRaw + `}}`,
+ },
+
+ //
+ // Compacted cases
+ //
+
+ "override/spaces-within": {
+ param.Override[NonCompactedDoubleParent](json.RawMessage(`{"com": "pact"}`)),
+ `{"com":"pact"}`,
+ },
+ "override/spaces-after": {
+ param.Override[NonCompactedDoubleParent](json.RawMessage(`{"com":"pact"} `)),
+ `{"com":"pact"}`,
+ },
+ "override/spaces-before": {
+ param.Override[NonCompactedDoubleParent](json.RawMessage(` {"com":"pact"}`)),
+ `{"com":"pact"}`,
+ },
+ "override/spaces-around": {
+ param.Override[NonCompactedDoubleParent](json.RawMessage(` { "com": "pact" }`)),
+ `{"com":"pact"}`,
+ },
+ "override/override-with-nested": {
+ param.Override[NonCompactedDoubleParent](NonCompactedParent{}),
+ `{"bad_child":{"foo":"bar"}}`,
+ },
+ "override/override-with-non-compacted": {
+ param.Override[NonCompactedDoubleParent](NonCompacted{}),
+ `{"foo":"bar"}`,
+ },
+ }
+
+ for name, test := range tests {
+ t.Run(name+"/marshal-json", func(t *testing.T) {
+ b, err := test.value.MarshalJSON()
+ if err != nil {
+ t.Fatalf("didn't expect error %v, expected %s", err, test.expected)
+ }
+ if string(b) != test.expected {
+ t.Fatalf("expected %s (%s), received %s", test.expected, reflect.TypeOf(test.value), string(b))
+ }
+ })
+
+ t.Run(name+"/json-marshal", func(t *testing.T) {
+ b, err := json.Marshal(test.value)
+ if err != nil {
+ t.Fatalf("didn't expect error %v, expected %s", err, test.expected)
+ }
+
+ // expected output of JSON Marshal should always be compacted
+ var compactedExpected bytes.Buffer
+ err = json.Compact(&compactedExpected, []byte(test.expected))
+ if err != nil {
+ t.Fatalf("didn't expect error %v, expected %s", err, test.expected)
+ }
+
+ if string(b) != compactedExpected.String() {
+ t.Fatalf("expected %s (%s), received %s", test.expected, reflect.TypeOf(test.value), string(b))
+ }
+ })
+
+ t.Run(name+"/shimjson-marshal", func(t *testing.T) {
+ b, err := shimjson.Marshal(test.value)
+ if err != nil {
+ t.Fatalf("didn't expect error %v, expected %s", err, test.expected)
+ }
+ if string(b) != test.expected {
+ t.Logf("expected %s (%s), received %s", test.expected, reflect.TypeOf(test.value), string(b))
+ }
+ })
+ }
+}
diff --git a/scripts/bootstrap b/scripts/bootstrap
index 5ab3066..46547f1 100755
--- a/scripts/bootstrap
+++ b/scripts/bootstrap
@@ -4,7 +4,7 @@ set -e
cd "$(dirname "$0")/.."
-if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then
+if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then
brew bundle check >/dev/null 2>&1 || {
echo -n "==> Install Homebrew dependencies? (y/N): "
read -r response
diff --git a/socialaccount.go b/socialaccount.go
index 33fc13f..0fcd313 100644
--- a/socialaccount.go
+++ b/socialaccount.go
@@ -87,7 +87,11 @@ func (r *SocialAccountService) List(ctx context.Context, query SocialAccountList
// Generates a URL that initiates the authentication flow for a user's social media
// account. When visited, the user is redirected to the selected social platform's
// login/authorization page. Upon successful authentication, they are redirected
-// back to your application
+// back to your application.
+//
+// For Quickstart projects using Post for Me system credentials,
+// `redirect_url_override` is not accepted. Configure the project redirect URL in
+// the dashboard instead.
func (r *SocialAccountService) NewAuthURL(ctx context.Context, body SocialAccountNewAuthURLParams, opts ...option.RequestOption) (res *SocialAccountNewAuthURLResponse, err error) {
opts = slices.Concat(r.Options, opts)
path := "v1/social-accounts/auth-url"
@@ -119,7 +123,7 @@ type SocialAccount struct {
// The external id of the social account
ExternalID string `json:"external_id" api:"required"`
// The metadata of the social account
- Metadata any `json:"metadata" api:"required"`
+ Metadata SocialAccountMetadata `json:"metadata" api:"required"`
// The platform of the social account
Platform string `json:"platform" api:"required"`
// The platform's profile photo of the social account
@@ -169,6 +173,8 @@ const (
SocialAccountStatusDisconnected SocialAccountStatus = "disconnected"
)
+type SocialAccountMetadata = any
+
type SocialAccountListResponse struct {
Data []SocialAccount `json:"data" api:"required"`
Meta SocialAccountListResponseMeta `json:"meta" api:"required"`
@@ -243,7 +249,7 @@ type SocialAccountDisconnectResponse struct {
// The external id of the social account
ExternalID string `json:"external_id" api:"required"`
// The metadata of the social account
- Metadata any `json:"metadata" api:"required"`
+ Metadata SocialAccountMetadata `json:"metadata" api:"required"`
// The platform of the social account
Platform string `json:"platform" api:"required"`
// The platform's profile photo of the social account
@@ -313,7 +319,7 @@ type SocialAccountNewParams struct {
// The platform's username of the social account
Username param.Opt[string] `json:"username,omitzero"`
// The metadata of the social account
- Metadata any `json:"metadata,omitzero"`
+ Metadata SocialAccountMetadata `json:"metadata,omitzero"`
paramObj
}
@@ -399,7 +405,7 @@ type SocialAccountNewAuthURLParams struct {
// Override the default redirect URL for the OAuth flow. If provided, this URL will
// be used instead of our redirect URL. Make sure this URL is included in your
// app's authorized redirect urls. This override will not work when using our
- // system credientals.
+ // system credentials; configure the project redirect URL in the dashboard instead.
RedirectURLOverride param.Opt[string] `json:"redirect_url_override,omitzero"`
// List of permissions you want to allow. Will default to only post permissions.
// You must include the "feeds" permission to request an account feed and metrics
@@ -437,6 +443,8 @@ type SocialAccountNewAuthURLParamsPlatformData struct {
Tiktok SocialAccountNewAuthURLParamsPlatformDataTiktok `json:"tiktok,omitzero"`
// Additional data for connecting TikTok Business accounts
TiktokBusiness SocialAccountNewAuthURLParamsPlatformDataTiktokBusiness `json:"tiktok_business,omitzero"`
+ // Additional data for connecting X accounts
+ X SocialAccountNewAuthURLParamsPlatformDataX `json:"x,omitzero"`
// Additional data for connecting YouTube accounts
Youtube SocialAccountNewAuthURLParamsPlatformDataYoutube `json:"youtube,omitzero"`
paramObj
@@ -474,7 +482,7 @@ type SocialAccountNewAuthURLParamsPlatformDataFacebook struct {
// Override the default permissions/scopes requested during OAuth. Default scopes:
// public_profile, pages_show_list, pages_read_engagement, pages_manage_posts,
// business_management
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -499,7 +507,7 @@ type SocialAccountNewAuthURLParamsPlatformDataInstagram struct {
// instagram scopes: instagram_business_basic, instagram_business_content_publish.
// Default facebook scopes: instagram_basic, instagram_content_publish,
// pages_show_list, public_profile, business_management
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -522,7 +530,7 @@ func init() {
// The property ConnectionType is required.
type SocialAccountNewAuthURLParamsPlatformDataLinkedin struct {
// The type of connection; If using our provided credentials always use
- // "organization". If using your own crednetials then only use "organization" if
+ // "organization". If using your own credentials then only use "organization" if
// you are using the Community API
//
// Any of "personal", "organization".
@@ -531,7 +539,7 @@ type SocialAccountNewAuthURLParamsPlatformDataLinkedin struct {
// scopes: openid, w_member_social, profile, email. Default organization scopes:
// r_basicprofile, w_member_social, r_organization_social, w_organization_social,
// rw_organization_admin
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -553,7 +561,7 @@ func init() {
type SocialAccountNewAuthURLParamsPlatformDataPinterest struct {
// Override the default permissions/scopes requested during OAuth. Default scopes:
// boards:read, boards:write, pins:read, pins:write, user_accounts:read
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -569,7 +577,7 @@ func (r *SocialAccountNewAuthURLParamsPlatformDataPinterest) UnmarshalJSON(data
type SocialAccountNewAuthURLParamsPlatformDataThreads struct {
// Override the default permissions/scopes requested during OAuth. Default scopes:
// threads_basic, threads_content_publish
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -585,7 +593,7 @@ func (r *SocialAccountNewAuthURLParamsPlatformDataThreads) UnmarshalJSON(data []
type SocialAccountNewAuthURLParamsPlatformDataTiktok struct {
// Override the default permissions/scopes requested during OAuth. Default scopes:
// user.info.basic, video.list, video.upload, video.publish
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -604,7 +612,7 @@ type SocialAccountNewAuthURLParamsPlatformDataTiktokBusiness struct {
// user.account.type, user.insights, video.list, video.insights, comment.list,
// comment.list.manage, video.publish, video.upload, biz.spark.auth,
// discovery.search.words
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
@@ -616,6 +624,32 @@ func (r *SocialAccountNewAuthURLParamsPlatformDataTiktokBusiness) UnmarshalJSON(
return apijson.UnmarshalRoot(data, r)
}
+// Additional data for connecting X accounts
+//
+// The property ConnectionType is required.
+type SocialAccountNewAuthURLParamsPlatformDataX struct {
+ // The type of connection; oauth1 for OAuth 1.0a app credentials, oauth2 for OAuth
+ // 2.0 app credentials.
+ //
+ // Any of "oauth1", "oauth2".
+ ConnectionType string `json:"connection_type,omitzero" api:"required"`
+ paramObj
+}
+
+func (r SocialAccountNewAuthURLParamsPlatformDataX) MarshalJSON() (data []byte, err error) {
+ type shadow SocialAccountNewAuthURLParamsPlatformDataX
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *SocialAccountNewAuthURLParamsPlatformDataX) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+func init() {
+ apijson.RegisterFieldValidator[SocialAccountNewAuthURLParamsPlatformDataX](
+ "connection_type", "oauth1", "oauth2",
+ )
+}
+
// Additional data for connecting YouTube accounts
type SocialAccountNewAuthURLParamsPlatformDataYoutube struct {
// Override the default permissions/scopes requested during OAuth. Default scopes:
@@ -623,7 +657,7 @@ type SocialAccountNewAuthURLParamsPlatformDataYoutube struct {
// https://www.googleapis.com/auth/youtube.upload,
// https://www.googleapis.com/auth/youtube.readonly,
// https://www.googleapis.com/auth/userinfo.profile
- PermissionOverrides [][]any `json:"permission_overrides,omitzero"`
+ PermissionOverrides []string `json:"permission_overrides,omitzero"`
paramObj
}
diff --git a/socialaccount_test.go b/socialaccount_test.go
index a03b76d..b530984 100644
--- a/socialaccount_test.go
+++ b/socialaccount_test.go
@@ -154,30 +154,33 @@ func TestSocialAccountNewAuthURLWithOptionalParams(t *testing.T) {
Handle: "handle",
},
Facebook: postforme.SocialAccountNewAuthURLParamsPlatformDataFacebook{
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
Instagram: postforme.SocialAccountNewAuthURLParamsPlatformDataInstagram{
ConnectionType: "instagram",
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
Linkedin: postforme.SocialAccountNewAuthURLParamsPlatformDataLinkedin{
ConnectionType: "personal",
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
Pinterest: postforme.SocialAccountNewAuthURLParamsPlatformDataPinterest{
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
Threads: postforme.SocialAccountNewAuthURLParamsPlatformDataThreads{
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
Tiktok: postforme.SocialAccountNewAuthURLParamsPlatformDataTiktok{
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
TiktokBusiness: postforme.SocialAccountNewAuthURLParamsPlatformDataTiktokBusiness{
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
+ },
+ X: postforme.SocialAccountNewAuthURLParamsPlatformDataX{
+ ConnectionType: "oauth1",
},
Youtube: postforme.SocialAccountNewAuthURLParamsPlatformDataYoutube{
- PermissionOverrides: [][]any{{map[string]any{}}},
+ PermissionOverrides: []string{"string"},
},
},
RedirectURLOverride: postforme.String("redirect_url_override"),
diff --git a/socialaccountfeed.go b/socialaccountfeed.go
index da00b34..72bdd59 100644
--- a/socialaccountfeed.go
+++ b/socialaccountfeed.go
@@ -30,6 +30,9 @@ import (
// - Post information including caption, url, media, etc..
// - When passing **expand=metrics**, Metrics information including views, likes,
// follows, etc..
+// - For **Facebook** feeds with **expand=metrics**, page size is capped by the
+// server-side **FacebookFeedMetricsLimitCap** setting (default: **10**) to
+// protect API memory usage.
//
// Note: Currently the following platforms are supported:
//
@@ -78,6 +81,122 @@ func (r *SocialAccountFeedService) List(ctx context.Context, socialAccountID str
return res, err
}
+type FacebookActivityByActionType struct {
+ // Action type (e.g., like, comment, share)
+ ActionType string `json:"action_type" api:"required"`
+ // Number of actions
+ Value float64 `json:"value" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ActionType respjson.Field
+ Value respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r FacebookActivityByActionType) RawJSON() string { return r.JSON.raw }
+func (r *FacebookActivityByActionType) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type FacebookVideoRetentionGraph struct {
+ // Percentage of viewers at this time
+ Rate float64 `json:"rate" api:"required"`
+ // Time in seconds
+ Time float64 `json:"time" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Rate respjson.Field
+ Time respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r FacebookVideoRetentionGraph) RawJSON() string { return r.JSON.raw }
+func (r *FacebookVideoRetentionGraph) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type FacebookVideoViewTimeByDemographic struct {
+ // Demographic key (e.g., age_gender, region, country)
+ Key string `json:"key" api:"required"`
+ // Total view time in milliseconds
+ Value float64 `json:"value" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Key respjson.Field
+ Value respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r FacebookVideoViewTimeByDemographic) RawJSON() string { return r.JSON.raw }
+func (r *FacebookVideoViewTimeByDemographic) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type PinterestMetricsWindow struct {
+ // Number of comments on the Pin
+ Comment float64 `json:"comment"`
+ // Number of times the Pin was shown (impressions)
+ Impression float64 `json:"impression"`
+ // The last time Pinterest updated these metrics
+ LastUpdated string `json:"last_updated"`
+ // Number of clicks from the Pin to an external destination (outbound clicks)
+ OutboundClick float64 `json:"outbound_click"`
+ // Number of clicks on the Pin to view it in closeup (Pin clicks)
+ PinClick float64 `json:"pin_click"`
+ // Number of visits to the author's profile driven from the Pin
+ ProfileVisit any `json:"profile_visit" api:"nullable"`
+ // Total number of reactions on the Pin
+ Reaction float64 `json:"reaction"`
+ // Number of saves of the Pin
+ Save float64 `json:"save"`
+ // Number of follows driven from the Pin
+ UserFollow any `json:"user_follow" api:"nullable"`
+ // Number of video views of at least 10 seconds
+ Video10sViews float64 `json:"video_10s_views"`
+ // Average watch time for the video
+ VideoAverageTime float64 `json:"video_average_time"`
+ // Number of video views that reached 95% completion
+ VideoP95Views float64 `json:"video_p95_views"`
+ // Total watch time for the video
+ VideoTotalTime float64 `json:"video_total_time"`
+ // Number of video views
+ VideoViews float64 `json:"video_views"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Comment respjson.Field
+ Impression respjson.Field
+ LastUpdated respjson.Field
+ OutboundClick respjson.Field
+ PinClick respjson.Field
+ ProfileVisit respjson.Field
+ Reaction respjson.Field
+ Save respjson.Field
+ UserFollow respjson.Field
+ Video10sViews respjson.Field
+ VideoAverageTime respjson.Field
+ VideoP95Views respjson.Field
+ VideoTotalTime respjson.Field
+ VideoViews respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r PinterestMetricsWindow) RawJSON() string { return r.JSON.raw }
+func (r *PinterestMetricsWindow) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
type PlatformPost struct {
// Caption or text content of the post
Caption string `json:"caption" api:"required"`
@@ -100,7 +219,7 @@ type PlatformPost struct {
// Post metrics and analytics data
Metrics PlatformPostMetricsUnion `json:"metrics"`
// Platform-specific data for the post
- PlatformData PlatformPostPlatformData `json:"platform_data"`
+ PlatformData YoutubePostPlatformData `json:"platform_data"`
// Date the post was published
PostedAt time.Time `json:"posted_at" format:"date-time"`
// ID of the social post
@@ -166,7 +285,7 @@ type PlatformPostMetricsUnion struct {
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
EmailClicks float64 `json:"email_clicks"`
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
- EngagementLikes []PlatformPostMetricsTikTokBusinessMetricsDtoEngagementLike `json:"engagement_likes"`
+ EngagementLikes []TiktokBusinessVideoMetricPercentage `json:"engagement_likes"`
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
Favorites float64 `json:"favorites"`
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
@@ -187,8 +306,8 @@ type PlatformPostMetricsUnion struct {
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
TotalTimeWatched float64 `json:"total_time_watched"`
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
- VideoViewRetention []PlatformPostMetricsTikTokBusinessMetricsDtoVideoViewRetention `json:"video_view_retention"`
- VideoViews float64 `json:"video_views"`
+ VideoViewRetention []TiktokBusinessVideoMetricPercentage `json:"video_view_retention"`
+ VideoViews float64 `json:"video_views"`
// This field is from variant [PlatformPostMetricsTikTokBusinessMetricsDto].
WebsiteClicks float64 `json:"website_clicks"`
CommentCount float64 `json:"comment_count"`
@@ -263,20 +382,12 @@ type PlatformPostMetricsUnion struct {
// This field is from variant [PlatformPostMetricsYouTubePostMetricsDto].
VideosRemovedFromPlaylists float64 `json:"videosRemovedFromPlaylists"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- ActivityByActionType []PlatformPostMetricsFacebookPostMetricsDtoActivityByActionType `json:"activity_by_action_type"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- ActivityByActionTypeUnique []PlatformPostMetricsFacebookPostMetricsDtoActivityByActionTypeUnique `json:"activity_by_action_type_unique"`
+ ActivityByActionType []FacebookActivityByActionType `json:"activity_by_action_type"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- FanReach float64 `json:"fan_reach"`
+ ActivityByActionTypeUnique []FacebookActivityByActionType `json:"activity_by_action_type_unique"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
MediaViews float64 `json:"media_views"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- NonviralReach float64 `json:"nonviral_reach"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- OrganicReach float64 `json:"organic_reach"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- PaidReach float64 `json:"paid_reach"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
ReactionsAnger float64 `json:"reactions_anger"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
ReactionsByType any `json:"reactions_by_type"`
@@ -305,21 +416,21 @@ type PlatformPostMetricsUnion struct {
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoLength float64 `json:"video_length"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoRetentionGraphAutoplayed []PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphAutoplayed `json:"video_retention_graph_autoplayed"`
+ VideoRetentionGraphAutoplayed []FacebookVideoRetentionGraph `json:"video_retention_graph_autoplayed"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoRetentionGraphClickedToPlay []PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphClickedToPlay `json:"video_retention_graph_clicked_to_play"`
+ VideoRetentionGraphClickedToPlay []FacebookVideoRetentionGraph `json:"video_retention_graph_clicked_to_play"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoSocialActionsUnique float64 `json:"video_social_actions_unique"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoViewTime float64 `json:"video_view_time"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoViewTimeByAgeGender []PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByAgeGender `json:"video_view_time_by_age_gender"`
+ VideoViewTimeByAgeGender []FacebookVideoViewTimeByDemographic `json:"video_view_time_by_age_gender"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoViewTimeByCountry []PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByCountry `json:"video_view_time_by_country"`
+ VideoViewTimeByCountry []FacebookVideoViewTimeByDemographic `json:"video_view_time_by_country"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoViewTimeByDistributionType any `json:"video_view_time_by_distribution_type"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoViewTimeByRegion []PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByRegion `json:"video_view_time_by_region"`
+ VideoViewTimeByRegion []FacebookVideoViewTimeByDemographic `json:"video_view_time_by_region"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoViewTimeOrganic float64 `json:"video_view_time_organic"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
@@ -335,17 +446,9 @@ type PlatformPostMetricsUnion struct {
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoViewsOrganic float64 `json:"video_views_organic"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoViewsOrganicUnique float64 `json:"video_views_organic_unique"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoViewsPaid float64 `json:"video_views_paid"`
// This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoViewsPaidUnique float64 `json:"video_views_paid_unique"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
VideoViewsSoundOn float64 `json:"video_views_sound_on"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- VideoViewsUnique float64 `json:"video_views_unique"`
- // This field is from variant [PlatformPostMetricsFacebookPostMetricsDto].
- ViralReach float64 `json:"viral_reach"`
// This field is from variant [PlatformPostMetricsTwitterPostMetricsDto].
NonPublicMetrics PlatformPostMetricsTwitterPostMetricsDtoNonPublicMetrics `json:"non_public_metrics"`
// This field is from variant [PlatformPostMetricsTwitterPostMetricsDto].
@@ -377,9 +480,9 @@ type PlatformPostMetricsUnion struct {
// This field is from variant [PlatformPostMetricsBlueskyPostMetricsDto].
RepostCount float64 `json:"repostCount"`
// This field is from variant [PlatformPostMetricsPinterestPostMetricsDto].
- Number90d PlatformPostMetricsPinterestPostMetricsDto90d `json:"90d"`
+ Number90d PinterestMetricsWindow `json:"90d"`
// This field is from variant [PlatformPostMetricsPinterestPostMetricsDto].
- LifetimeMetrics PlatformPostMetricsPinterestPostMetricsDtoLifetimeMetrics `json:"lifetime_metrics"`
+ LifetimeMetrics PinterestMetricsWindow `json:"lifetime_metrics"`
JSON struct {
AddressClicks respjson.Field
AppDownloadClicks respjson.Field
@@ -445,11 +548,7 @@ type PlatformPostMetricsUnion struct {
VideosRemovedFromPlaylists respjson.Field
ActivityByActionType respjson.Field
ActivityByActionTypeUnique respjson.Field
- FanReach respjson.Field
MediaViews respjson.Field
- NonviralReach respjson.Field
- OrganicReach respjson.Field
- PaidReach respjson.Field
ReactionsAnger respjson.Field
ReactionsByType respjson.Field
ReactionsHaha respjson.Field
@@ -479,12 +578,8 @@ type PlatformPostMetricsUnion struct {
VideoViewsByDistributionType respjson.Field
VideoViewsClickedToPlay respjson.Field
VideoViewsOrganic respjson.Field
- VideoViewsOrganicUnique respjson.Field
VideoViewsPaid respjson.Field
- VideoViewsPaidUnique respjson.Field
VideoViewsSoundOn respjson.Field
- VideoViewsUnique respjson.Field
- ViralReach respjson.Field
NonPublicMetrics respjson.Field
OrganicMetrics respjson.Field
PublicMetrics respjson.Field
@@ -583,7 +678,7 @@ type PlatformPostMetricsTikTokBusinessMetricsDto struct {
// Number of email clicks
EmailClicks float64 `json:"email_clicks" api:"required"`
// Engagement likes data by percentage and time
- EngagementLikes []PlatformPostMetricsTikTokBusinessMetricsDtoEngagementLike `json:"engagement_likes" api:"required"`
+ EngagementLikes []TiktokBusinessVideoMetricPercentage `json:"engagement_likes" api:"required"`
// Number of favorites on the post
Favorites float64 `json:"favorites" api:"required"`
// Rate of full video watches as a percentage
@@ -607,7 +702,7 @@ type PlatformPostMetricsTikTokBusinessMetricsDto struct {
// Total time watched in seconds
TotalTimeWatched float64 `json:"total_time_watched" api:"required"`
// Video view retention data by percentage and time
- VideoViewRetention []PlatformPostMetricsTikTokBusinessMetricsDtoVideoViewRetention `json:"video_view_retention" api:"required"`
+ VideoViewRetention []TiktokBusinessVideoMetricPercentage `json:"video_view_retention" api:"required"`
// Total number of video views
VideoViews float64 `json:"video_views" api:"required"`
// Number of website clicks
@@ -733,28 +828,6 @@ func (r *PlatformPostMetricsTikTokBusinessMetricsDtoAudienceType) UnmarshalJSON(
return apijson.UnmarshalRoot(data, r)
}
-type PlatformPostMetricsTikTokBusinessMetricsDtoEngagementLike struct {
- // Percentage value for the metric
- Percentage float64 `json:"percentage" api:"required"`
- // Time in seconds for the metric
- Second string `json:"second" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Percentage respjson.Field
- Second respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsTikTokBusinessMetricsDtoEngagementLike) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsTikTokBusinessMetricsDtoEngagementLike) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
type PlatformPostMetricsTikTokBusinessMetricsDtoImpressionSource struct {
// Name of the impression source
ImpressionSource string `json:"impression_source" api:"required"`
@@ -777,28 +850,6 @@ func (r *PlatformPostMetricsTikTokBusinessMetricsDtoImpressionSource) UnmarshalJ
return apijson.UnmarshalRoot(data, r)
}
-type PlatformPostMetricsTikTokBusinessMetricsDtoVideoViewRetention struct {
- // Percentage value for the metric
- Percentage float64 `json:"percentage" api:"required"`
- // Time in seconds for the metric
- Second string `json:"second" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Percentage respjson.Field
- Second respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsTikTokBusinessMetricsDtoVideoViewRetention) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsTikTokBusinessMetricsDtoVideoViewRetention) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
type PlatformPostMetricsTikTokPostMetricsDto struct {
// Number of comments on the video
CommentCount float64 `json:"comment_count" api:"required"`
@@ -981,22 +1032,14 @@ func (r *PlatformPostMetricsYouTubePostMetricsDto) UnmarshalJSON(data []byte) er
type PlatformPostMetricsFacebookPostMetricsDto struct {
// Total activity breakdown by action type
- ActivityByActionType []PlatformPostMetricsFacebookPostMetricsDtoActivityByActionType `json:"activity_by_action_type"`
+ ActivityByActionType []FacebookActivityByActionType `json:"activity_by_action_type"`
// Unique users activity breakdown by action type
- ActivityByActionTypeUnique []PlatformPostMetricsFacebookPostMetricsDtoActivityByActionTypeUnique `json:"activity_by_action_type_unique"`
+ ActivityByActionTypeUnique []FacebookActivityByActionType `json:"activity_by_action_type_unique"`
// Number of comments (from post object)
Comments float64 `json:"comments"`
- // Number of fans who saw the post
- FanReach float64 `json:"fan_reach"`
// Number of times the photo or video was viewed
MediaViews float64 `json:"media_views"`
- // Number of people who saw the post via non-viral distribution
- NonviralReach float64 `json:"nonviral_reach"`
- // Number of people who saw the post via organic distribution
- OrganicReach float64 `json:"organic_reach"`
- // Number of people who saw the post via paid distribution
- PaidReach float64 `json:"paid_reach"`
- // Total number of unique people who saw the post
+ // Total number of unique people who viewed the post media
Reach float64 `json:"reach"`
// Number of anger reactions
ReactionsAnger float64 `json:"reactions_anger"`
@@ -1029,21 +1072,21 @@ type PlatformPostMetricsFacebookPostMetricsDto struct {
// Length of the video in milliseconds
VideoLength float64 `json:"video_length"`
// Video retention graph for autoplayed views
- VideoRetentionGraphAutoplayed []PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphAutoplayed `json:"video_retention_graph_autoplayed"`
+ VideoRetentionGraphAutoplayed []FacebookVideoRetentionGraph `json:"video_retention_graph_autoplayed"`
// Video retention graph for clicked-to-play views
- VideoRetentionGraphClickedToPlay []PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphClickedToPlay `json:"video_retention_graph_clicked_to_play"`
+ VideoRetentionGraphClickedToPlay []FacebookVideoRetentionGraph `json:"video_retention_graph_clicked_to_play"`
// Number of unique people who performed social actions on the video
VideoSocialActionsUnique float64 `json:"video_social_actions_unique"`
// Total time video was viewed in milliseconds
VideoViewTime float64 `json:"video_view_time"`
// Video view time breakdown by age and gender
- VideoViewTimeByAgeGender []PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByAgeGender `json:"video_view_time_by_age_gender"`
+ VideoViewTimeByAgeGender []FacebookVideoViewTimeByDemographic `json:"video_view_time_by_age_gender"`
// Video view time breakdown by country
- VideoViewTimeByCountry []PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByCountry `json:"video_view_time_by_country"`
+ VideoViewTimeByCountry []FacebookVideoViewTimeByDemographic `json:"video_view_time_by_country"`
// Video view time breakdown by distribution type
VideoViewTimeByDistributionType any `json:"video_view_time_by_distribution_type"`
// Video view time breakdown by region
- VideoViewTimeByRegion []PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByRegion `json:"video_view_time_by_region"`
+ VideoViewTimeByRegion []FacebookVideoViewTimeByDemographic `json:"video_view_time_by_region"`
// Total time video was viewed in milliseconds via organic distribution
VideoViewTimeOrganic float64 `json:"video_view_time_organic"`
// Number of times video was viewed for 3+ seconds
@@ -1061,29 +1104,16 @@ type PlatformPostMetricsFacebookPostMetricsDto struct {
VideoViewsClickedToPlay float64 `json:"video_views_clicked_to_play"`
// Number of times video was viewed for 3+ seconds organically
VideoViewsOrganic float64 `json:"video_views_organic"`
- // Number of unique people who viewed the video for 3+ seconds organically
- VideoViewsOrganicUnique float64 `json:"video_views_organic_unique"`
// Number of times video was viewed for 3+ seconds via paid distribution
VideoViewsPaid float64 `json:"video_views_paid"`
- // Number of unique people who viewed the video for 3+ seconds via paid
- // distribution
- VideoViewsPaidUnique float64 `json:"video_views_paid_unique"`
// Number of times video was viewed with sound on
VideoViewsSoundOn float64 `json:"video_views_sound_on"`
- // Number of unique people who viewed the video for 3+ seconds
- VideoViewsUnique float64 `json:"video_views_unique"`
- // Number of people who saw the post in News Feed via viral reach
- ViralReach float64 `json:"viral_reach"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ActivityByActionType respjson.Field
ActivityByActionTypeUnique respjson.Field
Comments respjson.Field
- FanReach respjson.Field
MediaViews respjson.Field
- NonviralReach respjson.Field
- OrganicReach respjson.Field
- PaidReach respjson.Field
Reach respjson.Field
ReactionsAnger respjson.Field
ReactionsByType respjson.Field
@@ -1116,12 +1146,8 @@ type PlatformPostMetricsFacebookPostMetricsDto struct {
VideoViewsByDistributionType respjson.Field
VideoViewsClickedToPlay respjson.Field
VideoViewsOrganic respjson.Field
- VideoViewsOrganicUnique respjson.Field
VideoViewsPaid respjson.Field
- VideoViewsPaidUnique respjson.Field
VideoViewsSoundOn respjson.Field
- VideoViewsUnique respjson.Field
- ViralReach respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
@@ -1133,160 +1159,6 @@ func (r *PlatformPostMetricsFacebookPostMetricsDto) UnmarshalJSON(data []byte) e
return apijson.UnmarshalRoot(data, r)
}
-type PlatformPostMetricsFacebookPostMetricsDtoActivityByActionType struct {
- // Action type (e.g., like, comment, share)
- ActionType string `json:"action_type" api:"required"`
- // Number of actions
- Value float64 `json:"value" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ActionType respjson.Field
- Value respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoActivityByActionType) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoActivityByActionType) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PlatformPostMetricsFacebookPostMetricsDtoActivityByActionTypeUnique struct {
- // Action type (e.g., like, comment, share)
- ActionType string `json:"action_type" api:"required"`
- // Number of actions
- Value float64 `json:"value" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ActionType respjson.Field
- Value respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoActivityByActionTypeUnique) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoActivityByActionTypeUnique) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphAutoplayed struct {
- // Percentage of viewers at this time
- Rate float64 `json:"rate" api:"required"`
- // Time in seconds
- Time float64 `json:"time" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Rate respjson.Field
- Time respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphAutoplayed) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphAutoplayed) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphClickedToPlay struct {
- // Percentage of viewers at this time
- Rate float64 `json:"rate" api:"required"`
- // Time in seconds
- Time float64 `json:"time" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Rate respjson.Field
- Time respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphClickedToPlay) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoVideoRetentionGraphClickedToPlay) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByAgeGender struct {
- // Demographic key (e.g., age_gender, region, country)
- Key string `json:"key" api:"required"`
- // Total view time in milliseconds
- Value float64 `json:"value" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Key respjson.Field
- Value respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByAgeGender) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByAgeGender) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByCountry struct {
- // Demographic key (e.g., age_gender, region, country)
- Key string `json:"key" api:"required"`
- // Total view time in milliseconds
- Value float64 `json:"value" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Key respjson.Field
- Value respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByCountry) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByCountry) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByRegion struct {
- // Demographic key (e.g., age_gender, region, country)
- Key string `json:"key" api:"required"`
- // Total view time in milliseconds
- Value float64 `json:"value" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Key respjson.Field
- Value respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByRegion) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsFacebookPostMetricsDtoVideoViewTimeByRegion) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
type PlatformPostMetricsTwitterPostMetricsDto struct {
// Non-public metrics for the Tweet (available to the Tweet owner or advertisers)
NonPublicMetrics PlatformPostMetricsTwitterPostMetricsDtoNonPublicMetrics `json:"non_public_metrics"`
@@ -1514,9 +1386,9 @@ func (r *PlatformPostMetricsBlueskyPostMetricsDto) UnmarshalJSON(data []byte) er
type PlatformPostMetricsPinterestPostMetricsDto struct {
// Last 90 days of Pin metrics
- Number90d PlatformPostMetricsPinterestPostMetricsDto90d `json:"90d"`
+ Number90d PinterestMetricsWindow `json:"90d"`
// Lifetime Pin metrics
- LifetimeMetrics PlatformPostMetricsPinterestPostMetricsDtoLifetimeMetrics `json:"lifetime_metrics"`
+ LifetimeMetrics PinterestMetricsWindow `json:"lifetime_metrics"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
Number90d respjson.Field
@@ -1532,124 +1404,27 @@ func (r *PlatformPostMetricsPinterestPostMetricsDto) UnmarshalJSON(data []byte)
return apijson.UnmarshalRoot(data, r)
}
-// Last 90 days of Pin metrics
-type PlatformPostMetricsPinterestPostMetricsDto90d struct {
- // Number of comments on the Pin
- Comment float64 `json:"comment"`
- // Number of times the Pin was shown (impressions)
- Impression float64 `json:"impression"`
- // The last time Pinterest updated these metrics
- LastUpdated string `json:"last_updated"`
- // Number of clicks from the Pin to an external destination (outbound clicks)
- OutboundClick float64 `json:"outbound_click"`
- // Number of clicks on the Pin to view it in closeup (Pin clicks)
- PinClick float64 `json:"pin_click"`
- // Number of visits to the author's profile driven from the Pin
- ProfileVisit any `json:"profile_visit" api:"nullable"`
- // Total number of reactions on the Pin
- Reaction float64 `json:"reaction"`
- // Number of saves of the Pin
- Save float64 `json:"save"`
- // Number of follows driven from the Pin
- UserFollow any `json:"user_follow" api:"nullable"`
- // Number of video views of at least 10 seconds
- Video10sViews float64 `json:"video_10s_views"`
- // Average watch time for the video
- VideoAverageTime float64 `json:"video_average_time"`
- // Number of video views that reached 95% completion
- VideoP95Views float64 `json:"video_p95_views"`
- // Total watch time for the video
- VideoTotalTime float64 `json:"video_total_time"`
- // Number of video views
- VideoViews float64 `json:"video_views"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Comment respjson.Field
- Impression respjson.Field
- LastUpdated respjson.Field
- OutboundClick respjson.Field
- PinClick respjson.Field
- ProfileVisit respjson.Field
- Reaction respjson.Field
- Save respjson.Field
- UserFollow respjson.Field
- Video10sViews respjson.Field
- VideoAverageTime respjson.Field
- VideoP95Views respjson.Field
- VideoTotalTime respjson.Field
- VideoViews respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsPinterestPostMetricsDto90d) RawJSON() string { return r.JSON.raw }
-func (r *PlatformPostMetricsPinterestPostMetricsDto90d) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// Lifetime Pin metrics
-type PlatformPostMetricsPinterestPostMetricsDtoLifetimeMetrics struct {
- // Number of comments on the Pin
- Comment float64 `json:"comment"`
- // Number of times the Pin was shown (impressions)
- Impression float64 `json:"impression"`
- // The last time Pinterest updated these metrics
- LastUpdated string `json:"last_updated"`
- // Number of clicks from the Pin to an external destination (outbound clicks)
- OutboundClick float64 `json:"outbound_click"`
- // Number of clicks on the Pin to view it in closeup (Pin clicks)
- PinClick float64 `json:"pin_click"`
- // Number of visits to the author's profile driven from the Pin
- ProfileVisit any `json:"profile_visit" api:"nullable"`
- // Total number of reactions on the Pin
- Reaction float64 `json:"reaction"`
- // Number of saves of the Pin
- Save float64 `json:"save"`
- // Number of follows driven from the Pin
- UserFollow any `json:"user_follow" api:"nullable"`
- // Number of video views of at least 10 seconds
- Video10sViews float64 `json:"video_10s_views"`
- // Average watch time for the video
- VideoAverageTime float64 `json:"video_average_time"`
- // Number of video views that reached 95% completion
- VideoP95Views float64 `json:"video_p95_views"`
- // Total watch time for the video
- VideoTotalTime float64 `json:"video_total_time"`
- // Number of video views
- VideoViews float64 `json:"video_views"`
+type TiktokBusinessVideoMetricPercentage struct {
+ // Percentage value for the metric
+ Percentage float64 `json:"percentage" api:"required"`
+ // Time in seconds for the metric
+ Second string `json:"second" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Comment respjson.Field
- Impression respjson.Field
- LastUpdated respjson.Field
- OutboundClick respjson.Field
- PinClick respjson.Field
- ProfileVisit respjson.Field
- Reaction respjson.Field
- Save respjson.Field
- UserFollow respjson.Field
- Video10sViews respjson.Field
- VideoAverageTime respjson.Field
- VideoP95Views respjson.Field
- VideoTotalTime respjson.Field
- VideoViews respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Percentage respjson.Field
+ Second respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r PlatformPostMetricsPinterestPostMetricsDtoLifetimeMetrics) RawJSON() string {
- return r.JSON.raw
-}
-func (r *PlatformPostMetricsPinterestPostMetricsDtoLifetimeMetrics) UnmarshalJSON(data []byte) error {
+func (r TiktokBusinessVideoMetricPercentage) RawJSON() string { return r.JSON.raw }
+func (r *TiktokBusinessVideoMetricPercentage) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Platform-specific data for the post
-type PlatformPostPlatformData struct {
+type YoutubePostPlatformData struct {
// Title of the post
Title string `json:"title" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
@@ -1661,8 +1436,8 @@ type PlatformPostPlatformData struct {
}
// Returns the unmodified JSON received from the API
-func (r PlatformPostPlatformData) RawJSON() string { return r.JSON.raw }
-func (r *PlatformPostPlatformData) UnmarshalJSON(data []byte) error {
+func (r YoutubePostPlatformData) RawJSON() string { return r.JSON.raw }
+func (r *YoutubePostPlatformData) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
diff --git a/socialpost.go b/socialpost.go
index 9714d3c..34f2749 100644
--- a/socialpost.go
+++ b/socialpost.go
@@ -93,7 +93,7 @@ func (r *SocialPostService) List(ctx context.Context, query SocialPostListParams
}
// Delete Post
-func (r *SocialPostService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (res *SocialPostDeleteResponse, err error) {
+func (r *SocialPostService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (res *DeleteEntityResponse, err error) {
opts = slices.Concat(r.Options, opts)
if id == "" {
err = errors.New("missing required id parameter")
@@ -104,244 +104,265 @@ func (r *SocialPostService) Delete(ctx context.Context, id string, opts ...optio
return res, err
}
-type BlueskyConfigurationDto struct {
- // Overrides the `caption` from the post
- Caption any `json:"caption" api:"nullable"`
- // Overrides the `media` from the post
- Media []BlueskyConfigurationDtoMedia `json:"media" api:"nullable"`
+type AccountConfiguration struct {
+ // Configuration for the social account
+ Configuration AccountConfigurationConfiguration `json:"configuration" api:"required"`
+ // ID of the social account, you want to apply the configuration to
+ SocialAccountID string `json:"social_account_id" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Caption respjson.Field
- Media respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Configuration respjson.Field
+ SocialAccountID respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r BlueskyConfigurationDto) RawJSON() string { return r.JSON.raw }
-func (r *BlueskyConfigurationDto) UnmarshalJSON(data []byte) error {
+func (r AccountConfiguration) RawJSON() string { return r.JSON.raw }
+func (r *AccountConfiguration) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// ToParam converts this BlueskyConfigurationDto to a BlueskyConfigurationDtoParam.
+// ToParam converts this AccountConfiguration to a AccountConfigurationParam.
//
// Warning: the fields of the param type will not be present. ToParam should only
// be used at the last possible moment before sending a request. Test for this with
-// BlueskyConfigurationDtoParam.Overrides()
-func (r BlueskyConfigurationDto) ToParam() BlueskyConfigurationDtoParam {
- return param.Override[BlueskyConfigurationDtoParam](json.RawMessage(r.RawJSON()))
+// AccountConfigurationParam.Overrides()
+func (r AccountConfiguration) ToParam() AccountConfigurationParam {
+ return param.Override[AccountConfigurationParam](json.RawMessage(r.RawJSON()))
}
-type BlueskyConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []BlueskyConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
+// Configuration for the social account
+type AccountConfigurationConfiguration struct {
+ // Per-language localizations for the video title and description. Keys are BCP-47
+ // language tags (e.g. "fr", "es"). Maps to localizations on the YouTube Data API
+ // videos resource.
+ Localizations map[string]AccountConfigurationConfigurationLocalization `json:"localizations" api:"required"`
+ // Allow comments on TikTok
+ AllowComment bool `json:"allow_comment" api:"nullable"`
+ // Allow duets on TikTok
+ AllowDuet bool `json:"allow_duet" api:"nullable"`
+ // Allow stitch on TikTok
+ AllowStitch bool `json:"allow_stitch" api:"nullable"`
+ // Display name for the audio track on Instagram Reels. Only honored on Reels
+ // uploads, and only when the audio is original (Meta silently ignores it on
+ // licensed/fingerprinted tracks).
+ AudioName string `json:"audio_name" api:"nullable"`
+ // Will automatically add music to photo posts on TikTok
+ AutoAddMusic bool `json:"auto_add_music" api:"nullable"`
+ // Pinterest board IDs
+ BoardIDs []string `json:"board_ids" api:"nullable"`
+ // Overrides the `caption` from the post
+ Caption any `json:"caption" api:"nullable"`
+ // YouTube video category id (maps to snippet.categoryId; see YouTube Data API
+ // videoCategories.list)
+ CategoryID string `json:"category_id" api:"nullable"`
+ // List of page ids or users to invite as collaborators for a Video Reel (Instagram
+ // and Facebook)
+ Collaborators [][]any `json:"collaborators" api:"nullable"`
+ // Id of the twitter community to post to
+ CommunityID string `json:"community_id"`
+ // If true, marks the YouTube video as containing altered or synthetic content per
+ // YouTube's disclosure policy. Sets status.containsSyntheticMedia on the
+ // videos.insert call; YouTube adds a "How this content was made" label to the
+ // description automatically.
+ ContainsSyntheticMedia bool `json:"contains_synthetic_media" api:"nullable"`
+ // Default language of the video (BCP-47 language tag, e.g. "en"). Maps to
+ // snippet.defaultLanguage.
+ DefaultLanguage string `json:"default_language" api:"nullable"`
+ // Disclose branded content on TikTok
+ DiscloseBrandedContent bool `json:"disclose_branded_content" api:"nullable"`
+ // Disclose your brand on TikTok
+ DiscloseYourBrand bool `json:"disclose_your_brand" api:"nullable"`
+ // If true the video can be embedded on other websites (maps to status.embeddable).
+ // Defaults to true.
+ Embeddable bool `json:"embeddable" api:"nullable"`
+ // Flag content as AI generated on TikTok
+ IsAIGenerated bool `json:"is_ai_generated" api:"nullable"`
+ // Will create a draft upload to TikTok, posting will need to be completed from
+ // within the app
+ IsDraft bool `json:"is_draft" api:"nullable"`
+ // The video's license (maps to status.license). "youtube" is the standard YouTube
+ // license; "creativeCommon" is Creative Commons.
+ //
+ // Any of "youtube", "creativeCommon".
+ License string `json:"license" api:"nullable"`
+ // Pinterest post link
+ Link string `json:"link" api:"nullable"`
+ // Page id with a location that you want to tag the image or video with (Instagram
+ // and Facebook)
+ Location string `json:"location" api:"nullable"`
+ // If true will notify YouTube the video is intended for kids, defaults to false
+ MadeForKids bool `json:"made_for_kids" api:"nullable"`
+ // Overrides the `media` from the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Post placement for Facebook/Instagram/Threads
+ //
+ // Any of "reels", "timeline", "stories".
+ Placement string `json:"placement" api:"nullable"`
+ // Poll options for the twitter
+ Poll TwitterPoll `json:"poll"`
+ // Sets the privacy status for TikTok (private, public), or YouTube (private,
+ // public, unlisted)
+ //
+ // Any of "public", "private", "unlisted".
+ PrivacyStatus string `json:"privacy_status" api:"nullable"`
+ // If true, the extended video statistics are publicly viewable (maps to
+ // status.publicStatsViewable). Defaults to true.
+ PublicStatsViewable bool `json:"public_stats_viewable" api:"nullable"`
+ // ISO 8601 datetime at which the video should be published. Only honoured when
+ // privacy_status is "private" (maps to status.publishAt).
+ PublishAt string `json:"publish_at" api:"nullable"`
+ // Id of the tweet you want to quote
+ QuoteTweetID string `json:"quote_tweet_id"`
+ // ISO 8601 date (YYYY-MM-DD) or datetime when the video was recorded (maps to
+ // recordingDetails.recordingDate).
+ RecordingDate string `json:"recording_date" api:"nullable"`
+ // Who can reply to the tweet
+ //
+ // Any of "following", "mentionedUsers", "subscribers", "verified".
+ ReplySettings string `json:"reply_settings" api:"nullable"`
+ // LinkedIn UGC post id to reshare. The caption is used as the reshare commentary.
+ ResharePostID string `json:"reshare_post_id" api:"nullable"`
+ // If true, include the caption on each image in a Facebook carousel upload; if
+ // false, only include it on the final carousel post
+ SetCaptionForEachImage bool `json:"set_caption_for_each_image" api:"nullable"`
+ // If false Instagram video posts will only be shown in the Reels tab
+ ShareToFeed bool `json:"share_to_feed" api:"nullable"`
+ // YouTube video tags
+ Tags []string `json:"tags" api:"nullable"`
+ // Overrides the `title` from the post (Pinterest, TikTok, YouTube)
+ Title string `json:"title" api:"nullable"`
+ // Instagram trial reel type, when passed will be created as a trial reel. If
+ // manual the trial reel can be manually graduated in the native app. If perfomance
+ // the trial reel will be automatically graduated if the trial reel performs well.
+ //
+ // Any of "manual", "performance".
+ TrialReelType string `json:"trial_reel_type" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Localizations respjson.Field
+ AllowComment respjson.Field
+ AllowDuet respjson.Field
+ AllowStitch respjson.Field
+ AudioName respjson.Field
+ AutoAddMusic respjson.Field
+ BoardIDs respjson.Field
+ Caption respjson.Field
+ CategoryID respjson.Field
+ Collaborators respjson.Field
+ CommunityID respjson.Field
+ ContainsSyntheticMedia respjson.Field
+ DefaultLanguage respjson.Field
+ DiscloseBrandedContent respjson.Field
+ DiscloseYourBrand respjson.Field
+ Embeddable respjson.Field
+ IsAIGenerated respjson.Field
+ IsDraft respjson.Field
+ License respjson.Field
+ Link respjson.Field
+ Location respjson.Field
+ MadeForKids respjson.Field
+ Media respjson.Field
+ Placement respjson.Field
+ Poll respjson.Field
+ PrivacyStatus respjson.Field
+ PublicStatsViewable respjson.Field
+ PublishAt respjson.Field
+ QuoteTweetID respjson.Field
+ RecordingDate respjson.Field
+ ReplySettings respjson.Field
+ ResharePostID respjson.Field
+ SetCaptionForEachImage respjson.Field
+ ShareToFeed respjson.Field
+ Tags respjson.Field
+ Title respjson.Field
+ TrialReelType respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r BlueskyConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *BlueskyConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
+func (r AccountConfigurationConfiguration) RawJSON() string { return r.JSON.raw }
+func (r *AccountConfigurationConfiguration) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type BlueskyConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
+type AccountConfigurationConfigurationLocalization struct {
+ Description string `json:"description" api:"nullable"`
+ Title string `json:"title" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
+ Description respjson.Field
+ Title respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r BlueskyConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *BlueskyConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type BlueskyConfigurationDtoParam struct {
- // Overrides the `caption` from the post
- Caption any `json:"caption,omitzero"`
- // Overrides the `media` from the post
- Media []BlueskyConfigurationDtoMediaParam `json:"media,omitzero"`
- paramObj
-}
-
-func (r BlueskyConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
- type shadow BlueskyConfigurationDtoParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *BlueskyConfigurationDtoParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The property URL is required.
-type BlueskyConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []BlueskyConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r BlueskyConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow BlueskyConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *BlueskyConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type BlueskyConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
-}
-
-func (r BlueskyConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow BlueskyConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *BlueskyConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func init() {
- apijson.RegisterFieldValidator[BlueskyConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[BlueskyConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
-// The properties Caption, SocialAccounts are required.
-type CreateSocialPostParam struct {
- // Caption text for the post
- Caption string `json:"caption" api:"required"`
- // Array of social account IDs for posting
- SocialAccounts []string `json:"social_accounts,omitzero" api:"required"`
- // Array of social account IDs for posting
- ExternalID param.Opt[string] `json:"external_id,omitzero"`
- // If isDraft is set then the post will not be processed
- IsDraft param.Opt[bool] `json:"isDraft,omitzero"`
- // Scheduled date and time for the post, setting to null or undefined will post
- // instantly
- ScheduledAt param.Opt[time.Time] `json:"scheduled_at,omitzero" format:"date-time"`
- // Account-specific configurations for the post
- AccountConfigurations []CreateSocialPostAccountConfigurationParam `json:"account_configurations,omitzero"`
- // Array of media associated with the post. If multiple media items are provided
- // and the placement is `stories`, individual posts are created per media item.
- Media []CreateSocialPostMediaParam `json:"media,omitzero"`
- // Platform-specific configurations for the post
- PlatformConfigurations PlatformConfigurationsDtoParam `json:"platform_configurations,omitzero"`
- paramObj
-}
-
-func (r CreateSocialPostParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *CreateSocialPostParam) UnmarshalJSON(data []byte) error {
+func (r AccountConfigurationConfigurationLocalization) RawJSON() string { return r.JSON.raw }
+func (r *AccountConfigurationConfigurationLocalization) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
// The properties Configuration, SocialAccountID are required.
-type CreateSocialPostAccountConfigurationParam struct {
+type AccountConfigurationParam struct {
// Configuration for the social account
- Configuration CreateSocialPostAccountConfigurationConfigurationParam `json:"configuration,omitzero" api:"required"`
+ Configuration AccountConfigurationConfigurationParam `json:"configuration,omitzero" api:"required"`
// ID of the social account, you want to apply the configuration to
SocialAccountID string `json:"social_account_id" api:"required"`
paramObj
}
-func (r CreateSocialPostAccountConfigurationParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostAccountConfigurationParam
+func (r AccountConfigurationParam) MarshalJSON() (data []byte, err error) {
+ type shadow AccountConfigurationParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *CreateSocialPostAccountConfigurationParam) UnmarshalJSON(data []byte) error {
+func (r *AccountConfigurationParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
// Configuration for the social account
-type CreateSocialPostAccountConfigurationConfigurationParam struct {
+//
+// The property Localizations is required.
+type AccountConfigurationConfigurationParam struct {
+ // Per-language localizations for the video title and description. Keys are BCP-47
+ // language tags (e.g. "fr", "es"). Maps to localizations on the YouTube Data API
+ // videos resource.
+ Localizations map[string]AccountConfigurationConfigurationLocalizationParam `json:"localizations,omitzero" api:"required"`
// Allow comments on TikTok
AllowComment param.Opt[bool] `json:"allow_comment,omitzero"`
// Allow duets on TikTok
AllowDuet param.Opt[bool] `json:"allow_duet,omitzero"`
// Allow stitch on TikTok
AllowStitch param.Opt[bool] `json:"allow_stitch,omitzero"`
+ // Display name for the audio track on Instagram Reels. Only honored on Reels
+ // uploads, and only when the audio is original (Meta silently ignores it on
+ // licensed/fingerprinted tracks).
+ AudioName param.Opt[string] `json:"audio_name,omitzero"`
// Will automatically add music to photo posts on TikTok
AutoAddMusic param.Opt[bool] `json:"auto_add_music,omitzero"`
+ // YouTube video category id (maps to snippet.categoryId; see YouTube Data API
+ // videoCategories.list)
+ CategoryID param.Opt[string] `json:"category_id,omitzero"`
+ // If true, marks the YouTube video as containing altered or synthetic content per
+ // YouTube's disclosure policy. Sets status.containsSyntheticMedia on the
+ // videos.insert call; YouTube adds a "How this content was made" label to the
+ // description automatically.
+ ContainsSyntheticMedia param.Opt[bool] `json:"contains_synthetic_media,omitzero"`
+ // Default language of the video (BCP-47 language tag, e.g. "en"). Maps to
+ // snippet.defaultLanguage.
+ DefaultLanguage param.Opt[string] `json:"default_language,omitzero"`
// Disclose branded content on TikTok
DiscloseBrandedContent param.Opt[bool] `json:"disclose_branded_content,omitzero"`
// Disclose your brand on TikTok
DiscloseYourBrand param.Opt[bool] `json:"disclose_your_brand,omitzero"`
+ // If true the video can be embedded on other websites (maps to status.embeddable).
+ // Defaults to true.
+ Embeddable param.Opt[bool] `json:"embeddable,omitzero"`
// Flag content as AI generated on TikTok
IsAIGenerated param.Opt[bool] `json:"is_ai_generated,omitzero"`
// Will create a draft upload to TikTok, posting will need to be completed from
@@ -354,12 +375,23 @@ type CreateSocialPostAccountConfigurationConfigurationParam struct {
Location param.Opt[string] `json:"location,omitzero"`
// If true will notify YouTube the video is intended for kids, defaults to false
MadeForKids param.Opt[bool] `json:"made_for_kids,omitzero"`
+ // If true, the extended video statistics are publicly viewable (maps to
+ // status.publicStatsViewable). Defaults to true.
+ PublicStatsViewable param.Opt[bool] `json:"public_stats_viewable,omitzero"`
+ // ISO 8601 datetime at which the video should be published. Only honoured when
+ // privacy_status is "private" (maps to status.publishAt).
+ PublishAt param.Opt[string] `json:"publish_at,omitzero"`
+ // ISO 8601 date (YYYY-MM-DD) or datetime when the video was recorded (maps to
+ // recordingDetails.recordingDate).
+ RecordingDate param.Opt[string] `json:"recording_date,omitzero"`
+ // LinkedIn UGC post id to reshare. The caption is used as the reshare commentary.
+ ResharePostID param.Opt[string] `json:"reshare_post_id,omitzero"`
// If true, include the caption on each image in a Facebook carousel upload; if
// false, only include it on the final carousel post
SetCaptionForEachImage param.Opt[bool] `json:"set_caption_for_each_image,omitzero"`
// If false Instagram video posts will only be shown in the Reels tab
ShareToFeed param.Opt[bool] `json:"share_to_feed,omitzero"`
- // Overrides the `title` from the post
+ // Overrides the `title` from the post (Pinterest, TikTok, YouTube)
Title param.Opt[string] `json:"title,omitzero"`
// Id of the twitter community to post to
CommunityID param.Opt[string] `json:"community_id,omitzero"`
@@ -372,8 +404,13 @@ type CreateSocialPostAccountConfigurationConfigurationParam struct {
// List of page ids or users to invite as collaborators for a Video Reel (Instagram
// and Facebook)
Collaborators [][]any `json:"collaborators,omitzero"`
+ // The video's license (maps to status.license). "youtube" is the standard YouTube
+ // license; "creativeCommon" is Creative Commons.
+ //
+ // Any of "youtube", "creativeCommon".
+ License string `json:"license,omitzero"`
// Overrides the `media` from the post
- Media []CreateSocialPostAccountConfigurationConfigurationMediaParam `json:"media,omitzero"`
+ Media []SocialPostMediaParam `json:"media,omitzero"`
// Post placement for Facebook/Instagram/Threads
//
// Any of "reels", "timeline", "stories".
@@ -387,6 +424,8 @@ type CreateSocialPostAccountConfigurationConfigurationParam struct {
//
// Any of "following", "mentionedUsers", "subscribers", "verified".
ReplySettings string `json:"reply_settings,omitzero"`
+ // YouTube video tags
+ Tags []string `json:"tags,omitzero"`
// Instagram trial reel type, when passed will be created as a trial reel. If
// manual the trial reel can be manually graduated in the native app. If perfomance
// the trial reel will be automatically graduated if the trial reel performs well.
@@ -394,190 +433,143 @@ type CreateSocialPostAccountConfigurationConfigurationParam struct {
// Any of "manual", "performance".
TrialReelType string `json:"trial_reel_type,omitzero"`
// Poll options for the twitter
- Poll CreateSocialPostAccountConfigurationConfigurationPollParam `json:"poll,omitzero"`
+ Poll TwitterPollParam `json:"poll,omitzero"`
paramObj
}
-func (r CreateSocialPostAccountConfigurationConfigurationParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostAccountConfigurationConfigurationParam
+func (r AccountConfigurationConfigurationParam) MarshalJSON() (data []byte, err error) {
+ type shadow AccountConfigurationConfigurationParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *CreateSocialPostAccountConfigurationConfigurationParam) UnmarshalJSON(data []byte) error {
+func (r *AccountConfigurationConfigurationParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
func init() {
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationParam](
+ apijson.RegisterFieldValidator[AccountConfigurationConfigurationParam](
+ "license", "youtube", "creativeCommon",
+ )
+ apijson.RegisterFieldValidator[AccountConfigurationConfigurationParam](
"placement", "reels", "timeline", "stories",
)
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationParam](
+ apijson.RegisterFieldValidator[AccountConfigurationConfigurationParam](
"privacy_status", "public", "private", "unlisted",
)
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationParam](
+ apijson.RegisterFieldValidator[AccountConfigurationConfigurationParam](
"reply_settings", "following", "mentionedUsers", "subscribers", "verified",
)
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationParam](
+ apijson.RegisterFieldValidator[AccountConfigurationConfigurationParam](
"trial_reel_type", "manual", "performance",
)
}
-// The property URL is required.
-type CreateSocialPostAccountConfigurationConfigurationMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []CreateSocialPostAccountConfigurationConfigurationMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
+type AccountConfigurationConfigurationLocalizationParam struct {
+ Description param.Opt[string] `json:"description,omitzero"`
+ Title param.Opt[string] `json:"title,omitzero"`
paramObj
}
-func (r CreateSocialPostAccountConfigurationConfigurationMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostAccountConfigurationConfigurationMediaParam
+func (r AccountConfigurationConfigurationLocalizationParam) MarshalJSON() (data []byte, err error) {
+ type shadow AccountConfigurationConfigurationLocalizationParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *CreateSocialPostAccountConfigurationConfigurationMediaParam) UnmarshalJSON(data []byte) error {
+func (r *AccountConfigurationConfigurationLocalizationParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The properties ID, Platform, Type are required.
-type CreateSocialPostAccountConfigurationConfigurationMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
+type BlueskyConfigurationDto struct {
+ // Overrides the `caption` from the post
+ Caption any `json:"caption" api:"nullable"`
+ // Overrides the `media` from the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Caption respjson.Field
+ Media respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
}
-func (r CreateSocialPostAccountConfigurationConfigurationMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostAccountConfigurationConfigurationMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *CreateSocialPostAccountConfigurationConfigurationMediaTagParam) UnmarshalJSON(data []byte) error {
+// Returns the unmodified JSON received from the API
+func (r BlueskyConfigurationDto) RawJSON() string { return r.JSON.raw }
+func (r *BlueskyConfigurationDto) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func init() {
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationMediaTagParam](
- "type", "user", "product",
- )
+// ToParam converts this BlueskyConfigurationDto to a BlueskyConfigurationDtoParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// BlueskyConfigurationDtoParam.Overrides()
+func (r BlueskyConfigurationDto) ToParam() BlueskyConfigurationDtoParam {
+ return param.Override[BlueskyConfigurationDtoParam](json.RawMessage(r.RawJSON()))
}
-// Poll options for the twitter
-//
-// The properties DurationMinutes, Options are required.
-type CreateSocialPostAccountConfigurationConfigurationPollParam struct {
- // Duration of the poll in minutes
- DurationMinutes float64 `json:"duration_minutes" api:"required"`
- // The choices of the poll, requiring 2-4 options
- Options []string `json:"options,omitzero" api:"required"`
- // Who can reply to the tweet
- //
- // Any of "following", "mentionedUsers", "subscribers", "verified".
- ReplySettings string `json:"reply_settings,omitzero"`
+type BlueskyConfigurationDtoParam struct {
+ // Overrides the `caption` from the post
+ Caption any `json:"caption,omitzero"`
+ // Overrides the `media` from the post
+ Media []SocialPostMediaParam `json:"media,omitzero"`
paramObj
}
-func (r CreateSocialPostAccountConfigurationConfigurationPollParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostAccountConfigurationConfigurationPollParam
+func (r BlueskyConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
+ type shadow BlueskyConfigurationDtoParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *CreateSocialPostAccountConfigurationConfigurationPollParam) UnmarshalJSON(data []byte) error {
+func (r *BlueskyConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func init() {
- apijson.RegisterFieldValidator[CreateSocialPostAccountConfigurationConfigurationPollParam](
- "reply_settings", "following", "mentionedUsers", "subscribers", "verified",
- )
-}
-
-// The property URL is required.
-type CreateSocialPostMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []CreateSocialPostMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
+// The properties Caption, SocialAccounts are required.
+type CreateSocialPostParam struct {
+ // Caption text for the post
+ Caption string `json:"caption" api:"required"`
+ // Array of social account IDs for posting
+ SocialAccounts []string `json:"social_accounts,omitzero" api:"required"`
+ // Array of social account IDs for posting
+ ExternalID param.Opt[string] `json:"external_id,omitzero"`
+ // If isDraft is set then the post will not be processed
+ IsDraft param.Opt[bool] `json:"isDraft,omitzero"`
+ // Scheduled date and time for the post, setting to null or undefined will post
+ // instantly
+ ScheduledAt param.Opt[time.Time] `json:"scheduled_at,omitzero" format:"date-time"`
+ // Account-specific configurations for the post
+ AccountConfigurations []AccountConfigurationParam `json:"account_configurations,omitzero"`
+ // Array of media associated with the post. If multiple media items are provided
+ // and the placement is `stories`, individual posts are created per media item.
+ Media []SocialPostMediaParam `json:"media,omitzero"`
+ // Platform-specific configurations for the post
+ PlatformConfigurations PlatformConfigurationsDtoParam `json:"platform_configurations,omitzero"`
paramObj
}
-func (r CreateSocialPostMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostMediaParam
+func (r CreateSocialPostParam) MarshalJSON() (data []byte, err error) {
+ type shadow CreateSocialPostParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *CreateSocialPostMediaParam) UnmarshalJSON(data []byte) error {
+func (r *CreateSocialPostParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The properties ID, Platform, Type are required.
-type CreateSocialPostMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
+type DeleteEntityResponse struct {
+ // Whether or not the entity was deleted
+ Success bool `json:"success" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Success respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
}
-func (r CreateSocialPostMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow CreateSocialPostMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *CreateSocialPostMediaTagParam) UnmarshalJSON(data []byte) error {
+// Returns the unmodified JSON received from the API
+func (r DeleteEntityResponse) RawJSON() string { return r.JSON.raw }
+func (r *DeleteEntityResponse) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func init() {
- apijson.RegisterFieldValidator[CreateSocialPostMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[CreateSocialPostMediaTagParam](
- "type", "user", "product",
- )
-}
-
type FacebookConfigurationDto struct {
// Overrides the `caption` from the post
Caption any `json:"caption" api:"nullable"`
@@ -586,7 +578,7 @@ type FacebookConfigurationDto struct {
// Page id with a location that you want to tag the image or video with
Location string `json:"location" api:"nullable"`
// Overrides the `media` from the post
- Media []FacebookConfigurationDtoMedia `json:"media" api:"nullable"`
+ Media []SocialPostMedia `json:"media" api:"nullable"`
// Facebook post placement
//
// Any of "reels", "stories", "timeline".
@@ -623,73 +615,6 @@ func (r FacebookConfigurationDto) ToParam() FacebookConfigurationDtoParam {
return param.Override[FacebookConfigurationDtoParam](json.RawMessage(r.RawJSON()))
}
-type FacebookConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []FacebookConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r FacebookConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *FacebookConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type FacebookConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r FacebookConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *FacebookConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
// Facebook post placement
type FacebookConfigurationDtoPlacement string
@@ -710,7 +635,7 @@ type FacebookConfigurationDtoParam struct {
// List of page ids to invite as collaborators for a Video Reel
Collaborators [][]any `json:"collaborators,omitzero"`
// Overrides the `media` from the post
- Media []FacebookConfigurationDtoMediaParam `json:"media,omitzero"`
+ Media []SocialPostMediaParam `json:"media,omitzero"`
// Facebook post placement
//
// Any of "reels", "stories", "timeline".
@@ -726,93 +651,34 @@ func (r *FacebookConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The property URL is required.
-type FacebookConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []FacebookConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r FacebookConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow FacebookConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *FacebookConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type FacebookConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
+type InstagramConfigurationDto struct {
+ // Display name for the audio track on Instagram Reels. Only honored on Reels
+ // uploads, and only when the audio is original (Meta silently ignores it on
+ // licensed/fingerprinted tracks).
+ AudioName string `json:"audio_name" api:"nullable"`
+ // Overrides the `caption` from the post
+ Caption any `json:"caption" api:"nullable"`
+ // Instagram usernames to be tagged as a collaborator
+ Collaborators []string `json:"collaborators" api:"nullable"`
+ // Page id with a location that you want to tag the image or video with
+ Location string `json:"location" api:"nullable"`
+ // Overrides the `media` from the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Instagram post placement
//
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
-}
-
-func (r FacebookConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow FacebookConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *FacebookConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func init() {
- apijson.RegisterFieldValidator[FacebookConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[FacebookConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
-type InstagramConfigurationDto struct {
- // Overrides the `caption` from the post
- Caption any `json:"caption" api:"nullable"`
- // Instagram usernames to be tagged as a collaborator
- Collaborators []string `json:"collaborators" api:"nullable"`
- // Page id with a location that you want to tag the image or video with
- Location string `json:"location" api:"nullable"`
- // Overrides the `media` from the post
- Media []InstagramConfigurationDtoMedia `json:"media" api:"nullable"`
- // Instagram post placement
- //
- // Any of "reels", "stories", "timeline".
- Placement InstagramConfigurationDtoPlacement `json:"placement" api:"nullable"`
- // If false video posts will only be shown in the Reels tab
- ShareToFeed bool `json:"share_to_feed" api:"nullable"`
- // Instagram trial reel type, when passed will be created as a trial reel. If
- // manual the trial reel can be manually graduated in the native app. If perfomance
- // the trial reel will be automatically graduated if the trial reel performs well.
+ // Any of "reels", "stories", "timeline".
+ Placement InstagramConfigurationDtoPlacement `json:"placement" api:"nullable"`
+ // If false video posts will only be shown in the Reels tab
+ ShareToFeed bool `json:"share_to_feed" api:"nullable"`
+ // Instagram trial reel type, when passed will be created as a trial reel. If
+ // manual the trial reel can be manually graduated in the native app. If perfomance
+ // the trial reel will be automatically graduated if the trial reel performs well.
//
// Any of "manual", "performance".
TrialReelType InstagramConfigurationDtoTrialReelType `json:"trial_reel_type" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
+ AudioName respjson.Field
Caption respjson.Field
Collaborators respjson.Field
Location respjson.Field
@@ -841,73 +707,6 @@ func (r InstagramConfigurationDto) ToParam() InstagramConfigurationDtoParam {
return param.Override[InstagramConfigurationDtoParam](json.RawMessage(r.RawJSON()))
}
-type InstagramConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []InstagramConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r InstagramConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *InstagramConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type InstagramConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r InstagramConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *InstagramConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
// Instagram post placement
type InstagramConfigurationDtoPlacement string
@@ -928,6 +727,10 @@ const (
)
type InstagramConfigurationDtoParam struct {
+ // Display name for the audio track on Instagram Reels. Only honored on Reels
+ // uploads, and only when the audio is original (Meta silently ignores it on
+ // licensed/fingerprinted tracks).
+ AudioName param.Opt[string] `json:"audio_name,omitzero"`
// Page id with a location that you want to tag the image or video with
Location param.Opt[string] `json:"location,omitzero"`
// If false video posts will only be shown in the Reels tab
@@ -937,7 +740,7 @@ type InstagramConfigurationDtoParam struct {
// Instagram usernames to be tagged as a collaborator
Collaborators []string `json:"collaborators,omitzero"`
// Overrides the `media` from the post
- Media []InstagramConfigurationDtoMediaParam `json:"media,omitzero"`
+ Media []SocialPostMediaParam `json:"media,omitzero"`
// Instagram post placement
//
// Any of "reels", "stories", "timeline".
@@ -959,81 +762,20 @@ func (r *InstagramConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The property URL is required.
-type InstagramConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []InstagramConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r InstagramConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow InstagramConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *InstagramConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type InstagramConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
-}
-
-func (r InstagramConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow InstagramConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *InstagramConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func init() {
- apijson.RegisterFieldValidator[InstagramConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[InstagramConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
type LinkedinConfigurationDto struct {
// Overrides the `caption` from the post
Caption any `json:"caption" api:"nullable"`
// Overrides the `media` from the post
- Media []LinkedinConfigurationDtoMedia `json:"media" api:"nullable"`
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // LinkedIn UGC post id to reshare. The caption is used as the reshare commentary.
+ ResharePostID string `json:"reshare_post_id" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Caption respjson.Field
- Media respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Caption respjson.Field
+ Media respjson.Field
+ ResharePostID respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
@@ -1053,340 +795,85 @@ func (r LinkedinConfigurationDto) ToParam() LinkedinConfigurationDtoParam {
return param.Override[LinkedinConfigurationDtoParam](json.RawMessage(r.RawJSON()))
}
-type LinkedinConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []LinkedinConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
+type LinkedinConfigurationDtoParam struct {
+ // LinkedIn UGC post id to reshare. The caption is used as the reshare commentary.
+ ResharePostID param.Opt[string] `json:"reshare_post_id,omitzero"`
+ // Overrides the `caption` from the post
+ Caption any `json:"caption,omitzero"`
+ // Overrides the `media` from the post
+ Media []SocialPostMediaParam `json:"media,omitzero"`
+ paramObj
}
-// Returns the unmodified JSON received from the API
-func (r LinkedinConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *LinkedinConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
+func (r LinkedinConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
+ type shadow LinkedinConfigurationDtoParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *LinkedinConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type LinkedinConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
+type PinterestConfigurationDto struct {
+ // Pinterest board IDs
+ BoardIDs []string `json:"board_ids" api:"nullable"`
+ // Overrides the `caption` from the post
+ Caption any `json:"caption" api:"nullable"`
+ // Pinterest post link
+ Link string `json:"link" api:"nullable"`
+ // Overrides the `media` from the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Overrides the `title` from the post for Pinterest
+ Title string `json:"title" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
+ BoardIDs respjson.Field
+ Caption respjson.Field
+ Link respjson.Field
+ Media respjson.Field
+ Title respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r LinkedinConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *LinkedinConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
+func (r PinterestConfigurationDto) RawJSON() string { return r.JSON.raw }
+func (r *PinterestConfigurationDto) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type LinkedinConfigurationDtoParam struct {
+// ToParam converts this PinterestConfigurationDto to a
+// PinterestConfigurationDtoParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// PinterestConfigurationDtoParam.Overrides()
+func (r PinterestConfigurationDto) ToParam() PinterestConfigurationDtoParam {
+ return param.Override[PinterestConfigurationDtoParam](json.RawMessage(r.RawJSON()))
+}
+
+type PinterestConfigurationDtoParam struct {
+ // Pinterest post link
+ Link param.Opt[string] `json:"link,omitzero"`
+ // Overrides the `title` from the post for Pinterest
+ Title param.Opt[string] `json:"title,omitzero"`
+ // Pinterest board IDs
+ BoardIDs []string `json:"board_ids,omitzero"`
// Overrides the `caption` from the post
Caption any `json:"caption,omitzero"`
// Overrides the `media` from the post
- Media []LinkedinConfigurationDtoMediaParam `json:"media,omitzero"`
+ Media []SocialPostMediaParam `json:"media,omitzero"`
paramObj
}
-func (r LinkedinConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
- type shadow LinkedinConfigurationDtoParam
+func (r PinterestConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
+ type shadow PinterestConfigurationDtoParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *LinkedinConfigurationDtoParam) UnmarshalJSON(data []byte) error {
+func (r *PinterestConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The property URL is required.
-type LinkedinConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []LinkedinConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r LinkedinConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow LinkedinConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *LinkedinConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type LinkedinConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
-}
-
-func (r LinkedinConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow LinkedinConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *LinkedinConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func init() {
- apijson.RegisterFieldValidator[LinkedinConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[LinkedinConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
-type PinterestConfigurationDto struct {
- // Pinterest board IDs
- BoardIDs []string `json:"board_ids" api:"nullable"`
- // Overrides the `caption` from the post
- Caption any `json:"caption" api:"nullable"`
- // Pinterest post link
- Link string `json:"link" api:"nullable"`
- // Overrides the `media` from the post
- Media []PinterestConfigurationDtoMedia `json:"media" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- BoardIDs respjson.Field
- Caption respjson.Field
- Link respjson.Field
- Media respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PinterestConfigurationDto) RawJSON() string { return r.JSON.raw }
-func (r *PinterestConfigurationDto) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// ToParam converts this PinterestConfigurationDto to a
-// PinterestConfigurationDtoParam.
-//
-// Warning: the fields of the param type will not be present. ToParam should only
-// be used at the last possible moment before sending a request. Test for this with
-// PinterestConfigurationDtoParam.Overrides()
-func (r PinterestConfigurationDto) ToParam() PinterestConfigurationDtoParam {
- return param.Override[PinterestConfigurationDtoParam](json.RawMessage(r.RawJSON()))
-}
-
-type PinterestConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []PinterestConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PinterestConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *PinterestConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PinterestConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r PinterestConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *PinterestConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type PinterestConfigurationDtoParam struct {
- // Pinterest post link
- Link param.Opt[string] `json:"link,omitzero"`
- // Pinterest board IDs
- BoardIDs []string `json:"board_ids,omitzero"`
- // Overrides the `caption` from the post
- Caption any `json:"caption,omitzero"`
- // Overrides the `media` from the post
- Media []PinterestConfigurationDtoMediaParam `json:"media,omitzero"`
- paramObj
-}
-
-func (r PinterestConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
- type shadow PinterestConfigurationDtoParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *PinterestConfigurationDtoParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The property URL is required.
-type PinterestConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []PinterestConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r PinterestConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow PinterestConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *PinterestConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type PinterestConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
-}
-
-func (r PinterestConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow PinterestConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *PinterestConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func init() {
- apijson.RegisterFieldValidator[PinterestConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[PinterestConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
type PlatformConfigurationsDto struct {
// Bluesky configuration
Bluesky BlueskyConfigurationDto `json:"bluesky" api:"nullable"`
@@ -1477,7 +964,7 @@ type SocialPost struct {
// Unique identifier of the post
ID string `json:"id" api:"required"`
// Account-specific configurations for the post
- AccountConfigurations []SocialPostAccountConfiguration `json:"account_configurations" api:"required"`
+ AccountConfigurations []AccountConfiguration `json:"account_configurations" api:"required"`
// Caption text for the post
Caption string `json:"caption" api:"required"`
// Timestamp when the post was created
@@ -1500,577 +987,39 @@ type SocialPost struct {
UpdatedAt string `json:"updated_at" api:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
- AccountConfigurations respjson.Field
- Caption respjson.Field
- CreatedAt respjson.Field
- ExternalID respjson.Field
- Media respjson.Field
- PlatformConfigurations respjson.Field
- ScheduledAt respjson.Field
- SocialAccounts respjson.Field
- Status respjson.Field
- UpdatedAt respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPost) RawJSON() string { return r.JSON.raw }
-func (r *SocialPost) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type SocialPostAccountConfiguration struct {
- // Configuration for the social account
- Configuration SocialPostAccountConfigurationConfiguration `json:"configuration" api:"required"`
- // ID of the social account, you want to apply the configuration to
- SocialAccountID string `json:"social_account_id" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Configuration respjson.Field
- SocialAccountID respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostAccountConfiguration) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostAccountConfiguration) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// Configuration for the social account
-type SocialPostAccountConfigurationConfiguration struct {
- // Allow comments on TikTok
- AllowComment bool `json:"allow_comment" api:"nullable"`
- // Allow duets on TikTok
- AllowDuet bool `json:"allow_duet" api:"nullable"`
- // Allow stitch on TikTok
- AllowStitch bool `json:"allow_stitch" api:"nullable"`
- // Will automatically add music to photo posts on TikTok
- AutoAddMusic bool `json:"auto_add_music" api:"nullable"`
- // Pinterest board IDs
- BoardIDs []string `json:"board_ids" api:"nullable"`
- // Overrides the `caption` from the post
- Caption any `json:"caption" api:"nullable"`
- // List of page ids or users to invite as collaborators for a Video Reel (Instagram
- // and Facebook)
- Collaborators [][]any `json:"collaborators" api:"nullable"`
- // Id of the twitter community to post to
- CommunityID string `json:"community_id"`
- // Disclose branded content on TikTok
- DiscloseBrandedContent bool `json:"disclose_branded_content" api:"nullable"`
- // Disclose your brand on TikTok
- DiscloseYourBrand bool `json:"disclose_your_brand" api:"nullable"`
- // Flag content as AI generated on TikTok
- IsAIGenerated bool `json:"is_ai_generated" api:"nullable"`
- // Will create a draft upload to TikTok, posting will need to be completed from
- // within the app
- IsDraft bool `json:"is_draft" api:"nullable"`
- // Pinterest post link
- Link string `json:"link" api:"nullable"`
- // Page id with a location that you want to tag the image or video with (Instagram
- // and Facebook)
- Location string `json:"location" api:"nullable"`
- // If true will notify YouTube the video is intended for kids, defaults to false
- MadeForKids bool `json:"made_for_kids" api:"nullable"`
- // Overrides the `media` from the post
- Media []SocialPostAccountConfigurationConfigurationMedia `json:"media" api:"nullable"`
- // Post placement for Facebook/Instagram/Threads
- //
- // Any of "reels", "timeline", "stories".
- Placement string `json:"placement" api:"nullable"`
- // Poll options for the twitter
- Poll SocialPostAccountConfigurationConfigurationPoll `json:"poll"`
- // Sets the privacy status for TikTok (private, public), or YouTube (private,
- // public, unlisted)
- //
- // Any of "public", "private", "unlisted".
- PrivacyStatus string `json:"privacy_status" api:"nullable"`
- // Id of the tweet you want to quote
- QuoteTweetID string `json:"quote_tweet_id"`
- // Who can reply to the tweet
- //
- // Any of "following", "mentionedUsers", "subscribers", "verified".
- ReplySettings string `json:"reply_settings" api:"nullable"`
- // If true, include the caption on each image in a Facebook carousel upload; if
- // false, only include it on the final carousel post
- SetCaptionForEachImage bool `json:"set_caption_for_each_image" api:"nullable"`
- // If false Instagram video posts will only be shown in the Reels tab
- ShareToFeed bool `json:"share_to_feed" api:"nullable"`
- // Overrides the `title` from the post
- Title string `json:"title" api:"nullable"`
- // Instagram trial reel type, when passed will be created as a trial reel. If
- // manual the trial reel can be manually graduated in the native app. If perfomance
- // the trial reel will be automatically graduated if the trial reel performs well.
- //
- // Any of "manual", "performance".
- TrialReelType string `json:"trial_reel_type" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- AllowComment respjson.Field
- AllowDuet respjson.Field
- AllowStitch respjson.Field
- AutoAddMusic respjson.Field
- BoardIDs respjson.Field
- Caption respjson.Field
- Collaborators respjson.Field
- CommunityID respjson.Field
- DiscloseBrandedContent respjson.Field
- DiscloseYourBrand respjson.Field
- IsAIGenerated respjson.Field
- IsDraft respjson.Field
- Link respjson.Field
- Location respjson.Field
- MadeForKids respjson.Field
- Media respjson.Field
- Placement respjson.Field
- Poll respjson.Field
- PrivacyStatus respjson.Field
- QuoteTweetID respjson.Field
- ReplySettings respjson.Field
- SetCaptionForEachImage respjson.Field
- ShareToFeed respjson.Field
- Title respjson.Field
- TrialReelType respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostAccountConfigurationConfiguration) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostAccountConfigurationConfiguration) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type SocialPostAccountConfigurationConfigurationMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []SocialPostAccountConfigurationConfigurationMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostAccountConfigurationConfigurationMedia) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostAccountConfigurationConfigurationMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type SocialPostAccountConfigurationConfigurationMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostAccountConfigurationConfigurationMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostAccountConfigurationConfigurationMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// Poll options for the twitter
-type SocialPostAccountConfigurationConfigurationPoll struct {
- // Duration of the poll in minutes
- DurationMinutes float64 `json:"duration_minutes" api:"required"`
- // The choices of the poll, requiring 2-4 options
- Options []string `json:"options" api:"required"`
- // Who can reply to the tweet
- //
- // Any of "following", "mentionedUsers", "subscribers", "verified".
- ReplySettings string `json:"reply_settings"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- DurationMinutes respjson.Field
- Options respjson.Field
- ReplySettings respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostAccountConfigurationConfigurationPoll) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostAccountConfigurationConfigurationPoll) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type SocialPostMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []SocialPostMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostMedia) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type SocialPostMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// Current status of the post: draft, processed, scheduled, or processing
-type SocialPostStatus string
-
-const (
- SocialPostStatusDraft SocialPostStatus = "draft"
- SocialPostStatusScheduled SocialPostStatus = "scheduled"
- SocialPostStatusProcessing SocialPostStatus = "processing"
- SocialPostStatusProcessed SocialPostStatus = "processed"
-)
-
-type ThreadsConfigurationDto struct {
- // Overrides the `caption` from the post
- Caption any `json:"caption" api:"nullable"`
- // Overrides the `media` from the post
- Media []ThreadsConfigurationDtoMedia `json:"media" api:"nullable"`
- // Threads post placement
- //
- // Any of "reels", "timeline".
- Placement ThreadsConfigurationDtoPlacement `json:"placement" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Caption respjson.Field
- Media respjson.Field
- Placement respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r ThreadsConfigurationDto) RawJSON() string { return r.JSON.raw }
-func (r *ThreadsConfigurationDto) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// ToParam converts this ThreadsConfigurationDto to a ThreadsConfigurationDtoParam.
-//
-// Warning: the fields of the param type will not be present. ToParam should only
-// be used at the last possible moment before sending a request. Test for this with
-// ThreadsConfigurationDtoParam.Overrides()
-func (r ThreadsConfigurationDto) ToParam() ThreadsConfigurationDtoParam {
- return param.Override[ThreadsConfigurationDtoParam](json.RawMessage(r.RawJSON()))
-}
-
-type ThreadsConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []ThreadsConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r ThreadsConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *ThreadsConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type ThreadsConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r ThreadsConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *ThreadsConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// Threads post placement
-type ThreadsConfigurationDtoPlacement string
-
-const (
- ThreadsConfigurationDtoPlacementReels ThreadsConfigurationDtoPlacement = "reels"
- ThreadsConfigurationDtoPlacementTimeline ThreadsConfigurationDtoPlacement = "timeline"
-)
-
-type ThreadsConfigurationDtoParam struct {
- // Overrides the `caption` from the post
- Caption any `json:"caption,omitzero"`
- // Overrides the `media` from the post
- Media []ThreadsConfigurationDtoMediaParam `json:"media,omitzero"`
- // Threads post placement
- //
- // Any of "reels", "timeline".
- Placement ThreadsConfigurationDtoPlacement `json:"placement,omitzero"`
- paramObj
-}
-
-func (r ThreadsConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
- type shadow ThreadsConfigurationDtoParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *ThreadsConfigurationDtoParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The property URL is required.
-type ThreadsConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []ThreadsConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r ThreadsConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow ThreadsConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *ThreadsConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type ThreadsConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
-}
-
-func (r ThreadsConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow ThreadsConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *ThreadsConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-func init() {
- apijson.RegisterFieldValidator[ThreadsConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[ThreadsConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
-type TiktokConfiguration struct {
- // Allow comments on TikTok
- AllowComment bool `json:"allow_comment" api:"nullable"`
- // Allow duets on TikTok
- AllowDuet bool `json:"allow_duet" api:"nullable"`
- // Allow stitch on TikTok
- AllowStitch bool `json:"allow_stitch" api:"nullable"`
- // Will automatically add music to photo posts
- AutoAddMusic bool `json:"auto_add_music" api:"nullable"`
- // Overrides the `caption` from the post
- Caption any `json:"caption" api:"nullable"`
- // Disclose branded content on TikTok
- DiscloseBrandedContent bool `json:"disclose_branded_content" api:"nullable"`
- // Disclose your brand on TikTok
- DiscloseYourBrand bool `json:"disclose_your_brand" api:"nullable"`
- // Flag content as AI generated on TikTok
- IsAIGenerated bool `json:"is_ai_generated" api:"nullable"`
- // Will create a draft upload to TikTok, posting will need to be completed from
- // within the app
- IsDraft bool `json:"is_draft" api:"nullable"`
- // Overrides the `media` from the post
- Media []TiktokConfigurationMedia `json:"media" api:"nullable"`
- // Sets the privacy status for TikTok (private, public)
- PrivacyStatus string `json:"privacy_status" api:"nullable"`
- // Overrides the `title` from the post
- Title string `json:"title" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- AllowComment respjson.Field
- AllowDuet respjson.Field
- AllowStitch respjson.Field
- AutoAddMusic respjson.Field
- Caption respjson.Field
- DiscloseBrandedContent respjson.Field
- DiscloseYourBrand respjson.Field
- IsAIGenerated respjson.Field
- IsDraft respjson.Field
+ ID respjson.Field
+ AccountConfigurations respjson.Field
+ Caption respjson.Field
+ CreatedAt respjson.Field
+ ExternalID respjson.Field
Media respjson.Field
- PrivacyStatus respjson.Field
- Title respjson.Field
+ PlatformConfigurations respjson.Field
+ ScheduledAt respjson.Field
+ SocialAccounts respjson.Field
+ Status respjson.Field
+ UpdatedAt respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r TiktokConfiguration) RawJSON() string { return r.JSON.raw }
-func (r *TiktokConfiguration) UnmarshalJSON(data []byte) error {
+func (r SocialPost) RawJSON() string { return r.JSON.raw }
+func (r *SocialPost) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// ToParam converts this TiktokConfiguration to a TiktokConfigurationParam.
-//
-// Warning: the fields of the param type will not be present. ToParam should only
-// be used at the last possible moment before sending a request. Test for this with
-// TiktokConfigurationParam.Overrides()
-func (r TiktokConfiguration) ToParam() TiktokConfigurationParam {
- return param.Override[TiktokConfigurationParam](json.RawMessage(r.RawJSON()))
-}
+// Current status of the post: draft, processed, scheduled, or processing
+type SocialPostStatus string
+
+const (
+ SocialPostStatusDraft SocialPostStatus = "draft"
+ SocialPostStatusScheduled SocialPostStatus = "scheduled"
+ SocialPostStatusProcessing SocialPostStatus = "processing"
+ SocialPostStatusProcessed SocialPostStatus = "processed"
+)
-type TiktokConfigurationMedia struct {
+type SocialPostMedia struct {
// Public URL of the media
URL string `json:"url" api:"required"`
// If true the media will not be processed at all and instead be posted as is, this
@@ -2078,7 +1027,7 @@ type TiktokConfigurationMedia struct {
// requirements. Best used for larger files.
SkipProcessing bool `json:"skip_processing" api:"nullable"`
// List of tags to attach to the media
- Tags []TiktokConfigurationMediaTag `json:"tags" api:"nullable"`
+ Tags []SocialPostMediaTag `json:"tags" api:"nullable"`
// Timestamp in milliseconds of frame to use as thumbnail for the media
ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
// Public URL of the thumbnail for the media
@@ -2096,12 +1045,21 @@ type TiktokConfigurationMedia struct {
}
// Returns the unmodified JSON received from the API
-func (r TiktokConfigurationMedia) RawJSON() string { return r.JSON.raw }
-func (r *TiktokConfigurationMedia) UnmarshalJSON(data []byte) error {
+func (r SocialPostMedia) RawJSON() string { return r.JSON.raw }
+func (r *SocialPostMedia) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type TiktokConfigurationMediaTag struct {
+// ToParam converts this SocialPostMedia to a SocialPostMediaParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// SocialPostMediaParam.Overrides()
+func (r SocialPostMedia) ToParam() SocialPostMediaParam {
+ return param.Override[SocialPostMediaParam](json.RawMessage(r.RawJSON()))
+}
+
+type SocialPostMediaTag struct {
// Facebook User ID, Instagram Username or Instagram product id to tag
ID string `json:"id" api:"required"`
// The platform for the tags
@@ -2132,50 +1090,13 @@ type TiktokConfigurationMediaTag struct {
}
// Returns the unmodified JSON received from the API
-func (r TiktokConfigurationMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *TiktokConfigurationMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type TiktokConfigurationParam struct {
- // Allow comments on TikTok
- AllowComment param.Opt[bool] `json:"allow_comment,omitzero"`
- // Allow duets on TikTok
- AllowDuet param.Opt[bool] `json:"allow_duet,omitzero"`
- // Allow stitch on TikTok
- AllowStitch param.Opt[bool] `json:"allow_stitch,omitzero"`
- // Will automatically add music to photo posts
- AutoAddMusic param.Opt[bool] `json:"auto_add_music,omitzero"`
- // Disclose branded content on TikTok
- DiscloseBrandedContent param.Opt[bool] `json:"disclose_branded_content,omitzero"`
- // Disclose your brand on TikTok
- DiscloseYourBrand param.Opt[bool] `json:"disclose_your_brand,omitzero"`
- // Flag content as AI generated on TikTok
- IsAIGenerated param.Opt[bool] `json:"is_ai_generated,omitzero"`
- // Will create a draft upload to TikTok, posting will need to be completed from
- // within the app
- IsDraft param.Opt[bool] `json:"is_draft,omitzero"`
- // Sets the privacy status for TikTok (private, public)
- PrivacyStatus param.Opt[string] `json:"privacy_status,omitzero"`
- // Overrides the `title` from the post
- Title param.Opt[string] `json:"title,omitzero"`
- // Overrides the `caption` from the post
- Caption any `json:"caption,omitzero"`
- // Overrides the `media` from the post
- Media []TiktokConfigurationMediaParam `json:"media,omitzero"`
- paramObj
-}
-
-func (r TiktokConfigurationParam) MarshalJSON() (data []byte, err error) {
- type shadow TiktokConfigurationParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *TiktokConfigurationParam) UnmarshalJSON(data []byte) error {
+func (r SocialPostMediaTag) RawJSON() string { return r.JSON.raw }
+func (r *SocialPostMediaTag) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
// The property URL is required.
-type TiktokConfigurationMediaParam struct {
+type SocialPostMediaParam struct {
// Public URL of the media
URL string `json:"url" api:"required"`
// If true the media will not be processed at all and instead be posted as is, this
@@ -2183,7 +1104,7 @@ type TiktokConfigurationMediaParam struct {
// requirements. Best used for larger files.
SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
// List of tags to attach to the media
- Tags []TiktokConfigurationMediaTagParam `json:"tags,omitzero"`
+ Tags []SocialPostMediaTagParam `json:"tags,omitzero"`
// Timestamp in milliseconds of frame to use as thumbnail for the media
ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
// Public URL of the thumbnail for the media
@@ -2191,16 +1112,16 @@ type TiktokConfigurationMediaParam struct {
paramObj
}
-func (r TiktokConfigurationMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow TiktokConfigurationMediaParam
+func (r SocialPostMediaParam) MarshalJSON() (data []byte, err error) {
+ type shadow SocialPostMediaParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *TiktokConfigurationMediaParam) UnmarshalJSON(data []byte) error {
+func (r *SocialPostMediaParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
// The properties ID, Platform, Type are required.
-type TiktokConfigurationMediaTagParam struct {
+type SocialPostMediaTagParam struct {
// Facebook User ID, Instagram Username or Instagram product id to tag
ID string `json:"id" api:"required"`
// The platform for the tags
@@ -2221,159 +1142,225 @@ type TiktokConfigurationMediaTagParam struct {
paramObj
}
-func (r TiktokConfigurationMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow TiktokConfigurationMediaTagParam
+func (r SocialPostMediaTagParam) MarshalJSON() (data []byte, err error) {
+ type shadow SocialPostMediaTagParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *TiktokConfigurationMediaTagParam) UnmarshalJSON(data []byte) error {
+func (r *SocialPostMediaTagParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
func init() {
- apijson.RegisterFieldValidator[TiktokConfigurationMediaTagParam](
+ apijson.RegisterFieldValidator[SocialPostMediaTagParam](
"platform", "facebook", "instagram",
)
- apijson.RegisterFieldValidator[TiktokConfigurationMediaTagParam](
+ apijson.RegisterFieldValidator[SocialPostMediaTagParam](
"type", "user", "product",
)
}
-type TwitterConfigurationDto struct {
+type ThreadsConfigurationDto struct {
// Overrides the `caption` from the post
Caption any `json:"caption" api:"nullable"`
- // Id of the community to post to
- CommunityID string `json:"community_id"`
// Overrides the `media` from the post
- Media []TwitterConfigurationDtoMedia `json:"media" api:"nullable"`
- // Poll options for the tweet
- Poll TwitterConfigurationDtoPoll `json:"poll"`
- // Id of the tweet you want to quote
- QuoteTweetID string `json:"quote_tweet_id"`
- // Who can reply to the tweet
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Threads post placement
//
- // Any of "following", "mentionedUsers", "subscribers", "verified".
- ReplySettings TwitterConfigurationDtoReplySettings `json:"reply_settings" api:"nullable"`
+ // Any of "reels", "timeline".
+ Placement ThreadsConfigurationDtoPlacement `json:"placement" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Caption respjson.Field
- CommunityID respjson.Field
- Media respjson.Field
- Poll respjson.Field
- QuoteTweetID respjson.Field
- ReplySettings respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Caption respjson.Field
+ Media respjson.Field
+ Placement respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r TwitterConfigurationDto) RawJSON() string { return r.JSON.raw }
-func (r *TwitterConfigurationDto) UnmarshalJSON(data []byte) error {
+func (r ThreadsConfigurationDto) RawJSON() string { return r.JSON.raw }
+func (r *ThreadsConfigurationDto) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// ToParam converts this TwitterConfigurationDto to a TwitterConfigurationDtoParam.
+// ToParam converts this ThreadsConfigurationDto to a ThreadsConfigurationDtoParam.
//
// Warning: the fields of the param type will not be present. ToParam should only
// be used at the last possible moment before sending a request. Test for this with
-// TwitterConfigurationDtoParam.Overrides()
-func (r TwitterConfigurationDto) ToParam() TwitterConfigurationDtoParam {
- return param.Override[TwitterConfigurationDtoParam](json.RawMessage(r.RawJSON()))
+// ThreadsConfigurationDtoParam.Overrides()
+func (r ThreadsConfigurationDto) ToParam() ThreadsConfigurationDtoParam {
+ return param.Override[ThreadsConfigurationDtoParam](json.RawMessage(r.RawJSON()))
}
-type TwitterConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []TwitterConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
+// Threads post placement
+type ThreadsConfigurationDtoPlacement string
+
+const (
+ ThreadsConfigurationDtoPlacementReels ThreadsConfigurationDtoPlacement = "reels"
+ ThreadsConfigurationDtoPlacementTimeline ThreadsConfigurationDtoPlacement = "timeline"
+)
+
+type ThreadsConfigurationDtoParam struct {
+ // Overrides the `caption` from the post
+ Caption any `json:"caption,omitzero"`
+ // Overrides the `media` from the post
+ Media []SocialPostMediaParam `json:"media,omitzero"`
+ // Threads post placement
+ //
+ // Any of "reels", "timeline".
+ Placement ThreadsConfigurationDtoPlacement `json:"placement,omitzero"`
+ paramObj
+}
+
+func (r ThreadsConfigurationDtoParam) MarshalJSON() (data []byte, err error) {
+ type shadow ThreadsConfigurationDtoParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *ThreadsConfigurationDtoParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type TiktokConfiguration struct {
+ // Allow comments on TikTok
+ AllowComment bool `json:"allow_comment" api:"nullable"`
+ // Allow duets on TikTok
+ AllowDuet bool `json:"allow_duet" api:"nullable"`
+ // Allow stitch on TikTok
+ AllowStitch bool `json:"allow_stitch" api:"nullable"`
+ // Will automatically add music to photo posts
+ AutoAddMusic bool `json:"auto_add_music" api:"nullable"`
+ // Overrides the `caption` from the post
+ Caption any `json:"caption" api:"nullable"`
+ // Disclose branded content on TikTok
+ DiscloseBrandedContent bool `json:"disclose_branded_content" api:"nullable"`
+ // Disclose your brand on TikTok
+ DiscloseYourBrand bool `json:"disclose_your_brand" api:"nullable"`
+ // Flag content as AI generated on TikTok
+ IsAIGenerated bool `json:"is_ai_generated" api:"nullable"`
+ // Will create a draft upload to TikTok, posting will need to be completed from
+ // within the app
+ IsDraft bool `json:"is_draft" api:"nullable"`
+ // Overrides the `media` from the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Sets the privacy status for TikTok (private, public)
+ PrivacyStatus string `json:"privacy_status" api:"nullable"`
+ // Overrides the `title` from the post
+ Title string `json:"title" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ AllowComment respjson.Field
+ AllowDuet respjson.Field
+ AllowStitch respjson.Field
+ AutoAddMusic respjson.Field
+ Caption respjson.Field
+ DiscloseBrandedContent respjson.Field
+ DiscloseYourBrand respjson.Field
+ IsAIGenerated respjson.Field
+ IsDraft respjson.Field
+ Media respjson.Field
+ PrivacyStatus respjson.Field
+ Title respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r TwitterConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *TwitterConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
+func (r TiktokConfiguration) RawJSON() string { return r.JSON.raw }
+func (r *TiktokConfiguration) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type TwitterConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
+// ToParam converts this TiktokConfiguration to a TiktokConfigurationParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// TiktokConfigurationParam.Overrides()
+func (r TiktokConfiguration) ToParam() TiktokConfigurationParam {
+ return param.Override[TiktokConfigurationParam](json.RawMessage(r.RawJSON()))
+}
+
+type TiktokConfigurationParam struct {
+ // Allow comments on TikTok
+ AllowComment param.Opt[bool] `json:"allow_comment,omitzero"`
+ // Allow duets on TikTok
+ AllowDuet param.Opt[bool] `json:"allow_duet,omitzero"`
+ // Allow stitch on TikTok
+ AllowStitch param.Opt[bool] `json:"allow_stitch,omitzero"`
+ // Will automatically add music to photo posts
+ AutoAddMusic param.Opt[bool] `json:"auto_add_music,omitzero"`
+ // Disclose branded content on TikTok
+ DiscloseBrandedContent param.Opt[bool] `json:"disclose_branded_content,omitzero"`
+ // Disclose your brand on TikTok
+ DiscloseYourBrand param.Opt[bool] `json:"disclose_your_brand,omitzero"`
+ // Flag content as AI generated on TikTok
+ IsAIGenerated param.Opt[bool] `json:"is_ai_generated,omitzero"`
+ // Will create a draft upload to TikTok, posting will need to be completed from
+ // within the app
+ IsDraft param.Opt[bool] `json:"is_draft,omitzero"`
+ // Sets the privacy status for TikTok (private, public)
+ PrivacyStatus param.Opt[string] `json:"privacy_status,omitzero"`
+ // Overrides the `title` from the post
+ Title param.Opt[string] `json:"title,omitzero"`
+ // Overrides the `caption` from the post
+ Caption any `json:"caption,omitzero"`
+ // Overrides the `media` from the post
+ Media []SocialPostMediaParam `json:"media,omitzero"`
+ paramObj
}
-// Returns the unmodified JSON received from the API
-func (r TwitterConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *TwitterConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
+func (r TiktokConfigurationParam) MarshalJSON() (data []byte, err error) {
+ type shadow TiktokConfigurationParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *TiktokConfigurationParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Poll options for the tweet
-type TwitterConfigurationDtoPoll struct {
- // Duration of the poll in minutes
- DurationMinutes float64 `json:"duration_minutes" api:"required"`
- // The choices of the poll, requiring 2-4 options
- Options []string `json:"options" api:"required"`
+type TwitterConfigurationDto struct {
+ // Overrides the `caption` from the post
+ Caption any `json:"caption" api:"nullable"`
+ // Id of the community to post to
+ CommunityID string `json:"community_id"`
+ // Overrides the `media` from the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Poll options for the tweet
+ Poll TwitterPoll `json:"poll"`
+ // Id of the tweet you want to quote
+ QuoteTweetID string `json:"quote_tweet_id"`
// Who can reply to the tweet
//
// Any of "following", "mentionedUsers", "subscribers", "verified".
- ReplySettings string `json:"reply_settings"`
+ ReplySettings TwitterConfigurationDtoReplySettings `json:"reply_settings" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- DurationMinutes respjson.Field
- Options respjson.Field
- ReplySettings respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Caption respjson.Field
+ CommunityID respjson.Field
+ Media respjson.Field
+ Poll respjson.Field
+ QuoteTweetID respjson.Field
+ ReplySettings respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r TwitterConfigurationDtoPoll) RawJSON() string { return r.JSON.raw }
-func (r *TwitterConfigurationDtoPoll) UnmarshalJSON(data []byte) error {
+func (r TwitterConfigurationDto) RawJSON() string { return r.JSON.raw }
+func (r *TwitterConfigurationDto) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// ToParam converts this TwitterConfigurationDto to a TwitterConfigurationDtoParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// TwitterConfigurationDtoParam.Overrides()
+func (r TwitterConfigurationDto) ToParam() TwitterConfigurationDtoParam {
+ return param.Override[TwitterConfigurationDtoParam](json.RawMessage(r.RawJSON()))
+}
+
// Who can reply to the tweet
type TwitterConfigurationDtoReplySettings string
@@ -2392,13 +1379,13 @@ type TwitterConfigurationDtoParam struct {
// Overrides the `caption` from the post
Caption any `json:"caption,omitzero"`
// Overrides the `media` from the post
- Media []TwitterConfigurationDtoMediaParam `json:"media,omitzero"`
+ Media []SocialPostMediaParam `json:"media,omitzero"`
// Who can reply to the tweet
//
// Any of "following", "mentionedUsers", "subscribers", "verified".
ReplySettings TwitterConfigurationDtoReplySettings `json:"reply_settings,omitzero"`
// Poll options for the tweet
- Poll TwitterConfigurationDtoPollParam `json:"poll,omitzero"`
+ Poll TwitterPollParam `json:"poll,omitzero"`
paramObj
}
@@ -2410,74 +1397,52 @@ func (r *TwitterConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The property URL is required.
-type TwitterConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []TwitterConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
+type TwitterPoll struct {
+ // Duration of the poll in minutes
+ DurationMinutes float64 `json:"duration_minutes" api:"required"`
+ // The choices of the poll, requiring 2-4 options
+ Options []string `json:"options" api:"required"`
+ // Who can reply to the tweet
+ //
+ // Any of "following", "mentionedUsers", "subscribers", "verified".
+ ReplySettings TwitterPollReplySettings `json:"reply_settings"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ DurationMinutes respjson.Field
+ Options respjson.Field
+ ReplySettings respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
}
-func (r TwitterConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow TwitterConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *TwitterConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
+// Returns the unmodified JSON received from the API
+func (r TwitterPoll) RawJSON() string { return r.JSON.raw }
+func (r *TwitterPoll) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The properties ID, Platform, Type are required.
-type TwitterConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
- paramObj
+// ToParam converts this TwitterPoll to a TwitterPollParam.
+//
+// Warning: the fields of the param type will not be present. ToParam should only
+// be used at the last possible moment before sending a request. Test for this with
+// TwitterPollParam.Overrides()
+func (r TwitterPoll) ToParam() TwitterPollParam {
+ return param.Override[TwitterPollParam](json.RawMessage(r.RawJSON()))
}
-func (r TwitterConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow TwitterConfigurationDtoMediaTagParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *TwitterConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
+// Who can reply to the tweet
+type TwitterPollReplySettings string
-func init() {
- apijson.RegisterFieldValidator[TwitterConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[TwitterConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
+const (
+ TwitterPollReplySettingsFollowing TwitterPollReplySettings = "following"
+ TwitterPollReplySettingsMentionedUsers TwitterPollReplySettings = "mentionedUsers"
+ TwitterPollReplySettingsSubscribers TwitterPollReplySettings = "subscribers"
+ TwitterPollReplySettingsVerified TwitterPollReplySettings = "verified"
+)
-// Poll options for the tweet
-//
// The properties DurationMinutes, Options are required.
-type TwitterConfigurationDtoPollParam struct {
+type TwitterPollParam struct {
// Duration of the poll in minutes
DurationMinutes float64 `json:"duration_minutes" api:"required"`
// The choices of the poll, requiring 2-4 options
@@ -2485,46 +1450,89 @@ type TwitterConfigurationDtoPollParam struct {
// Who can reply to the tweet
//
// Any of "following", "mentionedUsers", "subscribers", "verified".
- ReplySettings string `json:"reply_settings,omitzero"`
+ ReplySettings TwitterPollReplySettings `json:"reply_settings,omitzero"`
paramObj
}
-func (r TwitterConfigurationDtoPollParam) MarshalJSON() (data []byte, err error) {
- type shadow TwitterConfigurationDtoPollParam
+func (r TwitterPollParam) MarshalJSON() (data []byte, err error) {
+ type shadow TwitterPollParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *TwitterConfigurationDtoPollParam) UnmarshalJSON(data []byte) error {
+func (r *TwitterPollParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func init() {
- apijson.RegisterFieldValidator[TwitterConfigurationDtoPollParam](
- "reply_settings", "following", "mentionedUsers", "subscribers", "verified",
- )
-}
-
type YoutubeConfigurationDto struct {
+ // Per-language localizations for the video title and description. Keys are BCP-47
+ // language tags (e.g. "fr", "es"). Maps to localizations on the YouTube Data API
+ // videos resource.
+ Localizations map[string]YoutubeConfigurationDtoLocalization `json:"localizations" api:"required"`
// Overrides the `caption` from the post
Caption any `json:"caption" api:"nullable"`
- // If true will notify YouTube the video is intended for kids, defaults to false
+ // YouTube video category id (maps to snippet.categoryId; see YouTube Data API
+ // videoCategories.list)
+ CategoryID string `json:"category_id" api:"nullable"`
+ // If true, marks the video as containing altered or synthetic content per
+ // YouTube's disclosure policy (maps to status.containsSyntheticMedia). YouTube
+ // adds a "How this content was made" label to the description automatically.
+ ContainsSyntheticMedia bool `json:"contains_synthetic_media" api:"nullable"`
+ // Default language of the video (BCP-47 language tag, e.g. "en"). Maps to
+ // snippet.defaultLanguage.
+ DefaultLanguage string `json:"default_language" api:"nullable"`
+ // Description for the YouTube video (maps to snippet.description). Falls back to
+ // the post caption when not provided.
+ Description string `json:"description" api:"nullable"`
+ // If true the video can be embedded on other websites (maps to status.embeddable).
+ // Defaults to true.
+ Embeddable bool `json:"embeddable" api:"nullable"`
+ // The video's license (maps to status.license). "youtube" is the standard YouTube
+ // license; "creativeCommon" is Creative Commons.
+ //
+ // Any of "youtube", "creativeCommon".
+ License YoutubeConfigurationDtoLicense `json:"license" api:"nullable"`
+ // If true will notify YouTube the video is intended for kids (maps to
+ // status.selfDeclaredMadeForKids), defaults to false
MadeForKids bool `json:"made_for_kids" api:"nullable"`
// Overrides the `media` from the post
- Media []YoutubeConfigurationDtoMedia `json:"media" api:"nullable"`
- // Sets the privacy status of the video, will default to public
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Sets the privacy status of the video (maps to status.privacyStatus), will
+ // default to public
//
// Any of "public", "private", "unlisted".
PrivacyStatus YoutubeConfigurationDtoPrivacyStatus `json:"privacy_status" api:"nullable"`
- // Overrides the `title` from the post
+ // If true, the extended video statistics are publicly viewable (maps to
+ // status.publicStatsViewable). Defaults to true.
+ PublicStatsViewable bool `json:"public_stats_viewable" api:"nullable"`
+ // ISO 8601 datetime at which the video should be published. Only honoured when
+ // privacy_status is "private" (maps to status.publishAt).
+ PublishAt string `json:"publish_at" api:"nullable"`
+ // ISO 8601 date (YYYY-MM-DD) or datetime when the video was recorded (maps to
+ // recordingDetails.recordingDate).
+ RecordingDate string `json:"recording_date" api:"nullable"`
+ // YouTube video tags (maps to snippet.tags)
+ Tags []string `json:"tags" api:"nullable"`
+ // Overrides the `title` from the post (maps to snippet.title)
Title string `json:"title" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Caption respjson.Field
- MadeForKids respjson.Field
- Media respjson.Field
- PrivacyStatus respjson.Field
- Title respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ Localizations respjson.Field
+ Caption respjson.Field
+ CategoryID respjson.Field
+ ContainsSyntheticMedia respjson.Field
+ DefaultLanguage respjson.Field
+ Description respjson.Field
+ Embeddable respjson.Field
+ License respjson.Field
+ MadeForKids respjson.Field
+ Media respjson.Field
+ PrivacyStatus respjson.Field
+ PublicStatsViewable respjson.Field
+ PublishAt respjson.Field
+ RecordingDate respjson.Field
+ Tags respjson.Field
+ Title respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
@@ -2543,74 +1551,35 @@ func (r YoutubeConfigurationDto) ToParam() YoutubeConfigurationDtoParam {
return param.Override[YoutubeConfigurationDtoParam](json.RawMessage(r.RawJSON()))
}
-type YoutubeConfigurationDtoMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []YoutubeConfigurationDtoMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r YoutubeConfigurationDtoMedia) RawJSON() string { return r.JSON.raw }
-func (r *YoutubeConfigurationDtoMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type YoutubeConfigurationDtoMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
+type YoutubeConfigurationDtoLocalization struct {
+ Description string `json:"description" api:"nullable"`
+ Title string `json:"title" api:"nullable"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
+ Description respjson.Field
+ Title respjson.Field
ExtraFields map[string]respjson.Field
raw string
} `json:"-"`
}
// Returns the unmodified JSON received from the API
-func (r YoutubeConfigurationDtoMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *YoutubeConfigurationDtoMediaTag) UnmarshalJSON(data []byte) error {
+func (r YoutubeConfigurationDtoLocalization) RawJSON() string { return r.JSON.raw }
+func (r *YoutubeConfigurationDtoLocalization) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// Sets the privacy status of the video, will default to public
+// The video's license (maps to status.license). "youtube" is the standard YouTube
+// license; "creativeCommon" is Creative Commons.
+type YoutubeConfigurationDtoLicense string
+
+const (
+ YoutubeConfigurationDtoLicenseYoutube YoutubeConfigurationDtoLicense = "youtube"
+ YoutubeConfigurationDtoLicenseCreativeCommon YoutubeConfigurationDtoLicense = "creativeCommon"
+)
+
+// Sets the privacy status of the video (maps to status.privacyStatus), will
+// default to public
type YoutubeConfigurationDtoPrivacyStatus string
const (
@@ -2619,19 +1588,58 @@ const (
YoutubeConfigurationDtoPrivacyStatusUnlisted YoutubeConfigurationDtoPrivacyStatus = "unlisted"
)
+// The property Localizations is required.
type YoutubeConfigurationDtoParam struct {
- // If true will notify YouTube the video is intended for kids, defaults to false
+ // Per-language localizations for the video title and description. Keys are BCP-47
+ // language tags (e.g. "fr", "es"). Maps to localizations on the YouTube Data API
+ // videos resource.
+ Localizations map[string]YoutubeConfigurationDtoLocalizationParam `json:"localizations,omitzero" api:"required"`
+ // YouTube video category id (maps to snippet.categoryId; see YouTube Data API
+ // videoCategories.list)
+ CategoryID param.Opt[string] `json:"category_id,omitzero"`
+ // If true, marks the video as containing altered or synthetic content per
+ // YouTube's disclosure policy (maps to status.containsSyntheticMedia). YouTube
+ // adds a "How this content was made" label to the description automatically.
+ ContainsSyntheticMedia param.Opt[bool] `json:"contains_synthetic_media,omitzero"`
+ // Default language of the video (BCP-47 language tag, e.g. "en"). Maps to
+ // snippet.defaultLanguage.
+ DefaultLanguage param.Opt[string] `json:"default_language,omitzero"`
+ // Description for the YouTube video (maps to snippet.description). Falls back to
+ // the post caption when not provided.
+ Description param.Opt[string] `json:"description,omitzero"`
+ // If true the video can be embedded on other websites (maps to status.embeddable).
+ // Defaults to true.
+ Embeddable param.Opt[bool] `json:"embeddable,omitzero"`
+ // If true will notify YouTube the video is intended for kids (maps to
+ // status.selfDeclaredMadeForKids), defaults to false
MadeForKids param.Opt[bool] `json:"made_for_kids,omitzero"`
- // Overrides the `title` from the post
+ // If true, the extended video statistics are publicly viewable (maps to
+ // status.publicStatsViewable). Defaults to true.
+ PublicStatsViewable param.Opt[bool] `json:"public_stats_viewable,omitzero"`
+ // ISO 8601 datetime at which the video should be published. Only honoured when
+ // privacy_status is "private" (maps to status.publishAt).
+ PublishAt param.Opt[string] `json:"publish_at,omitzero"`
+ // ISO 8601 date (YYYY-MM-DD) or datetime when the video was recorded (maps to
+ // recordingDetails.recordingDate).
+ RecordingDate param.Opt[string] `json:"recording_date,omitzero"`
+ // Overrides the `title` from the post (maps to snippet.title)
Title param.Opt[string] `json:"title,omitzero"`
// Overrides the `caption` from the post
Caption any `json:"caption,omitzero"`
+ // The video's license (maps to status.license). "youtube" is the standard YouTube
+ // license; "creativeCommon" is Creative Commons.
+ //
+ // Any of "youtube", "creativeCommon".
+ License YoutubeConfigurationDtoLicense `json:"license,omitzero"`
// Overrides the `media` from the post
- Media []YoutubeConfigurationDtoMediaParam `json:"media,omitzero"`
- // Sets the privacy status of the video, will default to public
+ Media []SocialPostMediaParam `json:"media,omitzero"`
+ // Sets the privacy status of the video (maps to status.privacyStatus), will
+ // default to public
//
// Any of "public", "private", "unlisted".
PrivacyStatus YoutubeConfigurationDtoPrivacyStatus `json:"privacy_status,omitzero"`
+ // YouTube video tags (maps to snippet.tags)
+ Tags []string `json:"tags,omitzero"`
paramObj
}
@@ -2643,70 +1651,20 @@ func (r *YoutubeConfigurationDtoParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-// The property URL is required.
-type YoutubeConfigurationDtoMediaParam struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing param.Opt[bool] `json:"skip_processing,omitzero"`
- // List of tags to attach to the media
- Tags []YoutubeConfigurationDtoMediaTagParam `json:"tags,omitzero"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms,omitzero"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url,omitzero"`
- paramObj
-}
-
-func (r YoutubeConfigurationDtoMediaParam) MarshalJSON() (data []byte, err error) {
- type shadow YoutubeConfigurationDtoMediaParam
- return param.MarshalObject(r, (*shadow)(&r))
-}
-func (r *YoutubeConfigurationDtoMediaParam) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-// The properties ID, Platform, Type are required.
-type YoutubeConfigurationDtoMediaTagParam struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform,omitzero" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type,omitzero" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X param.Opt[float64] `json:"x,omitzero"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y param.Opt[float64] `json:"y,omitzero"`
+type YoutubeConfigurationDtoLocalizationParam struct {
+ Description param.Opt[string] `json:"description,omitzero"`
+ Title param.Opt[string] `json:"title,omitzero"`
paramObj
}
-func (r YoutubeConfigurationDtoMediaTagParam) MarshalJSON() (data []byte, err error) {
- type shadow YoutubeConfigurationDtoMediaTagParam
+func (r YoutubeConfigurationDtoLocalizationParam) MarshalJSON() (data []byte, err error) {
+ type shadow YoutubeConfigurationDtoLocalizationParam
return param.MarshalObject(r, (*shadow)(&r))
}
-func (r *YoutubeConfigurationDtoMediaTagParam) UnmarshalJSON(data []byte) error {
+func (r *YoutubeConfigurationDtoLocalizationParam) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-func init() {
- apijson.RegisterFieldValidator[YoutubeConfigurationDtoMediaTagParam](
- "platform", "facebook", "instagram",
- )
- apijson.RegisterFieldValidator[YoutubeConfigurationDtoMediaTagParam](
- "type", "user", "product",
- )
-}
-
type SocialPostListResponse struct {
Data []SocialPost `json:"data" api:"required"`
Meta SocialPostListResponseMeta `json:"meta" api:"required"`
@@ -2751,23 +1709,6 @@ func (r *SocialPostListResponseMeta) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type SocialPostDeleteResponse struct {
- // Whether or not the entity was deleted
- Success bool `json:"success" api:"required"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- Success respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostDeleteResponse) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostDeleteResponse) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
type SocialPostNewParams struct {
CreateSocialPost CreateSocialPostParam
paramObj
diff --git a/socialpost_test.go b/socialpost_test.go
index 2ae85ff..0cb4862 100644
--- a/socialpost_test.go
+++ b/socialpost_test.go
@@ -31,27 +31,39 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
CreateSocialPost: postforme.CreateSocialPostParam{
Caption: "caption",
SocialAccounts: []string{"string"},
- AccountConfigurations: []postforme.CreateSocialPostAccountConfigurationParam{{
- Configuration: postforme.CreateSocialPostAccountConfigurationConfigurationParam{
+ AccountConfigurations: []postforme.AccountConfigurationParam{{
+ Configuration: postforme.AccountConfigurationConfigurationParam{
+ Localizations: map[string]postforme.AccountConfigurationConfigurationLocalizationParam{
+ "foo": {
+ Description: postforme.String("description"),
+ Title: postforme.String("title"),
+ },
+ },
AllowComment: postforme.Bool(true),
AllowDuet: postforme.Bool(true),
AllowStitch: postforme.Bool(true),
+ AudioName: postforme.String("audio_name"),
AutoAddMusic: postforme.Bool(true),
BoardIDs: []string{"string"},
Caption: map[string]any{},
+ CategoryID: postforme.String("category_id"),
Collaborators: [][]any{{map[string]any{}}},
CommunityID: postforme.String("community_id"),
+ ContainsSyntheticMedia: postforme.Bool(true),
+ DefaultLanguage: postforme.String("default_language"),
DiscloseBrandedContent: postforme.Bool(true),
DiscloseYourBrand: postforme.Bool(true),
+ Embeddable: postforme.Bool(true),
IsAIGenerated: postforme.Bool(true),
IsDraft: postforme.Bool(true),
+ License: "youtube",
Link: postforme.String("link"),
Location: postforme.String("location"),
MadeForKids: postforme.Bool(true),
- Media: []postforme.CreateSocialPostAccountConfigurationConfigurationMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.CreateSocialPostAccountConfigurationConfigurationMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -62,16 +74,21 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
ThumbnailURL: map[string]any{},
}},
Placement: "reels",
- Poll: postforme.CreateSocialPostAccountConfigurationConfigurationPollParam{
+ Poll: postforme.TwitterPollParam{
DurationMinutes: 0,
Options: []string{"string"},
- ReplySettings: "following",
+ ReplySettings: postforme.TwitterPollReplySettingsFollowing,
},
PrivacyStatus: "public",
+ PublicStatsViewable: postforme.Bool(true),
+ PublishAt: postforme.String("publish_at"),
QuoteTweetID: postforme.String("quote_tweet_id"),
+ RecordingDate: postforme.String("recording_date"),
ReplySettings: "following",
+ ResharePostID: postforme.String("reshare_post_id"),
SetCaptionForEachImage: postforme.Bool(true),
ShareToFeed: postforme.Bool(true),
+ Tags: []string{"string"},
Title: postforme.String("title"),
TrialReelType: "manual",
},
@@ -79,10 +96,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
}},
ExternalID: postforme.String("external_id"),
IsDraft: postforme.Bool(true),
- Media: []postforme.CreateSocialPostMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.CreateSocialPostMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -95,10 +112,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
PlatformConfigurations: postforme.PlatformConfigurationsDtoParam{
Bluesky: postforme.BlueskyConfigurationDtoParam{
Caption: map[string]any{},
- Media: []postforme.BlueskyConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.BlueskyConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -113,10 +130,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
Caption: map[string]any{},
Collaborators: [][]any{{map[string]any{}}},
Location: postforme.String("location"),
- Media: []postforme.FacebookConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.FacebookConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -130,13 +147,14 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
SetCaptionForEachImage: postforme.Bool(true),
},
Instagram: postforme.InstagramConfigurationDtoParam{
+ AudioName: postforme.String("audio_name"),
Caption: map[string]any{},
Collaborators: []string{"string"},
Location: postforme.String("location"),
- Media: []postforme.InstagramConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.InstagramConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -152,10 +170,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
},
Linkedin: postforme.LinkedinConfigurationDtoParam{
Caption: map[string]any{},
- Media: []postforme.LinkedinConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.LinkedinConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -165,15 +183,16 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
+ ResharePostID: postforme.String("reshare_post_id"),
},
Pinterest: postforme.PinterestConfigurationDtoParam{
BoardIDs: []string{"string"},
Caption: map[string]any{},
Link: postforme.String("link"),
- Media: []postforme.PinterestConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.PinterestConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -183,13 +202,14 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
+ Title: postforme.String("title"),
},
Threads: postforme.ThreadsConfigurationDtoParam{
Caption: map[string]any{},
- Media: []postforme.ThreadsConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.ThreadsConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -211,10 +231,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
DiscloseYourBrand: postforme.Bool(true),
IsAIGenerated: postforme.Bool(true),
IsDraft: postforme.Bool(true),
- Media: []postforme.TiktokConfigurationMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.TiktokConfigurationMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -237,10 +257,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
DiscloseYourBrand: postforme.Bool(true),
IsAIGenerated: postforme.Bool(true),
IsDraft: postforme.Bool(true),
- Media: []postforme.TiktokConfigurationMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.TiktokConfigurationMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -256,10 +276,10 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
X: postforme.TwitterConfigurationDtoParam{
Caption: map[string]any{},
CommunityID: postforme.String("community_id"),
- Media: []postforme.TwitterConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.TwitterConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -269,21 +289,33 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
- Poll: postforme.TwitterConfigurationDtoPollParam{
+ Poll: postforme.TwitterPollParam{
DurationMinutes: 0,
Options: []string{"string"},
- ReplySettings: "following",
+ ReplySettings: postforme.TwitterPollReplySettingsFollowing,
},
QuoteTweetID: postforme.String("quote_tweet_id"),
ReplySettings: postforme.TwitterConfigurationDtoReplySettingsFollowing,
},
Youtube: postforme.YoutubeConfigurationDtoParam{
- Caption: map[string]any{},
- MadeForKids: postforme.Bool(true),
- Media: []postforme.YoutubeConfigurationDtoMediaParam{{
+ Localizations: map[string]postforme.YoutubeConfigurationDtoLocalizationParam{
+ "foo": {
+ Description: postforme.String("description"),
+ Title: postforme.String("title"),
+ },
+ },
+ Caption: map[string]any{},
+ CategoryID: postforme.String("category_id"),
+ ContainsSyntheticMedia: postforme.Bool(true),
+ DefaultLanguage: postforme.String("default_language"),
+ Description: postforme.String("description"),
+ Embeddable: postforme.Bool(true),
+ License: postforme.YoutubeConfigurationDtoLicenseYoutube,
+ MadeForKids: postforme.Bool(true),
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.YoutubeConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -293,8 +325,12 @@ func TestSocialPostNewWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
- PrivacyStatus: postforme.YoutubeConfigurationDtoPrivacyStatusPublic,
- Title: postforme.String("title"),
+ PrivacyStatus: postforme.YoutubeConfigurationDtoPrivacyStatusPublic,
+ PublicStatsViewable: postforme.Bool(true),
+ PublishAt: postforme.String("publish_at"),
+ RecordingDate: postforme.String("recording_date"),
+ Tags: []string{"string"},
+ Title: postforme.String("title"),
},
},
ScheduledAt: postforme.Time(time.Now()),
@@ -352,27 +388,39 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
CreateSocialPost: postforme.CreateSocialPostParam{
Caption: "caption",
SocialAccounts: []string{"string"},
- AccountConfigurations: []postforme.CreateSocialPostAccountConfigurationParam{{
- Configuration: postforme.CreateSocialPostAccountConfigurationConfigurationParam{
+ AccountConfigurations: []postforme.AccountConfigurationParam{{
+ Configuration: postforme.AccountConfigurationConfigurationParam{
+ Localizations: map[string]postforme.AccountConfigurationConfigurationLocalizationParam{
+ "foo": {
+ Description: postforme.String("description"),
+ Title: postforme.String("title"),
+ },
+ },
AllowComment: postforme.Bool(true),
AllowDuet: postforme.Bool(true),
AllowStitch: postforme.Bool(true),
+ AudioName: postforme.String("audio_name"),
AutoAddMusic: postforme.Bool(true),
BoardIDs: []string{"string"},
Caption: map[string]any{},
+ CategoryID: postforme.String("category_id"),
Collaborators: [][]any{{map[string]any{}}},
CommunityID: postforme.String("community_id"),
+ ContainsSyntheticMedia: postforme.Bool(true),
+ DefaultLanguage: postforme.String("default_language"),
DiscloseBrandedContent: postforme.Bool(true),
DiscloseYourBrand: postforme.Bool(true),
+ Embeddable: postforme.Bool(true),
IsAIGenerated: postforme.Bool(true),
IsDraft: postforme.Bool(true),
+ License: "youtube",
Link: postforme.String("link"),
Location: postforme.String("location"),
MadeForKids: postforme.Bool(true),
- Media: []postforme.CreateSocialPostAccountConfigurationConfigurationMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.CreateSocialPostAccountConfigurationConfigurationMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -383,16 +431,21 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
ThumbnailURL: map[string]any{},
}},
Placement: "reels",
- Poll: postforme.CreateSocialPostAccountConfigurationConfigurationPollParam{
+ Poll: postforme.TwitterPollParam{
DurationMinutes: 0,
Options: []string{"string"},
- ReplySettings: "following",
+ ReplySettings: postforme.TwitterPollReplySettingsFollowing,
},
PrivacyStatus: "public",
+ PublicStatsViewable: postforme.Bool(true),
+ PublishAt: postforme.String("publish_at"),
QuoteTweetID: postforme.String("quote_tweet_id"),
+ RecordingDate: postforme.String("recording_date"),
ReplySettings: "following",
+ ResharePostID: postforme.String("reshare_post_id"),
SetCaptionForEachImage: postforme.Bool(true),
ShareToFeed: postforme.Bool(true),
+ Tags: []string{"string"},
Title: postforme.String("title"),
TrialReelType: "manual",
},
@@ -400,10 +453,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
}},
ExternalID: postforme.String("external_id"),
IsDraft: postforme.Bool(true),
- Media: []postforme.CreateSocialPostMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.CreateSocialPostMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -416,10 +469,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
PlatformConfigurations: postforme.PlatformConfigurationsDtoParam{
Bluesky: postforme.BlueskyConfigurationDtoParam{
Caption: map[string]any{},
- Media: []postforme.BlueskyConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.BlueskyConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -434,10 +487,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
Caption: map[string]any{},
Collaborators: [][]any{{map[string]any{}}},
Location: postforme.String("location"),
- Media: []postforme.FacebookConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.FacebookConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -451,13 +504,14 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
SetCaptionForEachImage: postforme.Bool(true),
},
Instagram: postforme.InstagramConfigurationDtoParam{
+ AudioName: postforme.String("audio_name"),
Caption: map[string]any{},
Collaborators: []string{"string"},
Location: postforme.String("location"),
- Media: []postforme.InstagramConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.InstagramConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -473,10 +527,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
},
Linkedin: postforme.LinkedinConfigurationDtoParam{
Caption: map[string]any{},
- Media: []postforme.LinkedinConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.LinkedinConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -486,15 +540,16 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
+ ResharePostID: postforme.String("reshare_post_id"),
},
Pinterest: postforme.PinterestConfigurationDtoParam{
BoardIDs: []string{"string"},
Caption: map[string]any{},
Link: postforme.String("link"),
- Media: []postforme.PinterestConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.PinterestConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -504,13 +559,14 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
+ Title: postforme.String("title"),
},
Threads: postforme.ThreadsConfigurationDtoParam{
Caption: map[string]any{},
- Media: []postforme.ThreadsConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.ThreadsConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -532,10 +588,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
DiscloseYourBrand: postforme.Bool(true),
IsAIGenerated: postforme.Bool(true),
IsDraft: postforme.Bool(true),
- Media: []postforme.TiktokConfigurationMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.TiktokConfigurationMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -558,10 +614,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
DiscloseYourBrand: postforme.Bool(true),
IsAIGenerated: postforme.Bool(true),
IsDraft: postforme.Bool(true),
- Media: []postforme.TiktokConfigurationMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.TiktokConfigurationMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -577,10 +633,10 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
X: postforme.TwitterConfigurationDtoParam{
Caption: map[string]any{},
CommunityID: postforme.String("community_id"),
- Media: []postforme.TwitterConfigurationDtoMediaParam{{
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.TwitterConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -590,21 +646,33 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
- Poll: postforme.TwitterConfigurationDtoPollParam{
+ Poll: postforme.TwitterPollParam{
DurationMinutes: 0,
Options: []string{"string"},
- ReplySettings: "following",
+ ReplySettings: postforme.TwitterPollReplySettingsFollowing,
},
QuoteTweetID: postforme.String("quote_tweet_id"),
ReplySettings: postforme.TwitterConfigurationDtoReplySettingsFollowing,
},
Youtube: postforme.YoutubeConfigurationDtoParam{
- Caption: map[string]any{},
- MadeForKids: postforme.Bool(true),
- Media: []postforme.YoutubeConfigurationDtoMediaParam{{
+ Localizations: map[string]postforme.YoutubeConfigurationDtoLocalizationParam{
+ "foo": {
+ Description: postforme.String("description"),
+ Title: postforme.String("title"),
+ },
+ },
+ Caption: map[string]any{},
+ CategoryID: postforme.String("category_id"),
+ ContainsSyntheticMedia: postforme.Bool(true),
+ DefaultLanguage: postforme.String("default_language"),
+ Description: postforme.String("description"),
+ Embeddable: postforme.Bool(true),
+ License: postforme.YoutubeConfigurationDtoLicenseYoutube,
+ MadeForKids: postforme.Bool(true),
+ Media: []postforme.SocialPostMediaParam{{
URL: "url",
SkipProcessing: postforme.Bool(true),
- Tags: []postforme.YoutubeConfigurationDtoMediaTagParam{{
+ Tags: []postforme.SocialPostMediaTagParam{{
ID: "id",
Platform: "facebook",
Type: "user",
@@ -614,8 +682,12 @@ func TestSocialPostUpdateWithOptionalParams(t *testing.T) {
ThumbnailTimestampMs: map[string]any{},
ThumbnailURL: map[string]any{},
}},
- PrivacyStatus: postforme.YoutubeConfigurationDtoPrivacyStatusPublic,
- Title: postforme.String("title"),
+ PrivacyStatus: postforme.YoutubeConfigurationDtoPrivacyStatusPublic,
+ PublicStatsViewable: postforme.Bool(true),
+ PublishAt: postforme.String("publish_at"),
+ RecordingDate: postforme.String("recording_date"),
+ Tags: []string{"string"},
+ Title: postforme.String("title"),
},
},
ScheduledAt: postforme.Time(time.Now()),
diff --git a/socialpostpreview.go b/socialpostpreview.go
new file mode 100644
index 0000000..dbce927
--- /dev/null
+++ b/socialpostpreview.go
@@ -0,0 +1,136 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package postforme
+
+import (
+ "context"
+ "net/http"
+ "slices"
+
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/apijson"
+ shimjson "github.com/DayMoonDevelopment/post-for-me-go/internal/encoding/json"
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/requestconfig"
+ "github.com/DayMoonDevelopment/post-for-me-go/option"
+ "github.com/DayMoonDevelopment/post-for-me-go/packages/param"
+ "github.com/DayMoonDevelopment/post-for-me-go/packages/respjson"
+)
+
+// Social Post Previews allow you to see what a Social Post will create for each
+// account in the post.
+//
+// SocialPostPreviewService contains methods and other services that help with
+// interacting with the post-for-me API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewSocialPostPreviewService] method instead.
+type SocialPostPreviewService struct {
+ Options []option.RequestOption
+}
+
+// NewSocialPostPreviewService generates a new service that applies the given
+// options to each request. These options are applied after the parent client's
+// options (if there is one), and before any request-specific options.
+func NewSocialPostPreviewService(opts ...option.RequestOption) (r SocialPostPreviewService) {
+ r = SocialPostPreviewService{}
+ r.Options = opts
+ return
+}
+
+// Create Post Previews
+func (r *SocialPostPreviewService) New(ctx context.Context, body SocialPostPreviewNewParams, opts ...option.RequestOption) (res *[]SocialPostPreview, err error) {
+ opts = slices.Concat(r.Options, opts)
+ path := "v1/social-post-previews"
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return res, err
+}
+
+// The properties Caption, PreviewSocialAccounts are required.
+type CreateSocialPostPreviewParam struct {
+ // Caption text for the post
+ Caption string `json:"caption" api:"required"`
+ // Array of social accounts. Can preview non connected accounts, just specify a
+ // random ID
+ PreviewSocialAccounts []CreateSocialPostPreviewPreviewSocialAccountParam `json:"preview_social_accounts,omitzero" api:"required"`
+ // Account-specific configurations for the post
+ AccountConfigurations []AccountConfigurationParam `json:"account_configurations,omitzero"`
+ // Array of media URLs associated with the post
+ Media []SocialPostMediaParam `json:"media,omitzero"`
+ // Platform-specific configurations for the post
+ PlatformConfigurations PlatformConfigurationsDtoParam `json:"platform_configurations,omitzero"`
+ paramObj
+}
+
+func (r CreateSocialPostPreviewParam) MarshalJSON() (data []byte, err error) {
+ type shadow CreateSocialPostPreviewParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *CreateSocialPostPreviewParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// The properties ID, Platform are required.
+type CreateSocialPostPreviewPreviewSocialAccountParam struct {
+ // ID of the social account, ex: spc_12312
+ ID string `json:"id" api:"required"`
+ // Platform of the social account
+ Platform string `json:"platform" api:"required"`
+ // username of the social account
+ Username param.Opt[string] `json:"username,omitzero"`
+ paramObj
+}
+
+func (r CreateSocialPostPreviewPreviewSocialAccountParam) MarshalJSON() (data []byte, err error) {
+ type shadow CreateSocialPostPreviewPreviewSocialAccountParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *CreateSocialPostPreviewPreviewSocialAccountParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type SocialPostPreview struct {
+ // Caption text for the post
+ Caption string `json:"caption" api:"required"`
+ // Platform of the post
+ Platform string `json:"platform" api:"required"`
+ // Id of the social account
+ SocialAccountID string `json:"social_account_id" api:"required"`
+ // Additional configuration for this platform
+ Configuration any `json:"configuration"`
+ // Array of media URLs associated with the post
+ Media []SocialPostMedia `json:"media" api:"nullable"`
+ // Url of the social account profile picture
+ SocialAccountProfilePictureURL any `json:"social_account_profile_picture_url"`
+ // Username of the social account
+ SocialAccountUsername any `json:"social_account_username"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Caption respjson.Field
+ Platform respjson.Field
+ SocialAccountID respjson.Field
+ Configuration respjson.Field
+ Media respjson.Field
+ SocialAccountProfilePictureURL respjson.Field
+ SocialAccountUsername respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r SocialPostPreview) RawJSON() string { return r.JSON.raw }
+func (r *SocialPostPreview) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type SocialPostPreviewNewParams struct {
+ CreateSocialPostPreview CreateSocialPostPreviewParam
+ paramObj
+}
+
+func (r SocialPostPreviewNewParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.CreateSocialPostPreview)
+}
+func (r *SocialPostPreviewNewParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
diff --git a/socialpostpreview_test.go b/socialpostpreview_test.go
new file mode 100644
index 0000000..ec8571d
--- /dev/null
+++ b/socialpostpreview_test.go
@@ -0,0 +1,346 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package postforme_test
+
+import (
+ "context"
+ "errors"
+ "os"
+ "testing"
+
+ "github.com/DayMoonDevelopment/post-for-me-go"
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/testutil"
+ "github.com/DayMoonDevelopment/post-for-me-go/option"
+)
+
+func TestSocialPostPreviewNewWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := postforme.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.SocialPostPreviews.New(context.TODO(), postforme.SocialPostPreviewNewParams{
+ CreateSocialPostPreview: postforme.CreateSocialPostPreviewParam{
+ Caption: "caption",
+ PreviewSocialAccounts: []postforme.CreateSocialPostPreviewPreviewSocialAccountParam{{
+ ID: "id",
+ Platform: "platform",
+ Username: postforme.String("username"),
+ }},
+ AccountConfigurations: []postforme.AccountConfigurationParam{{
+ Configuration: postforme.AccountConfigurationConfigurationParam{
+ Localizations: map[string]postforme.AccountConfigurationConfigurationLocalizationParam{
+ "foo": {
+ Description: postforme.String("description"),
+ Title: postforme.String("title"),
+ },
+ },
+ AllowComment: postforme.Bool(true),
+ AllowDuet: postforme.Bool(true),
+ AllowStitch: postforme.Bool(true),
+ AudioName: postforme.String("audio_name"),
+ AutoAddMusic: postforme.Bool(true),
+ BoardIDs: []string{"string"},
+ Caption: map[string]any{},
+ CategoryID: postforme.String("category_id"),
+ Collaborators: [][]any{{map[string]any{}}},
+ CommunityID: postforme.String("community_id"),
+ ContainsSyntheticMedia: postforme.Bool(true),
+ DefaultLanguage: postforme.String("default_language"),
+ DiscloseBrandedContent: postforme.Bool(true),
+ DiscloseYourBrand: postforme.Bool(true),
+ Embeddable: postforme.Bool(true),
+ IsAIGenerated: postforme.Bool(true),
+ IsDraft: postforme.Bool(true),
+ License: "youtube",
+ Link: postforme.String("link"),
+ Location: postforme.String("location"),
+ MadeForKids: postforme.Bool(true),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ Placement: "reels",
+ Poll: postforme.TwitterPollParam{
+ DurationMinutes: 0,
+ Options: []string{"string"},
+ ReplySettings: postforme.TwitterPollReplySettingsFollowing,
+ },
+ PrivacyStatus: "public",
+ PublicStatsViewable: postforme.Bool(true),
+ PublishAt: postforme.String("publish_at"),
+ QuoteTweetID: postforme.String("quote_tweet_id"),
+ RecordingDate: postforme.String("recording_date"),
+ ReplySettings: "following",
+ ResharePostID: postforme.String("reshare_post_id"),
+ SetCaptionForEachImage: postforme.Bool(true),
+ ShareToFeed: postforme.Bool(true),
+ Tags: []string{"string"},
+ Title: postforme.String("title"),
+ TrialReelType: "manual",
+ },
+ SocialAccountID: "social_account_id",
+ }},
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ PlatformConfigurations: postforme.PlatformConfigurationsDtoParam{
+ Bluesky: postforme.BlueskyConfigurationDtoParam{
+ Caption: map[string]any{},
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ },
+ Facebook: postforme.FacebookConfigurationDtoParam{
+ Caption: map[string]any{},
+ Collaborators: [][]any{{map[string]any{}}},
+ Location: postforme.String("location"),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ Placement: postforme.FacebookConfigurationDtoPlacementReels,
+ SetCaptionForEachImage: postforme.Bool(true),
+ },
+ Instagram: postforme.InstagramConfigurationDtoParam{
+ AudioName: postforme.String("audio_name"),
+ Caption: map[string]any{},
+ Collaborators: []string{"string"},
+ Location: postforme.String("location"),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ Placement: postforme.InstagramConfigurationDtoPlacementReels,
+ ShareToFeed: postforme.Bool(true),
+ TrialReelType: postforme.InstagramConfigurationDtoTrialReelTypeManual,
+ },
+ Linkedin: postforme.LinkedinConfigurationDtoParam{
+ Caption: map[string]any{},
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ ResharePostID: postforme.String("reshare_post_id"),
+ },
+ Pinterest: postforme.PinterestConfigurationDtoParam{
+ BoardIDs: []string{"string"},
+ Caption: map[string]any{},
+ Link: postforme.String("link"),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ Title: postforme.String("title"),
+ },
+ Threads: postforme.ThreadsConfigurationDtoParam{
+ Caption: map[string]any{},
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ Placement: postforme.ThreadsConfigurationDtoPlacementReels,
+ },
+ Tiktok: postforme.TiktokConfigurationParam{
+ AllowComment: postforme.Bool(true),
+ AllowDuet: postforme.Bool(true),
+ AllowStitch: postforme.Bool(true),
+ AutoAddMusic: postforme.Bool(true),
+ Caption: map[string]any{},
+ DiscloseBrandedContent: postforme.Bool(true),
+ DiscloseYourBrand: postforme.Bool(true),
+ IsAIGenerated: postforme.Bool(true),
+ IsDraft: postforme.Bool(true),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ PrivacyStatus: postforme.String("privacy_status"),
+ Title: postforme.String("title"),
+ },
+ TiktokBusiness: postforme.TiktokConfigurationParam{
+ AllowComment: postforme.Bool(true),
+ AllowDuet: postforme.Bool(true),
+ AllowStitch: postforme.Bool(true),
+ AutoAddMusic: postforme.Bool(true),
+ Caption: map[string]any{},
+ DiscloseBrandedContent: postforme.Bool(true),
+ DiscloseYourBrand: postforme.Bool(true),
+ IsAIGenerated: postforme.Bool(true),
+ IsDraft: postforme.Bool(true),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ PrivacyStatus: postforme.String("privacy_status"),
+ Title: postforme.String("title"),
+ },
+ X: postforme.TwitterConfigurationDtoParam{
+ Caption: map[string]any{},
+ CommunityID: postforme.String("community_id"),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ Poll: postforme.TwitterPollParam{
+ DurationMinutes: 0,
+ Options: []string{"string"},
+ ReplySettings: postforme.TwitterPollReplySettingsFollowing,
+ },
+ QuoteTweetID: postforme.String("quote_tweet_id"),
+ ReplySettings: postforme.TwitterConfigurationDtoReplySettingsFollowing,
+ },
+ Youtube: postforme.YoutubeConfigurationDtoParam{
+ Localizations: map[string]postforme.YoutubeConfigurationDtoLocalizationParam{
+ "foo": {
+ Description: postforme.String("description"),
+ Title: postforme.String("title"),
+ },
+ },
+ Caption: map[string]any{},
+ CategoryID: postforme.String("category_id"),
+ ContainsSyntheticMedia: postforme.Bool(true),
+ DefaultLanguage: postforme.String("default_language"),
+ Description: postforme.String("description"),
+ Embeddable: postforme.Bool(true),
+ License: postforme.YoutubeConfigurationDtoLicenseYoutube,
+ MadeForKids: postforme.Bool(true),
+ Media: []postforme.SocialPostMediaParam{{
+ URL: "url",
+ SkipProcessing: postforme.Bool(true),
+ Tags: []postforme.SocialPostMediaTagParam{{
+ ID: "id",
+ Platform: "facebook",
+ Type: "user",
+ X: postforme.Float(0),
+ Y: postforme.Float(0),
+ }},
+ ThumbnailTimestampMs: map[string]any{},
+ ThumbnailURL: map[string]any{},
+ }},
+ PrivacyStatus: postforme.YoutubeConfigurationDtoPrivacyStatusPublic,
+ PublicStatsViewable: postforme.Bool(true),
+ PublishAt: postforme.String("publish_at"),
+ RecordingDate: postforme.String("recording_date"),
+ Tags: []string{"string"},
+ Title: postforme.String("title"),
+ },
+ },
+ },
+ })
+ if err != nil {
+ var apierr *postforme.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
diff --git a/socialpostresult.go b/socialpostresult.go
index 1babe05..bca26ca 100644
--- a/socialpostresult.go
+++ b/socialpostresult.go
@@ -72,7 +72,7 @@ type SocialPostResult struct {
// Error message if the post failed
Error any `json:"error" api:"required"`
// Array of media URLs associated with the post
- Media []SocialPostResultMedia `json:"media" api:"required"`
+ Media []SocialPostMedia `json:"media" api:"required"`
// Platform-specific data
PlatformData SocialPostResultPlatformData `json:"platform_data" api:"required"`
// The ID of the associated post
@@ -102,73 +102,6 @@ func (r *SocialPostResult) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
-type SocialPostResultMedia struct {
- // Public URL of the media
- URL string `json:"url" api:"required"`
- // If true the media will not be processed at all and instead be posted as is, this
- // may increase chance of post failure if media does not meet platform's
- // requirements. Best used for larger files.
- SkipProcessing bool `json:"skip_processing" api:"nullable"`
- // List of tags to attach to the media
- Tags []SocialPostResultMediaTag `json:"tags" api:"nullable"`
- // Timestamp in milliseconds of frame to use as thumbnail for the media
- ThumbnailTimestampMs any `json:"thumbnail_timestamp_ms" api:"nullable"`
- // Public URL of the thumbnail for the media
- ThumbnailURL any `json:"thumbnail_url" api:"nullable"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- URL respjson.Field
- SkipProcessing respjson.Field
- Tags respjson.Field
- ThumbnailTimestampMs respjson.Field
- ThumbnailURL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostResultMedia) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostResultMedia) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
-type SocialPostResultMediaTag struct {
- // Facebook User ID, Instagram Username or Instagram product id to tag
- ID string `json:"id" api:"required"`
- // The platform for the tags
- //
- // Any of "facebook", "instagram".
- Platform string `json:"platform" api:"required"`
- // The type of tag, user to tag accounts, product to tag products (only supported
- // for instagram)
- //
- // Any of "user", "product".
- Type string `json:"type" api:"required"`
- // Percentage distance from left edge of the image, Not required for videos or
- // stories
- X float64 `json:"x"`
- // Percentage distance from top edge of the image, Not required for videos or
- // stories
- Y float64 `json:"y"`
- // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
- JSON struct {
- ID respjson.Field
- Platform respjson.Field
- Type respjson.Field
- X respjson.Field
- Y respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
- } `json:"-"`
-}
-
-// Returns the unmodified JSON received from the API
-func (r SocialPostResultMediaTag) RawJSON() string { return r.JSON.raw }
-func (r *SocialPostResultMediaTag) UnmarshalJSON(data []byte) error {
- return apijson.UnmarshalRoot(data, r)
-}
-
// Platform-specific data
type SocialPostResultPlatformData struct {
// Platform-specific ID
diff --git a/webhook.go b/webhook.go
new file mode 100644
index 0000000..6bcb96a
--- /dev/null
+++ b/webhook.go
@@ -0,0 +1,257 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package postforme
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/http"
+ "net/url"
+ "slices"
+
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/apijson"
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/apiquery"
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/requestconfig"
+ "github.com/DayMoonDevelopment/post-for-me-go/option"
+ "github.com/DayMoonDevelopment/post-for-me-go/packages/param"
+ "github.com/DayMoonDevelopment/post-for-me-go/packages/respjson"
+)
+
+// Webhooks enable you to subscribe to certain events. This involves Post for Me
+// making a POST request to the URL of any webhooks you create. Only the events you
+// subscribe to will be sent to your webhook URL.
+//
+// ## Payload
+//
+// When an event happens that your webhook is subscribed to, we will make a POST
+// request with the following JSON body
+//
+// ```
+//
+// {
+// "event_type": "",
+// "data": {}
+// }
+//
+// ```
+//
+// The event_type will be the event that triggered the webhook POST, data will be
+// the resulting entity from the event
+//
+// ## Security
+//
+// To verify the POST to your webhook URL is from us we will include a secret in
+// the header "Post-For-Me-Webhook-Secret". When you create a webhook you will
+// receive the secret in the response.
+//
+// ## Retries
+//
+// If your server fails to respond with a 2XX code, requests to it will be retried
+// with exponential backoff around 8 times over the course of just over a day.
+//
+// WebhookService contains methods and other services that help with interacting
+// with the post-for-me API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewWebhookService] method instead.
+type WebhookService struct {
+ Options []option.RequestOption
+}
+
+// NewWebhookService generates a new service that applies the given options to each
+// request. These options are applied after the parent client's options (if there
+// is one), and before any request-specific options.
+func NewWebhookService(opts ...option.RequestOption) (r WebhookService) {
+ r = WebhookService{}
+ r.Options = opts
+ return
+}
+
+// Create Webhook
+func (r *WebhookService) New(ctx context.Context, body WebhookNewParams, opts ...option.RequestOption) (res *Webhook, err error) {
+ opts = slices.Concat(r.Options, opts)
+ path := "v1/webhooks"
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return res, err
+}
+
+// Get webhook by ID
+func (r *WebhookService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *Webhook, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("v1/webhooks/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...)
+ return res, err
+}
+
+// Update Webhook
+func (r *WebhookService) Update(ctx context.Context, id string, body WebhookUpdateParams, opts ...option.RequestOption) (res *Webhook, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("v1/webhooks/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...)
+ return res, err
+}
+
+// Get a paginated result for webhooks based on the applied filters
+func (r *WebhookService) List(ctx context.Context, query WebhookListParams, opts ...option.RequestOption) (res *WebhookListResponse, err error) {
+ opts = slices.Concat(r.Options, opts)
+ path := "v1/webhooks"
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, query, &res, opts...)
+ return res, err
+}
+
+// Delete Webhook
+func (r *WebhookService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (res *DeleteEntityResponse, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if id == "" {
+ err = errors.New("missing required id parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("v1/webhooks/%s", id)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, &res, opts...)
+ return res, err
+}
+
+type Webhook struct {
+ // The unique identifier of the webhook
+ ID string `json:"id" api:"required"`
+ // Events that will be sent to the webhook
+ EventTypes []string `json:"event_types" api:"required"`
+ // Secret key used to verify webhook post
+ Secret string `json:"secret" api:"required"`
+ // The public webhook url
+ URL string `json:"url" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ ID respjson.Field
+ EventTypes respjson.Field
+ Secret respjson.Field
+ URL respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r Webhook) RawJSON() string { return r.JSON.raw }
+func (r *Webhook) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type WebhookListResponse struct {
+ Data []Webhook `json:"data" api:"required"`
+ Meta WebhookListResponseMeta `json:"meta" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Data respjson.Field
+ Meta respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r WebhookListResponse) RawJSON() string { return r.JSON.raw }
+func (r *WebhookListResponse) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type WebhookListResponseMeta struct {
+ // Maximum number of items returned.
+ Limit float64 `json:"limit" api:"required"`
+ // URL to the next page of results, or null if none.
+ Next string `json:"next" api:"required"`
+ // Number of items skipped.
+ Offset float64 `json:"offset" api:"required"`
+ // Total number of items available.
+ Total float64 `json:"total" api:"required"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Limit respjson.Field
+ Next respjson.Field
+ Offset respjson.Field
+ Total respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r WebhookListResponseMeta) RawJSON() string { return r.JSON.raw }
+func (r *WebhookListResponseMeta) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type WebhookNewParams struct {
+ // List of events the webhook will recieve
+ //
+ // Any of "social.post.created", "social.post.updated", "social.post.deleted",
+ // "social.post.result.created", "social.account.created",
+ // "social.account.updated".
+ EventTypes []string `json:"event_types,omitzero" api:"required"`
+ // Public url to recieve event data
+ URL string `json:"url" api:"required"`
+ paramObj
+}
+
+func (r WebhookNewParams) MarshalJSON() (data []byte, err error) {
+ type shadow WebhookNewParams
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *WebhookNewParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type WebhookUpdateParams struct {
+ // Public url to recieve event data
+ URL param.Opt[string] `json:"url,omitzero"`
+ // List of events the webhook will recieve
+ //
+ // Any of "social.post.created", "social.post.updated", "social.post.deleted",
+ // "social.post.result.created", "social.account.created",
+ // "social.account.updated".
+ EventTypes []string `json:"event_types,omitzero"`
+ paramObj
+}
+
+func (r WebhookUpdateParams) MarshalJSON() (data []byte, err error) {
+ type shadow WebhookUpdateParams
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *WebhookUpdateParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type WebhookListParams struct {
+ // Number of items to return
+ Limit param.Opt[float64] `query:"limit,omitzero" json:"-"`
+ // Number of items to skip
+ Offset param.Opt[float64] `query:"offset,omitzero" json:"-"`
+ // Filter by id(s). Multiple values imply OR logic (e.g.,
+ // ?id=wbh_xxxxxx&id=wbh_yyyyyy).
+ ID []string `query:"id,omitzero" json:"-"`
+ // Filter by event type(s). Multiple values imply OR logic (e.g.,
+ // ?event_type=social.post.created&event_type=social.post.updated).
+ EventType []string `query:"event_type,omitzero" json:"-"`
+ // Filter by url(s). Multiple values imply OR logic (e.g.,
+ // ?url=https://example.com&url=https://postforme.dev).
+ URL []string `query:"url,omitzero" json:"-"`
+ paramObj
+}
+
+// URLQuery serializes [WebhookListParams]'s query parameters as `url.Values`.
+func (r WebhookListParams) URLQuery() (v url.Values, err error) {
+ return apiquery.MarshalWithSettings(r, apiquery.QuerySettings{
+ ArrayFormat: apiquery.ArrayQueryFormatComma,
+ NestedFormat: apiquery.NestedQueryFormatBrackets,
+ })
+}
diff --git a/webhook_test.go b/webhook_test.go
new file mode 100644
index 0000000..64027fb
--- /dev/null
+++ b/webhook_test.go
@@ -0,0 +1,145 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package postforme_test
+
+import (
+ "context"
+ "errors"
+ "os"
+ "testing"
+
+ "github.com/DayMoonDevelopment/post-for-me-go"
+ "github.com/DayMoonDevelopment/post-for-me-go/internal/testutil"
+ "github.com/DayMoonDevelopment/post-for-me-go/option"
+)
+
+func TestWebhookNew(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := postforme.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Webhooks.New(context.TODO(), postforme.WebhookNewParams{
+ EventTypes: []string{"social.post.created"},
+ URL: "url",
+ })
+ if err != nil {
+ var apierr *postforme.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestWebhookGet(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := postforme.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Webhooks.Get(context.TODO(), "id")
+ if err != nil {
+ var apierr *postforme.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestWebhookUpdateWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := postforme.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Webhooks.Update(
+ context.TODO(),
+ "id",
+ postforme.WebhookUpdateParams{
+ EventTypes: []string{"social.post.created"},
+ URL: postforme.String("url"),
+ },
+ )
+ if err != nil {
+ var apierr *postforme.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestWebhookListWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := postforme.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Webhooks.List(context.TODO(), postforme.WebhookListParams{
+ ID: []string{"string"},
+ EventType: []string{"string"},
+ Limit: postforme.Float(0),
+ Offset: postforme.Float(0),
+ URL: []string{"string"},
+ })
+ if err != nil {
+ var apierr *postforme.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
+
+func TestWebhookDelete(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := postforme.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Webhooks.Delete(context.TODO(), "id")
+ if err != nil {
+ var apierr *postforme.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}