diff --git a/assets/images/bird.svg b/assets/images/bird.svg new file mode 100644 index 0000000..7abcd9d --- /dev/null +++ b/assets/images/bird.svg @@ -0,0 +1,3 @@ + + + diff --git a/includes/Gateways.php b/includes/Gateways.php index 91c5af0..db65e92 100644 --- a/includes/Gateways.php +++ b/includes/Gateways.php @@ -155,6 +155,7 @@ public function all() { 'vonage' => __NAMESPACE__ . '\Gateways\Vonage', 'clickatell' => __NAMESPACE__ . '\Gateways\Clickatell', 'plivo' => __NAMESPACE__ . '\Gateways\Plivo', + 'bird' => __NAMESPACE__ . '\Gateways\Bird', ]; if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { diff --git a/includes/Gateways/Bird.php b/includes/Gateways/Bird.php new file mode 100644 index 0000000..0fe98fd --- /dev/null +++ b/includes/Gateways/Bird.php @@ -0,0 +1,188 @@ +this link to get started with Bird. Follow these instructions to configure the gateway.', + 'texty' + ), + 'https://docs.bird.com/api/quickstarts/send-an-sms-message', + 'https://github.com/getdokan/texty/wiki/Bird' + ); + } + + /** + * Get the logo + * + * @return string + */ + public function logo() { + return TEXTY_URL . '/assets/images/bird.svg'; + } + + /** + * Get the settings + * + * @return array + */ + public function get_settings() { + $creds = texty()->settings()->get( 'bird' ); + + return [ + 'access_key' => [ + 'name' => __( 'Access Key', 'texty' ), + 'type' => 'text', + 'value' => isset( $creds['access_key'] ) ? $creds['access_key'] : '', + 'help' => '', + ], + 'workspace_id' => [ + 'name' => __( 'Workspace ID', 'texty' ), + 'type' => 'text', + 'value' => isset( $creds['workspace_id'] ) ? $creds['workspace_id'] : '', + 'help' => __( 'Found in your Bird dashboard workspace settings', 'texty' ), + ], + 'channel_id' => [ + 'name' => __( 'Channel ID', 'texty' ), + 'type' => 'text', + 'value' => isset( $creds['channel_id'] ) ? $creds['channel_id'] : '', + 'help' => __( 'The SMS channel ID from your Bird workspace', 'texty' ), + ], + ]; + } + + /** + * Get the API endpoint for sending messages + * + * @param string $workspace_id + * @param string $channel_id + * + * @return string + */ + private function get_endpoint( $workspace_id, $channel_id ) { + return sprintf( + '%s/workspaces/%s/channels/%s/messages', + self::API_BASE, + $workspace_id, + $channel_id + ); + } + + /** + * Send SMS + * + * @param string $to + * @param string $message + * + * @return WP_Error|true + */ + public function send( $to, $message ) { + $creds = texty()->settings()->get( 'bird' ); + $endpoint = $this->get_endpoint( $creds['workspace_id'], $creds['channel_id'] ); + + $args = [ + 'headers' => [ + 'Authorization' => 'AccessKey ' . $creds['access_key'], + 'Content-Type' => 'application/json', + ], + 'body' => wp_json_encode( [ + 'receiver' => [ + 'contacts' => [ + [ + 'identifierValue' => '+' . ltrim( $to, '+' ), + ], + ], + ], + 'body' => [ + 'type' => 'text', + 'text' => [ + 'text' => $message, + ], + ], + ] ), + ]; + + $response = wp_remote_post( $endpoint, $args ); + $response_code = wp_remote_retrieve_response_code( $response ); + $body = json_decode( wp_remote_retrieve_body( $response ) ); + + if ( 202 !== $response_code ) { + $error_message = isset( $body->errors[0]->description ) ? $body->errors[0]->description : __( 'Unknown error', 'texty' ); + $error_code = isset( $body->errors[0]->code ) ? $body->errors[0]->code : 'bird_error'; + + return new WP_Error( $error_code, $error_message, $body ); + } + + return true; + } + + /** + * Validate a REST API request + * + * @param WP_REST_Request $request + * + * @return WP_Error|array + */ + public function validate( $request ) { + $creds = $request->get_param( 'bird' ); + + $endpoint = sprintf( + '%s/workspaces/%s', + self::API_BASE, + $creds['workspace_id'] + ); + + $args = [ + 'headers' => [ + 'Authorization' => 'AccessKey ' . $creds['access_key'], + 'Content-Type' => 'application/json', + ], + ]; + + $response = wp_remote_get( $endpoint, $args ); + $response_code = wp_remote_retrieve_response_code( $response ); + $body = json_decode( wp_remote_retrieve_body( $response ) ); + + if ( 200 !== $response_code ) { + $error_message = isset( $body->errors[0]->description ) ? $body->errors[0]->description : __( 'Invalid credentials', 'texty' ); + $error_code = isset( $body->errors[0]->code ) ? $body->errors[0]->code : 'bird_error'; + + return new WP_Error( $error_code, $error_message, $body ); + } + + return [ + 'access_key' => $creds['access_key'], + 'workspace_id' => $creds['workspace_id'], + 'channel_id' => $creds['channel_id'], + ]; + } +}