We would like to create/update a lead in Intercom via Javascript, we can do it through the PHP, but I have no idea how to do the same with Javascript, because we are using Unbounce landing page and when visitor fill out the form we would like send it to Intercom and create the lead for us.
We can use Zapier integration inside the Unbounce but passing the UTM parameters is not allowed, so we want to use the Intercom API/Javascript directly.
Below is the PHP script that we are using to create lead through WP Intercom API
Anyone how to do the same using Javascript? so I can put inside the Unbounce page script manager.
$client = new IntercomClient('xxxxxxxxxxxxx=', null);
try {
// First check if this already exists
$leads = $client->leads->getLeads(['email' => $post['email']]);
foreach ($leads->contacts as $lead) {
$id = $lead->id;
}
if(!$id) {
$id = '';
}
$client->leads->update([
"id" => $id,
"email" => $post['email'],
"name" => preg_replace("/[^a-zA-Z0-9\s]/", "", ucwords($post['first_name'])),
"last_request_at" => time(),
"last_seen_ip" => $_SERVER['REMOTE_ADDR'],
"utm_campaign" => $post['Utm_campaign],
"utm_content" => $post['Utm_content'],
"utm_medium" => $post['Utm_medium'],
"utm_source" => $post['Utm_source'],
"utm_term" => $post['Utm_term'],
'Form Message' => preg_replace("/[^a-zA-Z0-9\s]/", "", $post['description'])]
]);
} catch(ClientException $e) {
$response = $e->getResponse();
$statusCode = $response->getStatusCode();
if ($statusCode == '404') {
// Handle 404 error
return;
} else {
throw $e;
}
}
Related
I want to change several background colors via "post type".
I don't know how to query the "post type".
I know, that my code is 100% wrong. I searched the web for a solution. But couldn't find any, that would work.
(function() {
var elements, posttype;
function init() {
elements = document.querySelectorAll('.color');
posttype = get_post_type();
}
function checkColor() {
if (posttype === 'veranstaltung') {
element.classList.add('pink');
element.classList.remove('color');
} else if (posttype === 'ausstellung') {
element.classList.add('green');
element.classList.remove('color')
} else if (posttype === 'digitale-events') {
element.classList.add('red');
element.classList.remove('color')
}
}
init();
checkColor();
})();
One method is javascript if you create a function inside function.php which you have to call all the custom post type and return all the post with ajax in javascript which I do not suggest, the second method is to create a custom page and display all the custom post type with php, and then you have to do a condition to check which post type is the post and then add a custom class to each custom post type.*Note: This get all posts of a custom type use:
$posts = get_posts([
'post_type' => 'custom',
'post_status' => 'publish',
'posts_per_page' => -1,
'order' => 'ASC'
]);
I am using Yii2 Pjax widget which is unable to throw error from controller due to which I am unable to log error for users when there is any error coming from the controller.
PJAX code
<?php Pjax::begin([
'id' => 'createBucketPjax',
'timeout' => 4000,
'formSelector' => '#createBucketForm',
'enablePushState' => false,
'clientOptions' => [
'skipOuterContainers' => true,
'error' => new JsExpression("function(event) {
alert('Anything');
}"),
]
]); ?>
CONTROLLER code:
if(!$fieldModel->save()){
$transaction->rollBack();
//Here I want to send error
$error = $fieldModel->getErrorsString();
return [
'success' => false,'error' => $error
];
}else{
return $this->renderAjax('create', [
'model' => $model
]);
}
I have tried below clientOptions but not working
'error' => new JsExpression("function(event) {
alert('Please work');
}"),
Also used javascript but no help :-
$(document).on('pjax:error', function(event) {
console.log(event);
})
Is there any way from which I can send 404 from controller in yii2 ? That can actually resolve my problem
From the Yii2 Pjax docs.
In responding to the AJAX request, Pjax will send the updated body content (based on the AJAX request) to the client which will replace the old content with the new one. The browser's URL will then be updated using pushState. The whole process requires no reloading of the layout or resources (js, css)
You must deal with full form content and not with json.
So you code must look like following (always return the form html back):
if(!$model->save()){
$transaction->rollBack();
}
return $this->renderAjax('create', [
'model' => $model
]);
I'm trying to setup a simple Stripe payment on my Wordpress plugin. I've followed their documentation and they recommend using fetch API to get the server side paymentIntent response from a .php file like below.
fetch("/create-payment-intent.php", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(orderData)
})
However, my plugin is built using OOP and the code is within a class so I'm guessing if i point to this file directly it wouldn't work as it first needs to be first initialised. Is there a way of using fetch to call a method in a php class? Or is it better to use AJAX to handle the above?
Update
This is the code Stripe have in their documentation which i need to run in create-payment-intent.php. However, in my case i want to run the methods in a class so using fetch() woudln't work.
# vendor using composer
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));
header('Content-Type: application/json');
# retrieve json from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$intent = null;
try {
if (isset($json_obj->payment_method_id)) {
# Create the PaymentIntent
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $json_obj->payment_method_id,
'amount' => 1099,
'currency' => 'usd',
'confirmation_method' => 'manual',
'confirm' => true,
]);
}
if (isset($json_obj->payment_intent_id)) {
$intent = \Stripe\PaymentIntent::retrieve(
$json_obj->payment_intent_id
);
$intent->confirm();
}
generateResponse($intent);
} catch (\Stripe\Exception\ApiErrorException $e) {
# Display error on client
echo json_encode([
'error' => $e->getMessage()
]);
}
function generateResponse($intent) {
# Note that if your API version is before 2019-02-11, 'requires_action'
# appears as 'requires_source_action'.
if ($intent->status == 'requires_action' &&
$intent->next_action->type == 'use_stripe_sdk') {
# Tell the client to handle the action
echo json_encode([
'requires_action' => true,
'payment_intent_client_secret' => $intent->client_secret
]);
} else if ($intent->status == 'succeeded') {
# The payment didn’t need any additional actions and completed!
# Handle post-payment fulfillment
echo json_encode([
"success" => true
]);
} else {
# Invalid status
http_response_code(500);
echo json_encode(['error' => 'Invalid PaymentIntent status']);
}
}
Stripe are soon to roll out their use of Strong Customer Authentication for payments with their platform. There's a fairly substantial section in their documentation about it.
https://stripe.com/docs/payments/payment-intents/quickstart#manual-confirmation-flow
The process has the following flow:
The vanilla PHP implementation is like so:
<?php
# vendor using composer
require_once('vendor/autoload.php');
\Stripe\Stripe::setApiKey(getenv('STRIPE_SECRET_KEY'));
header('Content-Type: application/json');
# retrieve json from POST body
$json_str = file_get_contents('php://input');
$json_obj = json_decode($json_str);
$intent = null;
try {
if (isset($json_obj->payment_method_id)) {
# Create the PaymentIntent
$intent = \Stripe\PaymentIntent::create([
'payment_method' => $json_obj->payment_method_id,
'amount' => 1099,
'currency' => 'gbp',
'confirmation_method' => 'manual',
'confirm' => true,
]);
}
if (isset($json_obj->payment_intent_id)) {
$intent = \Stripe\PaymentIntent::retrieve(
$json_obj->payment_intent_id
);
$intent->confirm();
}
generatePaymentResponse($intent);
} catch (\Stripe\Error\Base $e) {
# Display error on client
echo json_encode([
'error' => $e->getMessage()
]);
}
function generatePaymentResponse($intent) {
# Note that if your API version is before 2019-02-11, 'requires_action'
# appears as 'requires_source_action'.
if ($intent->status == 'requires_action' &&
$intent->next_action->type == 'use_stripe_sdk') {
# Tell the client to handle the action
echo json_encode([
'requires_action' => true,
'payment_intent_client_secret' => $intent->client_secret
]);
} else if ($intent->status == 'succeeded') {
# The payment didn’t need any additional actions and completed!
# Handle post-payment fulfillment
echo json_encode([
"success" => true
]);
} else {
# Invalid status
http_response_code(500);
echo json_encode(['error' => 'Invalid PaymentIntent status']);
}
}
?>
The necessary JavaScript for its use with Stripe Elements looks like this:
var cardholderName = document.getElementById('cardholder-name');
var cardButton = document.getElementById('card-button');
cardButton.addEventListener('click', function(ev) {
stripe.createPaymentMethod('card', cardElement, {
billing_details: {name: cardholderName.value}
}).then(function(result) {
if (result.error) {
// Show error in payment form
} else {
// Otherwise send paymentMethod.id to your server (see Step 2)
fetch('/ajax/confirm_payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_method_id: result.paymentMethod.id })
}).then(function(result) {
// Handle server response (see Step 3)
result.json().then(function(json) {
handleServerResponse(json);
})
});
}
});
});
function handleServerResponse(response) {
if (response.error) {
// Show error from server on payment form
} else if (response.requires_action) {
// Use Stripe.js to handle required card action
stripe.handleCardAction(
response.payment_intent_client_secret
).then(function(result) {
if (result.error) {
// Show error in payment form
} else {
// The card action has been handled
// The PaymentIntent can be confirmed again on the server
fetch('/ajax/confirm_payment', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ payment_intent_id: result.paymentIntent.id })
}).then(function(confirmResult) {
return confirmResult.json();
}).then(handleServerResponse);
}
});
} else {
// Show success message
}
}
In my own project I'm using Laravel which is entirely based on the MVC architecture and it fairly nice to you when it comes to most things.
I have tried to refactor a little but I have a question.
Why would you use this line $json_str = file_get_contents('php://input'); over just trying to grab the posted variables from the Request object used in Laravel?
I also read the following article from the PHP Manual:
https://www.php.net/manual/en/wrappers.php.php
To be perfectly honest I've been away from procedural PHP so this has confused me to no end.
Why use 'php://input' over the POST superglobal - Stripe SCA example
The body is encoded as JSON. You can tell because the next line explicitly decodes it.
PHP doesn't understand application/json requests. It will only populate $_POST if the data is encoding using the application/x-www-form-urlencoded or multipart/form-data formats.
Why would you use this line $json_str = file_get_contents('php://input'); over just trying to grab the posted variables from the Request object used in Laravel?
If you were using Laravel, there's no reason to do that.
Since there is no sign of anything Laravel in the example you gave, it is presumably not written with the intention of introducing a dependency on Laravel.
I'm currently using Semantic-UI in a project. I use the search module to get the results from input. Here's my JavaScript code:
$('.ui.search')
.search({
apiSettings: {
action: 'search',
url: 'process.php?q={query}',
onSuccess(response, element, xhr){
console.log(response);
}
},
fields: {
results: 'songs', // array of results (standard)
title: 'title', // result title
url: 'videoID'
},
showNoResults: true,
onResults(response) {
console.log(response);
}
})
;
I get the JSON response from process.php. Here it is:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
header("Content-Type: application/json; charset=UTF-8");
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
// This code will execute if the user entered a search query in the form
// and submitted the form. Otherwise, the page displays the form above.
$videos = array();
// $videos["action"]["url"] = "youtube.com";
if (isset($_GET['q'])) {
/*
* Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$DEVELOPER_KEY = 'MY_API_KEY';
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
try {
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'q' => $_GET['q'],
'maxResults' => 2
));
// Add each result to the appropriate list, and then display the lists of
// matching videos, channels, and playlists.
foreach ($searchResponse['items'] as $searchResult) {
switch ($searchResult['id']['kind']) {
case 'youtube#video':
$videos["songs"][] = array('title' => $searchResult['snippet']['title'], 'videoID' => $searchResult["id"]["videoId"]);
break;
}
}
} catch (Google_Service_Exception $e) {
die($e->getMessage());
}
}
echo json_encode($videos);
The problem is that once I start typing in the search input, nothing shows up, even though my JSON structure is valid. I have assigned the Semantic UI properties correctly. I'm following the standard JSON response that Semantic UI has suggested. Here's my JSON response
{
"songs":[
{
"title":"Wiz Khalifa - See You Again ft. Charlie Puth [Official Video] Furious 7 Soundtrack",
"videoID":"RgKAFK5djSk"
},
{
"title":"Wiz Khalifa - See You Again ft. Charlie Puth (MattyBRaps ft Carissa Adee Cover)",
"videoID":"Rpm8ZJuGEu4"
}
]
}
I've tried everything. It doesn't work. I would really appreciate your help