ZAPIER_SENDWEBHOOK

Class ZAPIER_SENDWEBHOOK

Contents

  • Methods

  • Source Source

    File: src/integrations/zapier/actions/zapier-sendwebhook.php

    class ZAPIER_SENDWEBHOOK {
    
    	/**
    	 * Integration code
    	 * @var string
    	 */
    	public static $integration = 'ZAPIER';
    	public static $number_of_keys;
    	private $action_code;
    	private $action_meta;
    
    	/**
    	 * Set up Automator action constructor.
    	 */
    	public function __construct() {
    		$this->action_code    = 'SENDWEBHOOK';
    		$this->action_meta    = 'WEBHOOK';
    		self::$number_of_keys = 7;
    
    		$this->define_action();
    		add_filter( 'automator_api_setup', [ $this, 'legacy_meta_data' ] );
    	}
    
    	/**
    	 * Define and register the action by pushing it into the Automator object
    	 */
    	public function define_action() {
    
    
    
    		$action = array(
    			'author'             => Automator()->get_author_name( $this->action_code ),
    			'support_link'       => Automator()->get_author_support_link( $this->action_code, 'knowledge-base/working-with-zapier-actions' ),
    			'integration'        => self::$integration,
    			'code'               => $this->action_code,
    			/* translators: Action - Zapier */
    			'sentence'           => sprintf( esc_attr__( 'Send data to Zapier {{webhook:%1$s}}', 'uncanny-automator' ), $this->action_meta ),
    			/* translators: Action - Zapier */
    			'select_option_name' => esc_attr__( 'Send data to Zapier {{webhook}}', 'uncanny-automator' ),
    			'priority'           => 10,
    			'accepted_args'      => 1,
    			'execution_function' => array( $this, 'send_webhook' ),
    			'options_group'      => [
    				$this->action_meta => [
    					// Webhook URL
    					[
    						'input_type' => 'url',
    
    						'option_code' => 'WEBHOOK_URL',
    						'label'       => esc_attr__( 'URL', 'uncanny-automator' ),
    
    						'supports_tokens' => true,
    						'required'        => true,
    					],
    					// Action event
    					[
    						'input_type' => 'select',
    
    						'option_code' => 'ACTION_EVENT',
    						/* translators: HTTP request method */
    						'label'       => esc_attr__( 'Request method', 'uncanny-automator' ),
    						'description' => esc_attr__( 'Select the HTTP request method supported by the webhook destination. If you are unsure, leave this value unchanged unless you are experiencing issues.', 'uncanny-automator' ),
    
    						'required' => true,
    
    						'default_value' => 'POST',
    						'options'       => [
    							'GET'  => 'GET',
    							'PUT'  => 'PUT',
    							'POST' => 'POST',
    						],
    					],
    					// Header
    					[
    						'input_type' => 'repeater',
    
    						'option_code' => 'WEBHOOK_HEADERS',
    
    						'label'       => esc_attr__( 'Headers', 'uncanny-automator' ),
    						'description' => esc_attr__( 'Add any HTTP request headers required by the webhook destination.', 'uncanny-automator' ),
    
    						'required'          => false,
    						'fields'            => [
    							[
    								'input_type' => 'text',
    
    								'option_code' => 'NAME',
    								'label'       => esc_attr__( 'Name', 'uncanny-automator' ),
    
    								'supports_tokens' => true,
    								'required'        => true,
    							],
    							[
    								'input_type' => 'text',
    
    								'option_code' => 'VALUE',
    								'label'       => esc_attr__( 'Value', 'uncanny-automator' ),
    
    								'supports_tokens' => true,
    								'required'        => true,
    							],
    						],
    
    						/* translators: Non-personal infinitive verb */
    						'add_row_button'    => esc_attr__( 'Add header', 'uncanny-automator' ),
    						/* translators: Non-personal infinitive verb */
    						'remove_row_button' => esc_attr__( 'Remove header', 'uncanny-automator' ),
    					],
    					// Fields
    					[
    						'input_type' => 'repeater',
    
    						'option_code' => 'WEBHOOK_FIELDS',
    
    						'label' => esc_attr__( 'Fields', 'uncanny-automator' ),
    
    						'required'          => true,
    						'fields'            => [
    							[
    								'input_type' => 'text',
    
    								'option_code' => 'KEY',
    								'label'       => esc_attr__( 'Key', 'uncanny-automator' ),
    
    								'supports_tokens' => true,
    								'required'        => true,
    							],
    							[
    								'input_type' => 'text',
    
    								'option_code' => 'VALUE',
    								'label'       => esc_attr__( 'Value', 'uncanny-automator' ),
    
    								'supports_tokens' => true,
    								'required'        => true,
    							],
    						],
    
    						/* translators: Non-personal infinitive verb */
    						'add_row_button'    => esc_attr__( 'Add pair', 'uncanny-automator' ),
    						/* translators: Non-personal infinitive verb */
    						'remove_row_button' => esc_attr__( 'Remove pair', 'uncanny-automator' ),
    					],
    				],
    			],
    			'buttons'            => [
    				[
    					'show_in'     => $this->action_meta,
    					'text'        => esc_attr__( 'Documentation', 'uncanny-automator' ),
    					'css_classes' => 'uap-btn uap-btn--transparent',
    					'on_click'    => 'function(){ window.open( "https://automatorplugin.com", "_blank" ); }',
    				],
    				[
    					'show_in'     => $this->action_meta,
    					/* translators: Non-personal infinitive verb */
    					'text'        => esc_attr__( 'Send test', 'uncanny-automator' ),
    					'css_classes' => 'uap-btn uap-btn--red',
    					'on_click'    => $this->send_test_js(),
    					'modules'     => [ 'markdown' ],
    				],
    			],
    		);
    
    		Automator()->register->action( $action );
    	}
    
    	/**
    	 * Anonymous JS function invoked as callback when clicking
    	 * the custom button "Send test". The JS function requires
    	 * the JS module "markdown". Make sure it's included in
    	 * the "modules" array
    	 *
    	 * @return string The JS code
    	 */
    
    	public function send_test_js() {
    		// Start output
    		ob_start();
    
    		// It's optional to add the <script> tags
    		// This must have only one anonymous function
    		?>
    
    		<script>
    
    			// Do when the user clicks on send test
    			function ($button, data, modules) {
    				// Add loading animation to the button
    				$button.addClass('uap-btn--loading uap-btn--disabled');
    
    				// Get the data we're going to send to the AJAX request
    				let dataToBeSent = {
    					action: 'sendtest_zp_webhook',
    					nonce: UncannyAutomator.nonce,
    
    					integration_id: data.item.integrationCode,
    					item_id: data.item.id,
    					values: data.values
    				}
    
    				// Do AJAX
    				jQuery.ajax({
    					method: 'POST',
    					dataType: 'json',
    					url: ajaxurl,
    					data: dataToBeSent,
    
    					success: function (response) {
    						// Remove loading animation from the button
    						$button.removeClass('uap-btn--loading uap-btn--disabled');
    
    						// Create notice
    						// But first check if the message is defined
    						if (typeof response.message !== 'undefined') {
    							// Get notice type
    							let noticeType = typeof response.type !== 'undefined' ? response.type : 'gray';
    
    							// Parse message using markdown
    							let markdown = new modules.Markdown(response.message);
    
    							// Create notice
    							let $notice = jQuery('<div/>', {
    								'class': 'item-options__notice item-options__notice--' + noticeType
    							});
    
    							// Get markdown HTML
    							let $message = markdown.getHTML();
    
    							// Add message to the notice container
    							$notice.html($message);
    
    							// Get the notices container
    							let $noticesContainer = jQuery('.item[data-id="' + data.item.id + '"] .item-options__notices');
    
    							// Add notice
    							$noticesContainer.html($notice);
    						}
    					},
    
    					statusCode: {
    						403: function () {
    							location.reload();
    						}
    					},
    
    					fail: function (response) {
    					}
    				});
    			}
    
    		</script>
    
    		<?php
    
    		// Get output
    		$output = ob_get_clean();
    
    		// Return output
    		return $output;
    	}
    
    
    	/**
    	 * Support legacy data structure.
    	 */
    	public function legacy_meta_data( $recipe_data ) {
    		if ( ! empty( $recipe_data['recipes_object'] ) ) {
    			foreach ( $recipe_data['recipes_object'] as $recipe_key => $recipe ) {
    				if ( 'trash' !== $recipe['post_status'] ) {
    					if ( ! empty( $recipe['actions'] ) ) {
    						foreach ( $recipe['actions'] as $action_key => $action ) {
    							if ( $this->action_code === $action['meta']['code'] ) {
    								if ( isset( $action['meta']['WEBHOOKURL'] ) && ! isset( $action['meta']['WEBHOOK_URL'] ) ) {
    									$recipe_data['recipes_object'][ $recipe_key ]['actions'][ $action_key ]['meta']['WEBHOOK_URL'] = $action['meta']['WEBHOOKURL'];
    								}
    								if ( isset( $action['meta']['KEY1'] ) && ! isset( $action['meta']['WEBHOOK_FIELDS'] ) ) {
    									$webhook_field = array();
    									for ( $i = 1; $i <= self::$number_of_keys; $i ++ ) {
    										if ( isset( $action['meta'][ 'KEY' . $i ] ) && ! empty( $action['meta'][ 'KEY' . $i ] ) ) {
    											$webhook_field[] = [
    												'KEY'   => $action['meta'][ 'KEY' . $i ],
    												'VALUE' => $action['meta'][ 'VALUE' . $i ],
    											];
    										}
    									}
    									$recipe_data['recipes_object'][ $recipe_key ]['actions'][ $action_key ]['meta']['WEBHOOK_FIELDS'] = json_encode( $webhook_field );
    								}
    								if ( ! isset( $action['meta']['ACTION_EVENT'] ) ) {
    									$recipe_data['recipes_object'][ $recipe_key ]['actions'][ $action_key ]['meta']['ACTION_EVENT'] = 'POST';
    								}
    							}
    						}
    					}
    				}
    			}
    		}
    
    		return $recipe_data;
    	}
    
    	/**
    	 * Validation function when the action is hit
    	 *
    	 * @param $user_id
    	 * @param $action_data
    	 * @param $recipe_id
    	 * @param $args
    	 */
    	public function send_webhook( $user_id, $action_data, $recipe_id, $args ) {
    
    
    		$key_values   = array();
    		$headers      = array();
    		$request_type = 'POST';
    		if ( isset( $action_data['meta']['WEBHOOKURL'] ) ) {
    			$webhook_url = Automator()->parse->text( $action_data['meta']['WEBHOOKURL'], $recipe_id, $user_id, $args );
    
    			for ( $i = 1; $i <= ZAPIER_SENDWEBHOOK::$number_of_keys; $i ++ ) {
    				$key                = Automator()->parse->text( $action_data['meta'][ 'KEY' . $i ], $recipe_id, $user_id, $args );
    				$value              = Automator()->parse->text( $action_data['meta'][ 'VALUE' . $i ], $recipe_id, $user_id, $args );
    				$key_values[ $key ] = $value;
    			}
    
    		} elseif ( isset( $action_data['meta']['WEBHOOK_URL'] ) ) {
    			$webhook_url = Automator()->parse->text( $action_data['meta']['WEBHOOK_URL'], $recipe_id, $user_id, $args );
    
    			$fields = json_decode( $action_data['meta']['WEBHOOK_FIELDS'], true );
    
    			for ( $i = 0; $i < count( $fields ); $i ++ ) {
    				$key                = Automator()->parse->text( $fields[ $i ]['KEY'], $recipe_id, $user_id, $args );
    				$value              = Automator()->parse->text( $fields[ $i ]['VALUE'], $recipe_id, $user_id, $args );
    				$key_values[ $key ] = $value;
    			}
    
    			if ( isset( $action_data['meta']['WEBHOOK_HEADERS'] ) ) {
    				$header_meta = json_decode( $action_data['meta']['WEBHOOK_HEADERS'], true );
    				if ( ! empty( $header_meta ) ) {
    					for ( $i = 0; $i <= count( $header_meta ); $i ++ ) {
    						$key = isset( $header_meta[ $i ]['NAME'] ) ? Automator()->parse->text( $header_meta[ $i ]['NAME'], $recipe_id, $user_id, $args ) : null;
    						// remove colon if user added in NAME
    						$key   = str_replace( ':', '', $key );
    						$value = isset( $header_meta[ $i ]['VALUE'] ) ? Automator()->parse->text( $header_meta[ $i ]['VALUE'], $recipe_id, $user_id, $args ) : null;
    						if ( ! is_null( $key ) && ! is_null( $value ) ) {
    							$headers[ $key ] = $value;
    						}
    					}
    				}
    			}
    
    			if ( 'POST' === (string) $action_data['meta']['ACTION_EVENT'] || 'CUSTOM' === (string) $action_data['meta']['ACTION_EVENT'] ) {
    				$request_type = 'POST';
    			} elseif ( 'GET' === (string) $action_data['meta']['ACTION_EVENT'] ) {
    				$request_type = 'GET';
    			} elseif ( 'PUT' === (string) $action_data['meta']['ACTION_EVENT'] ) {
    				$request_type = 'PUT';
    			}
    		}
    
    		if ( $key_values && ! is_null( $webhook_url ) ) {
    			$args = [
    				'method'   => $request_type,
    				'body'     => $key_values,
    				'timeout'  => '30',
    				'blocking' => false,
    			];
    
    			if ( ! empty( $headers ) ) {
    				$args['headers'] = $headers;
    			}
    
    			$response = wp_remote_request( $webhook_url, $args );
    
    			if ( $response instanceof WP_Error ) {
    				/* translators: 1. Webhook URL */
    				$error_message = sprintf( esc_attr__( 'An error was found in the webhook (%1$s) response.', 'uncanny-automator' ), $webhook_url );
    				Automator()->complete_action( $user_id, $action_data, $recipe_id, $error_message );
    
    				return;
    			}
    
    			Automator()->complete_action( $user_id, $action_data, $recipe_id );
    		}
    
    	}
    }
    

    Methods Methods

    • __construct — Set up Automator action constructor.
    • define_action — Define and register the action by pushing it into the Automator object
    • legacy_meta_data — Support legacy data structure.
    • send_test_js — Anonymous JS function invoked as callback when clicking the custom button "Send test". The JS function requires the JS module "markdown". Make sure it's included in the "modules" array
    • send_webhook — Validation function when the action is hit