Allow calling follow/unfollow API methods multiple times
For compatibility with Mastodon.
This commit is contained in:
parent
d46165f397
commit
6d331f7669
3 changed files with 97 additions and 27 deletions
|
@ -204,6 +204,38 @@ paths:
|
|||
$ref: '#/components/schemas/Account'
|
||||
404:
|
||||
description: Profile not found
|
||||
/api/v1/accounts/{account_id}/follow:
|
||||
post:
|
||||
summary: Follow the given actor.
|
||||
security:
|
||||
- tokenAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/account_id'
|
||||
responses:
|
||||
200:
|
||||
description: Successfully followed, or actor was already followed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Relationship'
|
||||
404:
|
||||
description: Profile not found
|
||||
/api/v1/accounts/{account_id}/unfollow:
|
||||
post:
|
||||
summary: Unfollow the given actor.
|
||||
security:
|
||||
- tokenAuth: []
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/account_id'
|
||||
responses:
|
||||
200:
|
||||
description: Successfully unfollowed, or actor was already not followed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Relationship'
|
||||
404:
|
||||
description: Profile not found
|
||||
/api/v1/statuses/{status_id}:
|
||||
delete:
|
||||
summary: Delete post
|
||||
|
@ -330,6 +362,10 @@ paths:
|
|||
$ref: '#/components/schemas/Status'
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
tokenAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
parameters:
|
||||
account_id:
|
||||
name: account_id
|
||||
|
@ -367,6 +403,22 @@ components:
|
|||
description: Ethereum wallet address.
|
||||
type: string
|
||||
example: '0xd8da6bf...'
|
||||
Relationship:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
description: The account id.
|
||||
type: string
|
||||
format: uuid
|
||||
following:
|
||||
description: Are you following this user?
|
||||
type: boolean
|
||||
followed_by:
|
||||
description: Are you followed by this user?
|
||||
type: boolean
|
||||
requested:
|
||||
description: Do you have a pending follow request for this user?
|
||||
type: boolean
|
||||
Status:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -12,7 +12,7 @@ use crate::activitypub::actor::Actor;
|
|||
use crate::activitypub::deliverer::deliver_activity;
|
||||
use crate::config::Config;
|
||||
use crate::database::{Pool, get_database_client};
|
||||
use crate::errors::{HttpError, ValidationError};
|
||||
use crate::errors::{DatabaseError, HttpError, ValidationError};
|
||||
use crate::ethereum::gate::is_allowed_user;
|
||||
use crate::mastodon_api::oauth::auth::get_current_user;
|
||||
use crate::models::posts::helpers::{
|
||||
|
@ -209,16 +209,25 @@ async fn follow_account(
|
|||
let target = get_profile_by_id(db_client, &account_id).await?;
|
||||
if let Some(remote_actor) = target.actor_json {
|
||||
// Remote follow
|
||||
let request = create_follow_request(db_client, ¤t_user.id, &target.id).await?;
|
||||
let activity = create_activity_follow(
|
||||
&config.instance_url(),
|
||||
¤t_user.profile,
|
||||
&request.id,
|
||||
&remote_actor.id,
|
||||
);
|
||||
deliver_activity(&config, ¤t_user, activity, vec![remote_actor]);
|
||||
match create_follow_request(db_client, ¤t_user.id, &target.id).await {
|
||||
Ok(request) => {
|
||||
let activity = create_activity_follow(
|
||||
&config.instance_url(),
|
||||
¤t_user.profile,
|
||||
&request.id,
|
||||
&remote_actor.id,
|
||||
);
|
||||
deliver_activity(&config, ¤t_user, activity, vec![remote_actor]);
|
||||
},
|
||||
Err(DatabaseError::AlreadyExists(_)) => (), // already following
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
} else {
|
||||
follow(db_client, ¤t_user.id, &target.id).await?;
|
||||
match follow(db_client, ¤t_user.id, &target.id).await {
|
||||
Ok(_) => (),
|
||||
Err(DatabaseError::AlreadyExists(_)) => (), // already following
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
};
|
||||
let relationship = get_relationship(
|
||||
db_client,
|
||||
|
@ -240,26 +249,35 @@ async fn unfollow_account(
|
|||
let target = get_profile_by_id(db_client, &account_id).await?;
|
||||
if let Some(remote_actor) = target.actor_json {
|
||||
// Remote follow
|
||||
let follow_request = get_follow_request_by_path(
|
||||
match get_follow_request_by_path(
|
||||
db_client,
|
||||
¤t_user.id,
|
||||
&target.id,
|
||||
).await?;
|
||||
unfollow(
|
||||
db_client,
|
||||
¤t_user.id,
|
||||
&target.id,
|
||||
).await?;
|
||||
// Federate
|
||||
let activity = create_activity_undo_follow(
|
||||
&config.instance_url(),
|
||||
¤t_user.profile,
|
||||
&follow_request.id,
|
||||
&remote_actor.id,
|
||||
);
|
||||
deliver_activity(&config, ¤t_user, activity, vec![remote_actor]);
|
||||
).await {
|
||||
Ok(follow_request) => {
|
||||
unfollow(
|
||||
db_client,
|
||||
¤t_user.id,
|
||||
&target.id,
|
||||
).await?;
|
||||
// Federate
|
||||
let activity = create_activity_undo_follow(
|
||||
&config.instance_url(),
|
||||
¤t_user.profile,
|
||||
&follow_request.id,
|
||||
&remote_actor.id,
|
||||
);
|
||||
deliver_activity(&config, ¤t_user, activity, vec![remote_actor]);
|
||||
},
|
||||
Err(DatabaseError::NotFound(_)) => (), // not following
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
} else {
|
||||
unfollow(db_client, ¤t_user.id, &target.id).await?;
|
||||
match unfollow(db_client, ¤t_user.id, &target.id).await {
|
||||
Ok(_) => (),
|
||||
Err(DatabaseError::NotFound(_)) => (), // not following
|
||||
Err(other_error) => return Err(other_error.into()),
|
||||
};
|
||||
};
|
||||
let relationship = get_relationship(
|
||||
db_client,
|
||||
|
|
|
@ -161,7 +161,7 @@ pub async fn create_follow_request(
|
|||
&request.target_id,
|
||||
&request.request_status,
|
||||
],
|
||||
).await?;
|
||||
).await.map_err(catch_unique_violation("follow request"))?;
|
||||
Ok(request)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue