diff --git a/src/ChannelClient.php b/src/ChannelClient.php index 855ad95..f4aaa3e 100644 --- a/src/ChannelClient.php +++ b/src/ChannelClient.php @@ -18,7 +18,7 @@ public function __construct(string $landlord_id, string $channel_id, string $dis protected function authQuery(RequestInterface $request): array{ $timestamp = time(); - $auth = $this->generateAuth((string)$timestamp); + $auth = $this->generateAuth((string)$request->getBody(), (string)$timestamp); return [ 'auth' => $auth, @@ -27,7 +27,7 @@ protected function authQuery(RequestInterface $request): array{ ]; } - private function generateAuth(string $timestamp): string{ - return hash_hmac('sha256', $timestamp, $this->display_key) ?: ''; + private function generateAuth(string $json, string $timestamp): string{ + return hash_hmac('sha256', $json.$timestamp, $this->display_key) ?: ''; } } diff --git a/src/Models/EnquiryCreation.php b/src/Models/EnquiryCreation.php new file mode 100644 index 0000000..bb31103 --- /dev/null +++ b/src/Models/EnquiryCreation.php @@ -0,0 +1,292 @@ +property_id; + } + + + /** + * @param int $property_id + * + * @return $this + */ + public function setPropertyId($property_id) + { + $this->property_id = $property_id; + + return $this; + } + + + /** + * @return string + */ + public function getContractId() + { + return $this->contract_id; + } + + + /** + * @param string $contract_id + * + * @return $this + */ + public function setContractId($contract_id) + { + $this->contract_id = $contract_id; + + return $this; + } + + + /** + * @return string + */ + public function getFirstName() + { + return $this->first_name; + } + + + /** + * @param string $first_name + * + * @return $this + */ + public function setFirstName($first_name) + { + $this->first_name = $first_name; + + return $this; + } + + + /** + * @return string + */ + public function getLastName() + { + return $this->last_name; + } + + + /** + * @param string $last_name + * + * @return $this + */ + public function setLastName($last_name) + { + $this->last_name = $last_name; + + return $this; + } + + + /** + * @return string + */ + public function getEmail() + { + return $this->email; + } + + + /** + * @param string $email + * + * @return $this + */ + public function setEmail($email) + { + $this->email = $email; + + return $this; + } + + + /** + * @return string + */ + public function getPhone() + { + return $this->phone; + } + + + /** + * @param string $phone + * + * @return $this + */ + public function setPhone($phone) + { + $this->phone = $phone; + + return $this; + } + + + /** + * @return string + */ + public function getTenantType() + { + return $this->tenant_type; + } + + + /** + * @param string $tenant_type + * + * @return $this + */ + public function setTenantType($tenant_type) + { + $this->tenant_type = $tenant_type; + + return $this; + } + + + /** + * @return string + */ + public function getEnquiryMethod() + { + return $this->enquiry_method; + } + + + /** + * @param string $enquiry_method + * + * @return $this + */ + public function setEnquiryMethod($enquiry_method) + { + $this->enquiry_method = $enquiry_method; + + return $this; + } + + + /** + * @return string + */ + public function getEnquiryType() + { + return $this->enquiry_type; + } + + + /** + * @param string $enquiry_type + * + * @return $this + */ + public function setEnquiryType($enquiry_type) + { + $this->enquiry_type = $enquiry_type; + + return $this; + } + + + /** + * @return string + */ + public function getMessage() + { + return $this->message; + } + + + /** + * @param string $message + * + * @return $this + */ + public function setMessage($message) + { + $this->message = $message; + + return $this; + } +} diff --git a/src/Models/EnquirySaved.php b/src/Models/EnquirySaved.php new file mode 100644 index 0000000..ceafc01 --- /dev/null +++ b/src/Models/EnquirySaved.php @@ -0,0 +1,36 @@ +enquiry_id; + } + + + /** + * @param string $enquiry_id + * + * @return $this + */ + public function setEnquiryId($enquiry_id) + { + $this->enquiry_id = $enquiry_id; + + return $this; + } +} diff --git a/src/Models/PropertyManager.php b/src/Models/PropertyManager.php index d95512b..64bbbc0 100644 --- a/src/Models/PropertyManager.php +++ b/src/Models/PropertyManager.php @@ -34,6 +34,14 @@ class PropertyManager extends SwaggerModel */ protected $company = ''; + /** + * True if the landlord has given the channel permission to send + * enquiries for their listings (e.g. via POST /enquiry) + * + * @var bool + */ + protected $can_send_enquiries = false; + /** * @return string @@ -121,4 +129,26 @@ public function setCompany($company) return $this; } + + + /** + * @return bool + */ + public function getCanSendEnquiries() + { + return $this->can_send_enquiries; + } + + + /** + * @param bool $can_send_enquiries + * + * @return $this + */ + public function setCanSendEnquiries($can_send_enquiries) + { + $this->can_send_enquiries = $can_send_enquiries; + + return $this; + } } diff --git a/src/Requests/GetProperties.php b/src/Requests/GetProperties.php index b6203e8..98db3c9 100644 --- a/src/Requests/GetProperties.php +++ b/src/Requests/GetProperties.php @@ -20,7 +20,15 @@ class GetProperties extends SwaggerRequest * @var null */ public $page; - protected static array $query_params = ['page']; + + /** + * Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' + * + * + * @var null + */ + public $version; + protected static array $query_params = ['page', 'version']; public function setPage($page) @@ -29,6 +37,12 @@ public function setPage($page) } + public function setVersion($version) + { + $this->version = $version; + } + + /** * @return \SturentsLib\Api\Models\ListProperties|\SturentsLib\Api\Models\Error|\SturentsLib\Api\Models\AuthError|\SturentsLib\Api\Models\GetError|\SturentsLib\Api\Models\RateLimitError|list<\SturentsLib\Api\Models\ListProperties>|list<\SturentsLib\Api\Models\Error>|list<\SturentsLib\Api\Models\AuthError>|list<\SturentsLib\Api\Models\GetError>|list<\SturentsLib\Api\Models\RateLimitError> */ diff --git a/src/Requests/GetSummary.php b/src/Requests/GetSummary.php index e80d63d..13bec55 100644 --- a/src/Requests/GetSummary.php +++ b/src/Requests/GetSummary.php @@ -10,6 +10,22 @@ class GetSummary extends SwaggerRequest public const METHOD = 'GET'; public const URI = '/api/summary'; + /** + * Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' + * + * + * @var null + */ + public $version; + protected static array $query_params = ['version']; + + + public function setVersion($version) + { + $this->version = $version; + } + + /** * @return \SturentsLib\Api\Models\PropertyManager|\SturentsLib\Api\Models\Error|\SturentsLib\Api\Models\AuthError|\SturentsLib\Api\Models\GetError|list<\SturentsLib\Api\Models\PropertyManager>|list<\SturentsLib\Api\Models\Error>|list<\SturentsLib\Api\Models\AuthError>|list<\SturentsLib\Api\Models\GetError> */ diff --git a/src/Requests/PostEnquiry.php b/src/Requests/PostEnquiry.php new file mode 100644 index 0000000..2abe431 --- /dev/null +++ b/src/Requests/PostEnquiry.php @@ -0,0 +1,52 @@ +body = json_encode($enquiry, JSON_THROW_ON_ERROR); + } + + + public function setVersion($version) + { + $this->version = $version; + } + + + /** + * @return \SturentsLib\Api\Models\EnquirySaved|\SturentsLib\Api\Models\SendDataError|\SturentsLib\Api\Models\AuthError|\SturentsLib\Api\Models\Error|list<\SturentsLib\Api\Models\EnquirySaved>|list<\SturentsLib\Api\Models\SendDataError>|list<\SturentsLib\Api\Models\AuthError>|list<\SturentsLib\Api\Models\Error> + */ + public function sendWith(SwaggerClient $client) + { + return $client->make($this, [ + '200' => \SturentsLib\Api\Models\EnquirySaved::class, + '400' => \SturentsLib\Api\Models\SendDataError::class, + '401' => \SturentsLib\Api\Models\AuthError::class, + '403' => \SturentsLib\Api\Models\AuthError::class, + '404' => \SturentsLib\Api\Models\Error::class, + 'default' => \SturentsLib\Api\Models\Error::class + ]); + } +} diff --git a/swagger/api-channel.yml b/swagger/api-channel.yml index ce1c898..8a9f78d 100644 --- a/swagger/api-channel.yml +++ b/swagger/api-channel.yml @@ -65,7 +65,7 @@ paths: - in: query name: version type: string - required: true + required: false description: | Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' tags: @@ -111,7 +111,7 @@ paths: - in: query name: version type: string - required: true + required: false description: | Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' tags: @@ -182,6 +182,53 @@ paths: $ref: '#/definitions/GetError' default: $ref: '#/definitions/Error' + /enquiry: + post: + summary: Submit a tenant enquiry + description: | + Channel-facing endpoint for submitting a tenant enquiry against a specific + property/contract term. Auth follows the same channel HMAC pattern as + other v3 API endpoints (timestamp + SHA256 HMAC of body+timestamp using + the channel's public key). + + The landlord must have explicitly enabled your channel to send them + enquiries before this endpoint will accept requests for their properties. + Check the "can_send_enquiries" field returned by GET /summary for each + property manager to see whether this has been enabled - if it is false, + requests to this endpoint for that landlord will be rejected with a 403. + security: + - Channel: [] + PropertyManager: [] + Timestamp: [] + Auth: [] + parameters: + - in: query + name: version + type: string + required: false + description: | + Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' + - in: body + name: Enquiry + schema: + $ref: '#/definitions/EnquiryCreation' + tags: + - Property listings + responses: + '200': + description: Indicates the created enquiry ID + schema: + $ref: '#/definitions/EnquirySaved' + '400': + $ref: '#/definitions/SendDataError' + '401': + $ref: '#/definitions/AuthError' + '403': + $ref: '#/definitions/AuthError' + '404': + $ref: '#/definitions/Error' + default: + $ref: '#/definitions/Error' definitions: GetError: description: | @@ -200,6 +247,17 @@ definitions: error: type: string description: Message indicating the rate limit has been exceeded and when to try again + SendDataError: + description: | + There were problems with the input data in the request body. + These will be described in the "messages" field of the response + type: object + properties: + messages: + type: array + description: Keyed by field name (collapsed using . characters) + items: + type: string AuthError: description: | The key supplied did not match the property manager or channel @@ -791,6 +849,11 @@ definitions: type: string description: | ID for the organisation this account belongs to on the StuRents website + can_send_enquiries: + type: boolean + description: | + True if the landlord has given the channel permission to send + enquiries for their listings (e.g. via POST /enquiry) Error: type: object properties: @@ -984,3 +1047,51 @@ definitions: type: string description: | Date and time that the room summary was last updated + EnquiryCreation: + type: object + required: + - property_id + - contract_id + - first_name + - last_name + - email + - phone + - tenant_type + - enquiry_method + - enquiry_type + properties: + property_id: + type: integer + description: Plain (non-hashed) house id + contract_id: + type: string + description: Hashed availability id + first_name: + type: string + last_name: + type: string + email: + type: string + format: email + phone: + type: string + tenant_type: + type: string + enum: [student, professional, guardian] + enquiry_method: + type: string + enum: [phone, message] + enquiry_type: + type: string + enum: [enquire, book, viewing] + message: + type: string + description: | + Optional free-text message; used as the enquiry subject if provided, + otherwise a label derived from enquiry_type is used + EnquirySaved: + type: object + properties: + enquiry_id: + type: string + description: Hashed id of the created enquiry diff --git a/swagger/api-display.yml b/swagger/api-display.yml index 80f7626..33cf0bf 100644 --- a/swagger/api-display.yml +++ b/swagger/api-display.yml @@ -62,7 +62,7 @@ paths: - in: query name: version type: string - required: true + required: false description: | Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' tags: diff --git a/swagger/api-upload.yml b/swagger/api-upload.yml index e8ffad5..f0a8eb3 100644 --- a/swagger/api-upload.yml +++ b/swagger/api-upload.yml @@ -84,7 +84,7 @@ paths: - in: query name: version type: string - required: true + required: false description: | Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' tags: diff --git a/swagger/api.yml b/swagger/api.yml index 1075cba..e768146 100644 --- a/swagger/api.yml +++ b/swagger/api.yml @@ -98,7 +98,7 @@ paths: - in: query name: version type: string - required: true + required: false description: | Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' tags: @@ -135,7 +135,7 @@ paths: - in: query name: version type: string - required: true + required: false description: | Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' responses: @@ -697,6 +697,54 @@ paths: $ref: '#/definitions/GetError' default: $ref: '#/definitions/Error' + /enquiry: + post: + summary: Submit a tenant enquiry + description: | + Channel-facing endpoint for submitting a tenant enquiry against a specific + property/contract term. Auth follows the same channel HMAC pattern as + other v3 API endpoints (timestamp + SHA256 HMAC of body+timestamp using + the channel's public key). + + The landlord must have explicitly enabled your channel to send them + enquiries before this endpoint will accept requests for their properties. + Check the "can_send_enquiries" field returned by GET /summary for each + property manager to see whether this has been enabled - if it is false, + requests to this endpoint for that landlord will be rejected with a 403. + security: + - Channel: [] + PropertyManager: [] + Timestamp: [] + Auth: [] + parameters: + - in: query + name: version + type: string + required: false + description: | + Should be set to "3" (defaults to "1.3" if not set and the 1.3 version is deprecated)' + - in: body + name: Enquiry + schema: + $ref: '#/definitions/EnquiryCreation' + tags: + - Changing data on StuRents + - Enquiries + responses: + '200': + description: Indicates the created enquiry ID + schema: + $ref: '#/definitions/EnquirySaved' + '400': + $ref: '#/definitions/SendDataError' + '401': + $ref: '#/definitions/AuthError' + '403': + $ref: '#/definitions/AuthError' + '404': + $ref: '#/definitions/Error' + default: + $ref: '#/definitions/Error' definitions: GetError: description: | @@ -1518,6 +1566,11 @@ definitions: type: string description: | ID for the organisation this account belongs to on the StuRents website + can_send_enquiries: + type: boolean + description: | + True if the landlord has given the channel permission to send + enquiries for their listings (e.g. via POST /enquiry) BankAccount: properties: descriptor: @@ -1550,6 +1603,54 @@ definitions: media_id: type: string description: Unique reference to the Media item on StuRents + EnquiryCreation: + type: object + required: + - property_id + - contract_id + - first_name + - last_name + - email + - phone + - tenant_type + - enquiry_method + - enquiry_type + properties: + property_id: + type: integer + description: Plain (non-hashed) house id + contract_id: + type: string + description: Hashed availability id + first_name: + type: string + last_name: + type: string + email: + type: string + format: email + phone: + type: string + tenant_type: + type: string + enum: [student, professional, guardian] + enquiry_method: + type: string + enum: [phone, message] + enquiry_type: + type: string + enum: [enquire, book, viewing] + message: + type: string + description: | + Optional free-text message; used as the enquiry subject if provided, + otherwise a label derived from enquiry_type is used + EnquirySaved: + type: object + properties: + enquiry_id: + type: string + description: Hashed id of the created enquiry Error: type: object properties: