diff --git a/proxy/config.dist.php b/proxy/config.dist.php index 6ad7b2a..59510bb 100644 --- a/proxy/config.dist.php +++ b/proxy/config.dist.php @@ -111,7 +111,7 @@ $rest_allowed_actions = array( ), ), ), - '123.45.678.1' => array( + '123.45.67.8' => array( 'Contact' => array( 'getsingle' => array( 'first_name' => 'string', @@ -124,3 +124,35 @@ $rest_allowed_actions = array( ), ), ); + + +/**************************************************************** + ** WebHook2API CONFIGURATIONS ** + ****************************************************************/ +# remove if you don't want this feature or rename to $webhook2api to activate +$_webhook2api = [ + "configurations" => [ + "default" => [ + "name" => "Example", + "ip_sources" => ['172.10.0.1/24', '192.168.1.1/24'], // only accept source ID from the given range + "data_sources" => ["POST/json", "REQUEST"], // POST/json json-decodes the post data, REQUEST is PHP's $_REQUEST array + "sentinel" => [["type", "equal:customer.created"]], // only execute if all of these are true + "entity" => "Contact", + "action" => "create", + "api_key" => "api key", + "parameter_mapping" => [ + [["data", "object", "metadata", "salutation"], ["prefix_id"]], + [["data", "object", "metadata", "first_name"], ["first_name"]], + [["data", "object", "metadata", "last_name"], ["last_name"]], + [["data", "object", "metadata", "street"], ["street_address"]], + [["data", "object", "metadata", "zip_code"], ["postal_code"]], + [["data", "object", "metadata", "city"], ["city"]], + [["data", "object", "metadata", "country"], ["country_id"]], + [["data", "object", "metadata", "telephone"], ["phone"]], + [["data", "object", "metadata", "birthday"], ["birth_date"]], + [["data", "object", "metadata", "email"], ["email"]] + ], + "parameter_sanitation" => [], + ] + ] +]; \ No newline at end of file diff --git a/proxy/webhook2api.php b/proxy/webhook2api.php new file mode 100644 index 0000000..92c993b --- /dev/null +++ b/proxy/webhook2api.php @@ -0,0 +1,300 @@ + "Access denied", 403]; + } + } else { + echo "Error"; + // unknown instruction + // //error_log("Webhook2API[{$configuration['name']}]: don't understad sentinel '{$check}'. Ignored."); + } + } + } + + // compile API query + $params = []; + if (!empty($configuration['parameter_mapping']) && is_array($configuration['parameter_mapping'])) { + foreach ($configuration['parameter_mapping'] as $mapping) { + $source_path = $mapping[0]; + $target_path = $mapping[1]; + $modifiers = isset($mapping[2]) ? $mapping[2] : []; + + // get value + $value = webhook2api_getValue($data, $source_path); + + // run modifiers + foreach ($modifiers as $modifier) { + // TODO: implement + //error_log("Webhook2API.modifiers: not implemented!"); + } + + // set to target + webhook2api_setValue($params, $target_path, $value); + } + } else { + $params = $data; + } + + // sanitise data + if (!empty($configuration['parameter_sanitation']) && is_array($configuration['parameter_sanitation'])) { + // TODO: implement + //error_log("Webhook2API.sanitation: not implemented!"); + } + + // send to target REST API + if (empty($configuration['entity']) || empty($configuration['action'])) { + //error_log("Webhook2API[{$configuration['name']}]: Missing entity/action."); + return ["internal_error" => "Configuration error", 403]; + } + if (empty($configuration['api_key'])) { + //error_log("Webhook2API[{$configuration['name']}]: Missing api_key."); + return ["internal_error" => "Configuration error", 403]; + } + $params['api_key'] = $configuration['api_key']; + + // run API call + return civicrm_api3($configuration['entity'], $configuration['action'], $params); + +} + + +/** + * Get the value from a multidimensional array, + * specified by the path + * + * @param $data array multidimensional data array + * @param $path array|string path description + * @return mixed value + */ +function webhook2api_getValue($data, $path) { + if (is_string($path)) { + if (isset($data[$path])) { + return $data[$path]; + } else { + return NULL; + } + } elseif (is_array($path)) { + if (count($path) == 0) { + return NULL; + } elseif (count($path) == 1) { + return webhook2api_getValue($data, $path[0]); + } else { + $path_element = array_shift($path); + $sub_data = webhook2api_getValue($data, $path_element); + if (is_array($sub_data)) { + return webhook2api_getValue($sub_data, $path); + } else { + return NULL; + } + } + } +} + +/** + * Set the value from a multidimensional array as specified by the path + * + * @param $data array the data + * @param $target_path array destination + * @param $value mixed value + */ +function webhook2api_setValue(&$data, $target_path, $value) { + if (is_array($target_path)) { + if (count($target_path) == 0) { + civiproxy_log("Webhook2API.setValue: Empty target path!"); + return; + + } elseif (count($target_path) == 1) { + // last element -> set value + $data[$target_path[0]] = $value; + + } else { + // not last element + $element = array_shift($target_path); + if (!isset($data[$element])) { + $data[$element] = []; + } + if (is_array($data[$element])) { + webhook2api_setValue($data[$element], $target_path, $value); + } else { + civiproxy_log("Webhook2API.setValue: path node is not an array!"); + } + } + + } elseif (is_string($target_path)) { + webhook2api_setValue($data, [$target_path], $value); + + } else { + civiproxy_log("Webhook2API.setValue: path neither string nor array!"); + } +} \ No newline at end of file