ruma_client_api/membership/
invite_user.rs

1//! `POST /_matrix/client/*/rooms/{roomId}/invite`
2//!
3//! Invite a user to a room.
4
5pub mod v3 {
6    //! `/v3/` ([spec (MXID)][spec-mxid], [spec (3PID)][spec-3pid])
7    //!
8    //! This endpoint has two forms: one to invite a user
9    //! [by their Matrix identifier][spec-mxid], and one to invite a user
10    //! [by their third party identifier][spec-3pid].
11    //!
12    //! [spec-mxid]: https://spec.matrix.org/latest/client-server-api/#post_matrixclientv3roomsroomidinvite
13    //! [spec-3pid]: https://spec.matrix.org/latest/client-server-api/#thirdparty_post_matrixclientv3roomsroomidinvite
14
15    use ruma_common::{
16        OwnedRoomId, OwnedUserId,
17        api::{auth_scheme::AccessToken, request, response},
18        metadata,
19    };
20    use serde::{Deserialize, Serialize};
21
22    use crate::membership::Invite3pid;
23
24    metadata! {
25        method: POST,
26        rate_limited: true,
27        authentication: AccessToken,
28        history: {
29            1.0 => "/_matrix/client/r0/rooms/{room_id}/invite",
30            1.1 => "/_matrix/client/v3/rooms/{room_id}/invite",
31        }
32    }
33
34    /// Request type for the `invite_user` endpoint.
35    #[request(error = crate::Error)]
36    pub struct Request {
37        /// The room where the user should be invited.
38        #[ruma_api(path)]
39        pub room_id: OwnedRoomId,
40
41        /// The user to invite.
42        #[serde(flatten)]
43        pub recipient: InvitationRecipient,
44
45        /// Optional reason for inviting the user.
46        #[serde(skip_serializing_if = "Option::is_none")]
47        pub reason: Option<String>,
48    }
49
50    /// Response type for the `invite_user` endpoint.
51    #[response(error = crate::Error)]
52    #[derive(Default)]
53    pub struct Response {}
54
55    impl Request {
56        /// Creates a new `Request` with the given room ID and invitation recipient.
57        pub fn new(room_id: OwnedRoomId, recipient: InvitationRecipient) -> Self {
58            Self { room_id, recipient, reason: None }
59        }
60    }
61
62    impl Response {
63        /// Creates an empty `Response`.
64        pub fn new() -> Self {
65            Self {}
66        }
67    }
68
69    /// Distinguishes between invititations by Matrix or third party identifiers.
70    #[derive(Clone, Debug, Deserialize, Serialize)]
71    #[cfg_attr(not(ruma_unstable_exhaustive_types), non_exhaustive)]
72    #[serde(untagged)]
73    pub enum InvitationRecipient {
74        /// Used to invite user by their Matrix identifier.
75        UserId {
76            /// Matrix identifier of user.
77            user_id: OwnedUserId,
78        },
79
80        /// Used to invite user by a third party identifier.
81        ThirdPartyId(Invite3pid),
82    }
83
84    #[cfg(test)]
85    mod tests {
86        use assert_matches2::assert_matches;
87        use ruma_common::thirdparty::Medium;
88        use serde_json::{from_value as from_json_value, json};
89
90        use super::InvitationRecipient;
91
92        #[test]
93        fn deserialize_invite_by_user_id() {
94            let incoming =
95                from_json_value::<InvitationRecipient>(json!({ "user_id": "@carl:example.org" }))
96                    .unwrap();
97
98            assert_matches!(incoming, InvitationRecipient::UserId { user_id });
99            assert_eq!(user_id, "@carl:example.org");
100        }
101
102        #[test]
103        fn deserialize_invite_by_3pid() {
104            let incoming = from_json_value::<InvitationRecipient>(json!({
105                "id_server": "example.org",
106                "id_access_token": "abcdefghijklmnop",
107                "medium": "email",
108                "address": "carl@example.org"
109            }))
110            .unwrap();
111
112            assert_matches!(incoming, InvitationRecipient::ThirdPartyId(third_party_id));
113
114            assert_eq!(third_party_id.id_server, "example.org");
115            assert_eq!(third_party_id.id_access_token, "abcdefghijklmnop");
116            assert_eq!(third_party_id.medium, Medium::Email);
117            assert_eq!(third_party_id.address, "carl@example.org");
118        }
119    }
120}