@@ -183,9 +183,9 @@ type DeleteRecordPayload struct {
183183}
184184
185185type PostInteractionRecord struct {
186- Type string `json:"$type"`
187- CreatedAt string `json:"createdAt"`
188- Subject Subject `json:"subject"`
186+ Type string `json:"$type"`
187+ CreatedAt string `json:"createdAt"`
188+ Subject interface {} `json:"subject"`
189189}
190190
191191type CreatePostRecord struct {
@@ -322,6 +322,30 @@ func GetUserInfo(pds string, token string, screen_name string) (*bridge.TwitterU
322322 return twitterUser , nil
323323}
324324
325+ func GetUserInfoRaw (pds string , token string , screen_name string ) (* User , error ) {
326+ url := pds + "/xrpc/app.bsky.actor.getProfile" + "?actor=" + screen_name
327+
328+ resp , err := SendRequest (& token , http .MethodGet , url , nil )
329+ if err != nil {
330+ return nil , err
331+ }
332+ defer resp .Body .Close ()
333+ if resp .StatusCode != http .StatusOK {
334+ bodyBytes , _ := io .ReadAll (resp .Body )
335+ bodyString := string (bodyBytes )
336+ fmt .Println ("Response Status:" , resp .StatusCode )
337+ fmt .Println ("Response Body:" , bodyString )
338+ return nil , errors .New ("failed to fetch user info" )
339+ }
340+
341+ author := User {}
342+ if err := json .NewDecoder (resp .Body ).Decode (& author ); err != nil {
343+ return nil , err
344+ }
345+
346+ return & author , nil
347+ }
348+
325349func GetUsersInfo (pds string , token string , items []string , ignoreCache bool ) ([]* bridge.TwitterUser , error ) {
326350 var results []* bridge.TwitterUser
327351 var missing []string
@@ -791,7 +815,7 @@ func LikePost(pds string, token string, id string, my_did string) (error, *Threa
791815 bodyString := string (bodyBytes )
792816 fmt .Println ("Response Status:" , resp .StatusCode )
793817 fmt .Println ("Response Body:" , bodyString )
794- return errors .New ("failed to retweet : " + bodyString ), nil
818+ return errors .New ("failed to like : " + bodyString ), nil
795819 }
796820
797821 likeRes := CreateRecordResult {}
@@ -834,19 +858,120 @@ func UnlikePost(pds string, token string, id string, my_did string) (error, *Thr
834858 bodyString := string (bodyBytes )
835859 fmt .Println ("Response Status:" , resp .StatusCode )
836860 fmt .Println ("Response Body:" , bodyString )
837- return errors .New ("failed to retweet : " + bodyString ), nil
861+ return errors .New ("failed to unlike : " + bodyString ), nil
838862 }
839863
840864 likeRes := CreateRecordResult {}
841865 if err := json .NewDecoder (resp .Body ).Decode (& likeRes ); err != nil {
842866 return err , nil
843867 }
844868
845- thread .Thread .Post .Viewer .Like = & likeRes .URI // maybe?
869+ emptyString := ""
870+ thread .Thread .Post .Viewer .Like = & emptyString
846871
847872 return nil , thread
848873}
849874
875+ func FollowUser (pds string , token string , targetActor string , my_did string ) (error , * User ) {
876+ url := pds + "/xrpc/com.atproto.repo.createRecord"
877+
878+ targetUser , err := GetUserInfoRaw (pds , token , targetActor )
879+ if err != nil {
880+ return errors .New ("failed to fetch post" ), nil
881+ }
882+
883+ if targetUser .Viewer .Following != nil {
884+ return errors .New ("already following user" ), nil
885+ }
886+
887+ payload := CreateRecordPayload {
888+ Collection : "app.bsky.graph.follow" ,
889+ Repo : my_did ,
890+ Record : PostInteractionRecord {
891+ Type : "app.bsky.graph.follow" ,
892+ CreatedAt : time .Now ().UTC ().Format (time .RFC3339 ),
893+ Subject : targetUser .DID ,
894+ },
895+ }
896+
897+ reqBody , err := json .Marshal (payload )
898+ if err != nil {
899+ return errors .New ("failed to marshal payload" ), nil
900+ }
901+
902+ resp , err := SendRequest (& token , http .MethodPost , url , bytes .NewReader (reqBody ))
903+ if err != nil {
904+ return err , nil
905+ }
906+ defer resp .Body .Close ()
907+
908+ if resp .StatusCode != http .StatusOK {
909+ bodyBytes , _ := io .ReadAll (resp .Body )
910+ bodyString := string (bodyBytes )
911+ fmt .Println ("Response Status:" , resp .StatusCode )
912+ fmt .Println ("Response Body:" , bodyString )
913+ return errors .New ("failed to retweet: " + bodyString ), nil
914+ }
915+
916+ followRes := CreateRecordResult {}
917+ if err := json .NewDecoder (resp .Body ).Decode (& followRes ); err != nil {
918+ return err , nil
919+ }
920+
921+ targetUser .Viewer .Following = & strings .Split (followRes .URI , "/app.bsky.graph.follow/" )[1 ]
922+ targetUser .FollowersCount ++
923+
924+ return nil , targetUser
925+ }
926+
927+ func UnfollowUser (pds string , token string , targetActor string , my_did string ) (error , * User ) {
928+ url := pds + "/xrpc/com.atproto.repo.deleteRecord"
929+
930+ targetUser , err := GetUserInfoRaw (pds , token , targetActor )
931+ if err != nil {
932+ return errors .New ("failed to fetch post" ), nil
933+ }
934+
935+ if targetUser .Viewer .Following == nil {
936+ return errors .New ("not following user" ), nil
937+ }
938+
939+ payload := DeleteRecordPayload {
940+ Collection : "app.bsky.graph.follow" ,
941+ Repo : my_did ,
942+ RKey : strings .Split (* targetUser .Viewer .Following , "/app.bsky.graph.follow/" )[1 ],
943+ }
944+
945+ reqBody , err := json .Marshal (payload )
946+ if err != nil {
947+ return errors .New ("failed to marshal payload" ), nil
948+ }
949+
950+ resp , err := SendRequest (& token , http .MethodPost , url , bytes .NewReader (reqBody ))
951+ if err != nil {
952+ return err , nil
953+ }
954+ defer resp .Body .Close ()
955+
956+ if resp .StatusCode != http .StatusOK {
957+ bodyBytes , _ := io .ReadAll (resp .Body )
958+ bodyString := string (bodyBytes )
959+ fmt .Println ("Response Status:" , resp .StatusCode )
960+ fmt .Println ("Response Body:" , bodyString )
961+ return errors .New ("failed to unfollow: " + bodyString ), nil
962+ }
963+
964+ unfollowRes := CreateRecordResult {}
965+ if err := json .NewDecoder (resp .Body ).Decode (& unfollowRes ); err != nil {
966+ return err , nil
967+ }
968+
969+ emptyString := ""
970+ targetUser .Viewer .Following = & emptyString
971+
972+ return nil , targetUser
973+ }
974+
850975func GetLikes (pds string , token string , uri string , limit int ) (* Likes , error ) {
851976 url := fmt .Sprintf (pds + "/xrpc/app.bsky.feed.getLikes?limit=%d&uri=%s" , limit , uri )
852977
@@ -866,7 +991,7 @@ func GetLikes(pds string, token string, uri string, limit int) (*Likes, error) {
866991 bodyString := string (bodyBytes )
867992 fmt .Println ("Response Status:" , resp .StatusCode )
868993 fmt .Println ("Response Body:" , bodyString )
869- return nil , errors .New ("failed to fetch timeline " )
994+ return nil , errors .New ("failed to fetch likes " )
870995 }
871996
872997 likes := Likes {}
@@ -896,7 +1021,7 @@ func GetRetweetAuthors(pds string, token string, uri string, limit int) (*Repost
8961021 bodyString := string (bodyBytes )
8971022 fmt .Println ("Response Status:" , resp .StatusCode )
8981023 fmt .Println ("Response Body:" , bodyString )
899- return nil , errors .New ("failed to fetch timeline " )
1024+ return nil , errors .New ("failed to fetch retweet authors " )
9001025 }
9011026
9021027 retweetAuthors := RepostedBy {}
0 commit comments