mattn / go-mastodon Goto Github PK
View Code? Open in Web Editor NEWmastodon client for golang
License: MIT License
mastodon client for golang
License: MIT License
It seems that although the URL for multiple IDS is correctly formed as id[]=1&id[]=2
only the first item is returned.
wsClientを使って、タイムラインを取得するとpanicします。以下がエラー情報です。
panic: interface conversion: interface {} is string, not float64
goroutine 15 [running]:
github.com/silverscat/mastodon-go-test/vendor/github.com/mattn/go-mastodon.(*WSClient).handleWS(0xc42030d650, 0x6fa860, 0xc42001a0e8, 0xc42008b300, 0x7c, 0xc42007ce40, 0x0, 0x0)
/home/kugo/go/src/github.com/silverscat/mastodon-go-test/vendor/github.com/mattn/go-mastodon/streaming_ws.go:130 +0x7d8
github.com/silverscat/mastodon-go-test/vendor/github.com/mattn/go-mastodon.(*WSClient).streamingWS.func1(0xc42007ce40, 0xc42030d650, 0x6fa860, 0xc42001a0e8, 0xc42011ae00)
/home/kugo/go/src/github.com/silverscat/mastodon-go-test/vendor/github.com/mattn/go-mastodon/streaming_ws.go:71 +0x95
created by github.com/silverscat/mastodon-go-test/vendor/github.com/mattn/go-mastodon.(*WSClient).streamingWS
/home/kugo/go/src/github.com/silverscat/mastodon-go-test/vendor/github.com/mattn/go-mastodon/streaming_ws.go:68 +0x352
exit status 2
以下のコードで再現
package main
import (
"context"
"fmt"
"log"
"regexp"
mastodon "github.com/mattn/go-mastodon"
)
func main() {
client := mastodon.NewClient(&mastodon.Config{Server: "https://pawoo.net", ClientID: "くらいあんとあいでー", ClientSecret: "くらいあんとしーくれっと"})
if err := client.Authenticate(context.Background(), "いーめーる", "ぱすわーど"); err != nil {
log.Fatal(err)
}
wsClient := client.NewWSClient()
for {
events, err := wsClient.StreamingWSPublic(context.Background(), false)
if err != nil {
log.Fatal(err)
}
for event := range events {
if upEvent, ok := event.(*mastodon.UpdateEvent); ok {
fmt.Println(fmt.Sprintf("%s %s %s", upEvent.Status.Account.Acct, upEvent.Status.CreatedAt.Local().Format("2006/1/2 15:04:05"), upEvent.Status.Content))
}
}
}
}
I'm currently trying to write a mastodon bot (source code is available here), but unfortunately I get a "invalid_grant" error. The exact error message is:
bad authorization: 401 Unauthorized: invalid_grant
If I register my app and the immediately post a status everything's fine. But the bots purpose is to post every 3.56 days the current status of the year (e.g. "51% if the year is over"), and this somehow leads to the mentioned error. Any idea on how to debug this? Or what I could do about it?! Currently I'm using username/password for authentication, so this shouldn't be a problem (IMHO, not sure about that). Is there maybe a (hidden) access token that gets invalid after a certain time?
Edit: The instance I'm using is mastodon.bayern (Mastodon v2.8.0), and the account is marked as "bot". Not sure if this makes any difference.
Instance構造体のContactAccountですが、jsonの定義が間違っているためデータがnilで返ってきます。
「json:"contact_account"
」が正しいのではないでしょうか?
Hey there,
it would be great to have support for the /v1/admin endpoints as they are very useful for automated moderation :)
According to https://github.com/tootsuite/documentation/blob/master/Using-the-API/Streaming-API.md the "home timelime" is at /api/v1/streaming/user
, but client.StreamingHome tries .../home
.
(Probably should be renamed to client.StreamingUser then.)
Also, it would be nice to add showing this stream this to the mstdn client. (Perhaps I'll brush up my Go and send a PR later.)
Currently, we can decide whether we want --simplejson, which lacks a lot of detail (acct, date...)
or --json, which contains all upstream data but no conveniently formatted text.
Would it be possible to add the result of textContent to the --json format too, so it's easier to work with it without formatting HTML downstream?
The streaming endpoint URL may not be located at the main domain. For instance mastodon.social has it's streaming endpoint at streaming.mastodon.social.
streaming.go currently expects the endpoint to be at the main domain. The actual URL should probably be fetched in StreamingUser() and handed over to streaming() in full. Both methods would need to be touched. Do you want me to apply the change?
Hello,
Is there any reason for not having GetTimelineDirect
(ie GET /api/v1/timelines/direct
) ?
Hey there, thank you for making this SDK, I am making good use of it here: https://github.com/turbot/steampipe-plugin-mastodon
When I got to the followers/following part of the exercise, I wound up doing this workaround: https://github.com/turbot/steampipe-plugin-mastodon/blob/0bbcd2203aafcb4cb0a33b6f9b1d94567dbae600/mastodon/utils.go#L89 If that was unnecessary then please set me straight!
max_id
, since_id
, limit
is required with the following APIs.
https://github.com/tootsuite/documentation/blob/master/Using-the-API/API.md
I have three ideas.
func (c *Client) GetTimelineHome(ctx context.Context, maxID, sinceID, limit *int) (tl []*Status, retMaxID, retSinceID int, err error)
Pagination
.type Pagination struct {
MaxID *int
SinceID *int
Limit *int
}
func (c *Client) GetTimelineHome(ctx context.Context, pn *Pagination) ([]*Status, *Pagination, error)
max_id
and since_id
using the Timeline
type.type Timeline struct {
Statuses []*Status
MaxID int
SinceID int
}
func (c *Client) GetTimelineHome(ctx context.Context, maxID, sinceID, limit *int) (*Timeline, error)
Which do you think is good?
Also, please tell me if there is any other good way.
This project has a go.mod version set to 1.16, but build tests are still testing on 1.15 - Is this intentional? I ask as a couple of functions were moved out of ioutil into os in 1.16 and I'd like to clean that up. But that breaks the 1.15 build
Im trying to send a Toot to a gotosocial instance.
While its working perfectly fine sending a Toot to a Mastodon Instance, it does throw an invalid_request
error to gotosocial.
The code that I use for reference
func postToMastodon(text string) error {
var c *mastodon.Client
var t *mastodon.Toot
// Register App
app, err := mastodon.RegisterApp(context.Background(), &mastodon.AppConfig{
Server: "https://this.server/",
ClientName: "relaystation",
Scopes: "read write follow",
Website: "urn:ietf:wg:oauth:2.0:oob",
})
if err != nil {
log.Fatal(err)
}
// authenticate
c = mastodon.NewClient(&mastodon.Config{
Server: "https://this.server/",
ClientID: app.ClientID,
ClientSecret: app.ClientSecret,
})
err = c.Authenticate(context.Background(), "[email protected]", "secret")
if err != nil {
log.Fatal(err)
}
t = &mastodon.Toot{}
t.Status = text
}
This is the error that I get
2022/12/20 11:47:53 bad authorization: 400 Bad Request: invalid_request
This is in the logs of gotosocial.
gotosocial[843043]: timestamp="20/12/2022 10:07:17.585" func=router.loggingMiddleware.func1 level=INFO latency=338.232µs clientIP=10.88.0.29 userAgent=Go-http-client/2.0 method=POST statusCode=400 path=/oauth/token msg="Bad Request: wrote 115B"
And the corresponding part on the gotosocial side of auth is https://github.com/superseriousbusiness/gotosocial/blob/694a49058951de31cca4ea061e2c08d44e712612/internal/api/client/auth/token.go#L32-L55
I'm not entirely sure what the cause, someone else having this issue or am I doing something wrong?
I tried using go-mastodon against the https://chaos.social
instance, which uses version 2.6.5 according to https://chaos.social/api/v1/instance, with following code:
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/mattn/go-mastodon"
)
func main() {
ctx := context.Background()
c := mastodon.NewClient(&mastodon.Config{
Server: "https://chaos.social",
})
pg := mastodon.Pagination{}
for {
timeline, err := c.GetTimelinePublic(ctx, false, &pg)
if err != nil {
log.Println(err)
}
for _, item := range timeline {
fmt.Printf("%#v\n", item)
}
if pg.MaxID == "" {
break
}
time.Sleep(10 * time.Second)
}
}
This quits with the output
2018/12/21 07:25:04 strconv.ParseInt: parsing "": invalid syntax
which is coming from
Line 296 in 4def10a
I have an experimental fix that works for me here for the simple purpose of the above code: https://github.com/marians/go-mastodon/pull/1/files
My understanding of the Mastodon API version differences is not deep enough to tell when min_id
has been introduced, where it is used, whether since_id
is still in use etc. So I can't provide a PR currently that makes pagination work in all cases. Hopefully the description is enough for others to do so. Thanks!
Hi,
I was wondering if there is any editing option for the statuses in the package or not. So for example if we have a status that is already posted on Mastodon, is there any way that we can edit that?
Hello, I noticed the "bot" and "discoverable" flags was missing from the Profile struct. Is it possible to add them?
I would like to use it to update accounts for bots and I'm willing to solve this issue myself with a PR at a later date.
(for reference, the flags are documented in the mastodon docs)
I am attempting to use this library to write a bot that posts markov generated sentences based upon a users history. Below is a snippet of the code I am using to download an accounts history:
pg := mastodon.Pagination{}
last, err := s.db.GetLastStatusIdForAccount(*account)
fmt.Println(fmt.Sprintf("Continuing from: %s", last))
if err != nil {
return cli.Exit(err, 1)
}
if last != "-1" {
pg.MinID = last
}
page := 1
for {
ss, err := s.client.GetAccountStatuses(context.Background(), account.ID, &pg)
if err != nil {
return cli.Exit(err, 1)
}
err = s.db.InsertStatuses(ss)
if err != nil {
return cli.Exit(err, 1)
}
fmt.Println(fmt.Sprintf("%d, Messages Found: %d", page, len(ss)))
if pg.MaxID == "" {
break
}
pg.SinceID = ""
pg.MinID = ""
time.Sleep(3 * time.Second)
page++
}
By setting the MinID to an empty string in each iteration it seems to go from the most recent page backwards; my account has about 6000 statuses but this seems to get to 70 pages of 20 results plus a final page of 6 making for a total of about 1,300 statuses.
Is there something I am doing wrong or does Mastodon/Pleroma limit how far back in history we can go with the API?
For some reason the go.mod points to someone else's repo now and it means this package can't be installed.
err := c.GetTimeline("/api/v1/timelines/home")
if err != nil {
log.Fatal(err)
}
GetTimeline is not implemented.
Currently the URL that's produced is like so:
https://social.coop/api/v1/lists/1064/accounts?account_ids=109348240344188934
Which returns 200 but does not add to the list.
This will actually add to the list:
https://social.coop/api/v1/lists/1064/accounts?account_ids[]=109348240344188934
I made this change to complete my task, but not raising a PR because I'm not sure where else this might be happening.
+++ b/lists.go
@@ -90,7 +90,7 @@ func (c *Client) DeleteList(ctx context.Context, id ID) error {
func (c *Client) AddToList(ctx context.Context, list ID, accounts ...ID) error {
params := url.Values{}
for _, acct := range accounts {
- params.Add("account_ids", string(acct))
+ params.Add("account_ids[]", string(acct))
}
I'm not sure if this is a library limitation or not, but I noticed that I received invalid_grant errors until I turned off 2factor.
To give a bit of context as to what I am talking about, here is how the NewClient
function looks like:
// NewClient returns a new mastodon API client.
func NewClient(config *Config) *Client {
return &Client{
Client: *http.DefaultClient,
Config: config,
}
}
While I could possibly understand the concerns (prevent mutability, etc), it breaks the expected semantic. http.Client
is a pointer type (as it can be seen by http.DefaultHTTPClient
). Even though a copy by value is perfectly OK for now, you may never know if it won't hold a mutex or something similar in the future that would turn making a copy into a bug.
I'm trying to use AuthenticateApp and it seems to be authenticating ok (at least, it doesn't err) but when I try to post a status I get the following error:
bad request: 403 Forbidden: This action is outside the authorized scopes
yet I have read/write all scopes selected on my app configuration within mastodon (created manually and just using teh client id/secret from that)
So I got to looking and noticed that the Authenticate func provides scopes:
// Authenticate gets access-token to the API.
func (c *Client) Authenticate(ctx context.Context, username, password string) error {
params := url.Values{
"client_id": {c.Config.ClientID},
"client_secret": {c.Config.ClientSecret},
"grant_type": {"password"},
"username": {username},
"password": {password},
"scope": {"read write follow"},
}
return c.authenticate(ctx, params)
}
Here's the action I'm trying to take:
theToot := mastodon.Toot{
Status: message,
}
_, err = client.PostStatus(context.Background(), &theToot)
Does AuthenticateApp need to do the same to work? Or am I doing something dumb? :)
Thanks!
Since Mastodon is a federated system, usernames are not unique, and we don't necessarily know which username was the real poster. The data in account.acct
will be equal to username for the same instance, and else something like [email protected]
.
(This is what the official web frontend displays too.)
go get github.com/mattn/go-mastodon
# github.com/mattn/go-mastodon
../../mattn/go-mastodon/status.go:183: undefined: url.PathEscape
Cannot download and use this lib :-(
When trying to work with AuthenticateToken I found it quite confusing on how to get the returned AccessToken. It's currently located in a private member of the client and it's unclear how the developer intends for you to save it for future use.
I ended up just temporarily modifying the code to just print it out to console, but that seems like an awful solution. I think a could solution would be return it on AuthenticateToken().
Hi,
UploadMedia and UploadMediaFromReader doesn't seem to support adding a description to your files or am I missing something?
I can help with a PR in that case, but want to know if it's already possible first
Is it possible that this a problem with Mastodon 2.0?
vxv@vxl:/wrk/scoop/cli$ cat reg.go
package main
import (
"context"
"fmt"
"log"
masto "github.com/mattn/go-mastodon"
)
func main() {
app, err := masto.RegisterApp(context.Background(), &masto.AppConfig{
Server: "https://social.coop",
ClientName: "socialcoop-blog",
Scopes: "read write follow",
Website: "https://social.coop/@h",
})
if err != nil {
log.Fatal(err)
}
fmt.Printf("client-id : %v+\n", app.ClientID)
fmt.Printf("client-secret: %v+\n", app.ClientSecret)
}
vxv@vxl:/wrk/scoop/cli$ go build reg.go
vxv@vxl:/wrk/scoop/cli$ ./reg
2017/11/22 22:48:38 json: cannot unmarshal string into Go struct field Application.id of type int64
vxv@vxl:/wrk/scoop/cli$
Right now parsing Content
for HTML is really not great, this would allow having the text only and not the HTML.
For example, if I have the following statusIDs.
100, 99, 98 ... 1
If I make the following call:
/api/v1/timelines/public?since_id=74&max_id=78
I would expect the following results: [77, 76, 75]. This is also what I get when I call the api directly.
However, what I currently see is : [77, 76, 75, 74, 73, 72, ... etc]
I don't understand why go-mastodon deliberately sets since_id to an empty string if a max_id is specified. I would like to be able to paginate through the results until I reach the since_id that I specified, but that's not currently possible because when I specify a max_id, then my since_id value is ignored...
Instead of https://github.com/mattn/go-mastodon/blob/master/mastodon.go#L311
func (p *Pagination) setValues(params url.Values) url.Values {
if p.MaxID != "" {
params.Set("max_id", string(p.MaxID))
} else if p.SinceID != "" {
params.Set("since_id", string(p.SinceID))
}
if p.Limit > 0 {
params.Set("limit", fmt.Sprint(p.Limit))
}
return params
}
why not?:
if p.MaxID != "" {
params.Set("max_id", string(p.MaxID))
}
if p.SinceID != "" {
params.Set("since_id", string(p.SinceID))
}
I know this has been raised before although I can't seem to work out what the issue is. I've tried registering the app in the web UI preferences and also with [go-mastodon](https://github.com/mattn/go-mastodon)
and whatever I try I get bad authorization: 400 Bad Request: invalid_grant
in response.
I've tried the following code (obviously with the correct values) and I can't get it to work, any ideas I could try?
Thanks!
package main
import (
"context"
"log"
"github.com/mattn/go-mastodon"
)
func main() {
app, err := mastodon.RegisterApp(context.Background(), &mastodon.AppConfig{
Server: "https://the.server",
ClientName: "my-client",
Scopes: "read write follow",
Website: "https://github.com/the/path",
})
if err != nil {
log.Fatal(err)
}
cl := mastodon.NewClient(&mastodon.Config{
Server: "https://the.server",
ClientID: app.ClientID,
ClientSecret: app.ClientSecret,
})
err = cl.Authenticate(context.Background(), "[email protected]", "password")
if err != nil {
log.Fatal(err)
}
}
Hey,
can you please start tagging your commits from time to time to be able to stay up to date when using go mod?
Cheers
I got an error below when I use StreamingWSUser().
panic: interface conversion: interface {} is string, not float64
goroutine 18 [running]:
github.com/mattn/go-mastodon.(*WSClient).handleWS(0xc4204261c0, 0x7d4cc0, 0xc420016058, 0xc42008a780, 0x7d, 0xc42001a7e0, 0x0, 0xc420280240)
/go/src/github.com/mattn/go-mastodon/streaming_ws.go:131 +0x93d
github.com/mattn/go-mastodon.(*WSClient).streamingWS.func1(0xc42001a7e0, 0xc4204261c0, 0x7d4cc0, 0xc420016058, 0xc4200dc280)
/go/src/github.com/mattn/go-mastodon/streaming_ws.go:72 +0x95
created by github.com/mattn/go-mastodon.(*WSClient).streamingWS
/go/src/github.com/mattn/go-mastodon/streaming_ws.go:69 +0x339
I've previously used Mastodon.py and once you have the AccessToken you don't require the ClientID and ClientSecret. This doesn't seem to be the case with go-mastodon. Is there a reason for this? Can this be changed to Mastodon.py's behavior?
Did this repository go back in time?
I know I'm just an idiot, but I can't figure out how to get it working. Please, send instructions. I have been trying to get it to work for 1+ hrs. I use Win11, I have Go installed.
It would be nice to make the scope to operate on configurable in Authenticate
. Currently it's hard-coded to "read write follow", which seems to be the full permission set.
It looks like the library doesn't yet have any support for the V2 APIs introduced in Mastodon 4.0.0. Is there work underway to add it? I need some support for it and don't mind at all starting to add it in, but I don't want to duplicate work that's already underway.
In both go.mod
and example_test.go
the module github.com/rmrfslashbin/go-mastodon
is used instead of github.com/mattn/go-mastodon
. This applies to both the zip
file and the tar.gz
file in the v0.0.7
release.
This reference is not used in the source code itself and it looks like it was already fixed last week but no new tag was added.
Instead, only an empty line is displayed.
(Use --type user:yourusername
to reproduce.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.