Drupal 8 Guzzle Format Query String - post

Forgive me for my ignorance, this is my first attempt at Drupal 8 and I'm not a good php developer to begin with. But I've been reading and searching for hours. I'm trying to do a post using the new Guzzle that replaces the drupal_http_request(). I've done this using Curl but can't seem to get this going in the right direction here. I'm just not "getting it".
Here is a sample of the array I have that pulls data from a custom form. I also tried this with a custom variable where I built the string.
$fields = array(
"enroll_id" => $plan,
"notice_date" => $date,
"effective_date" => $date,
);
$client = \Drupal::httpClient();
$response = $client->post('myCustomURL', ['query' => $fields]);
$data = $response->getBody()->getContents();
try {
drupal_set_message($data);
} catch (RequestException $e) {
watchdog_exception('MyCustomForm', $e->getMessage());
}
This indeed returns the result of REJECTED from my API in $data below - but it doesn't append the URL to included the query => array. I've tried numerous combinations of this just putting the fully built URL in the post (that works with my API - tested) and I still receive the same result from my API. In the end what I'm trying to accomplish is
https://myCustomURL?enroll_id=value&notice_date=12/12/12&effective_date=12/12/12
Any direction or tips would be much appreciated.

Thanks for the responses guys. I was able to get it to work correctly by changing a few things in my post. First changing client -> post to a request('POST', XXX) and then changing "query" to "form_params" as "body" has been deprecated.
http://docs.guzzlephp.org/en/latest/quickstart.html#query-string-parameters
$client = \Drupal::httpClient();
$response = $client->request('POST','https://myURL.html', ['form_params' => $fields]);
$data = $response->getBody()->getContents();

Using $client->post will send a POST request. By looking at the URL that you tested directly you want a GET request.
Either use $client->get or $client->request with the GET parameter. More information and examples in the Guzzle documentation.

Related

Get Caller From value in Twilio

I've written a script which generates a wordpress post each time a call is received to log a serevice event within our call centre application which is working correctly in as much as the call is handled correctly and a wordpress post is created, but I'm not able to pass the value of the person who is calling to Wordpress. As you can see below I've tried several things.
Here is the code I'm currently using:
$response = new TwiML;
$response = new VoiceResponse();
// $caller = $fromCaller;
$caller = $call['from'];
$caller .= $call['callerid'];
$caller .= $dial['callerid'];
$content = 'Service Request received from ' . $caller;
// Register the Request in to Wordpress
// Create post object
$my_post = array(
'post_title' => 'Service Event',
'post_type' => 'mce_service',
'post_content' => $content,
'post_status' => 'private',
'post_author' => 1
);
// Insert the post into the database
wp_insert_post( $my_post );
Anyone able to point me in the right direction as clearly I'm missing something and the docs aren't helping me.
I found what I was looking for and posting an answer to my own question as it may help others.
$caller = $_REQUEST["From"];

Twilio PHP SDK - Did twilio receive my request?

We are using the Twilio PHP SDK and the Notify Client. When I make a request how do I get the status of that request. Did it return a good 2XX, an error 4XX? And to be clear, I don't mean, what is the status of the messages. I simply mean, did twilio get my API call?
When testing in Postman with the REST API I typically get a 200 or 201 response if everything went well.
$twilio = new Client($acct_sid, $token);
$Addresses = array("+12015551234");
$toBindingAttributes = array();
foreach ($Addresses as $Address) {
array_push($toBindingAttributes, '{"binding_type":"sms","address":"' . $Address . '"}');
}
$notification = $twilio->notify->services($notify_sid)
->notifications->create([
"toBinding" => $toBindingAttributes,
"body" => "Twilio Test."
]);
I've tried to return $notification and I just get [Twilio.Notify.V1.NotificationInstance]
-----Edit-----
ok I realize now that [Twilio.Notify.V1.NotificationInstance] is an object. I was able to print_r($notification) and see that there is a statusCode property.
I tried to echo that property print_r(#notification->statusCode) but I get "Unknown Property".
Is it because it's "protected"?
[statusCode:protected] => 201
Thanks
Since the result is the [Twilio.Notify.V1.NotificationInstance] object.
The problem is all the properties within the object are protected we cannot access them directly.
We were able to get to them with a bunch of strpos, substr, and regex but found a much easier way using a getter.
By doing this way
print($twilio->getHttpClient()->lastResponse->getStatusCode());
More info in the Twilio-PHP library
https://github.com/twilio/twilio-php/blob/650f42647c9b3039e03ae075785164ec97203e94/src/Twilio/Http/Response.php

Hiding YouTube API for client using server

My inexperience has left me short of understanding how to hide an API Key. Sorry, but I've been away from web development for 15 years as I specialized in relational databases, and a lot has changed.
I've read a ton of articles, but don't understand how to take advantage of them. I want to put my YouTube API key(s) on the server, but have the client able to use them w/o exposure. I don't understand how setting an API Key on my server (ISP provided) enables the client to access the YouTube channel associated with the project. Can someone explain this to me?
I am not sure what you want to do but for a project I worked on I needed to get a specific playlist from YouTube and make the contents public to the visitors of the website.
What I did is a sort of proxy. I set up a php file contains the api key, and then have the end user get the YT content through this php file.
The php file gets the content form YT using curl.
I hope it helps.
EDIT 1
The way to hide the key is to put it in a PHP file on the server.
This PHP file will the one connecting to youtube and retrieving the data you want on your client page.
This example of code, with the correct api key and correct playlist id will get a json file with the 10 first tracks of the play list.
The $resp will have the json data. To extract it, it has to be decoded for example into an associative array. Once in the array it can be easily mixed in to the html that will be rendered on the client browser.
<?php
$apiKey = "AIza...";
$results = "10";
$playList = "PL0WeB6UKDIHRyXXXXXXXXXX...";
$request = "https://www.googleapis.com/youtube/v3/playlistItems?part=id,contentDetails,snippet&maxResults=" . $results .
"&fields=items(contentDetails%2FvideoId%2Cid%2Csnippet(position%2CpublishedAt%2Cthumbnails%2Fdefault%2Ctitle))" .
"&playlistId=" . $playList .
"&key=" . $apiKey;
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_URL => $request,
CURLOPT_SSL_VERIFYPEER => false
));
$resp = curl_exec($curl);
if (curl_errno($curl)) {
$status = "CURL_ERROR";
}else{
// check the HTTP status code of the request
$resultStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($resultStatus == 200) {
$status = "OK";
//Do something with the $resp which is in JSON format.
//Like decoding it into an associative array
} else {
$status = "YT_ERROR";
}
}
curl_close($curl);
?>
<html>
<!-- your html here -->
</html>
Note: CURLOPT_SSL_VERIFYPEER is set to false. This is in development. For prod it should be true.
Also note that using the api this way, you can restrict the calls to your api key bounding them to your domain. You do that in the googla api console. (Tip for production)

Twilio how i find answer by human/ machine and also get the response using PHP

I have send the parameter from my front end code Angular like this,
var params = {"PhoneNumber": Ph};
Twilio.Device.connect(params, {"Record": true, "IfMachine": 'Continue'});
Now, how i get the response of call attends by machine or human status i need to get the response of the call?
Tamil, I've written a post explaining how we recommend you go about this using <Gather> and the example in PHP:
https://www.twilio.com/blog/2016/02/tracking-call-status-how-can-you-tell-if-a-human-answers-the-phone-2.html
<?php
# Include Twilio PHP helper library.
require "/path/to/twilio-php/Services/Twilio.php";
# Create response object.
$response = new Services_Twilio_Twiml();
$response->say("Hello, press any key to hear a top secret message.");
$gather = $response->gather(array(
'action' => "YOUR_TWIML_BIN"
));
$response->say("You did not reveal yourself to be human. Goodbye!");
print $response;
?>

How to retrieve Medium stories for a user from the API?

I'm trying to integrate Medium blogging into an app by showing some cards with posts images and links to the original Medium publication.
From Medium API docs I can see how to retrieve publications and create posts, but it doesn't mention retrieving posts. Is retrieving posts/stories for a user currently possible using the Medium's API?
The API is write-only and is not intended to retrieve posts (Medium staff told me)
You can simply use the RSS feed as such:
https://medium.com/feed/#your_profile
You can simply get the RSS feed via GET, then if you need it in JSON format just use a NPM module like rss-to-json and you're good to go.
Edit:
It is possible to make a request to the following URL and you will get the response. Unfortunately, the response is in RSS format which would require some parsing to JSON if needed.
https://medium.com/feed/#yourhandle
⚠️ The following approach is not applicable anymore as it is behind Cloudflare's DDoS protection.
If you planning to get it from the Client-side using JavaScript or jQuery or Angular, etc. then you need to build an API gateway or web service that serves your feed. In the case of PHP, RoR, or any server-side that should not be the case.
You can get it directly in JSON format as given beneath:
https://medium.com/#yourhandle/latest?format=json
In my case, I made a simple web service in the express app and host it over Heroku. React App hits the API exposed over Heroku and gets the data.
const MEDIUM_URL = "https://medium.com/#yourhandle/latest?format=json";
router.get("/posts", (req, res, next) => {
request.get(MEDIUM_URL, (err, apiRes, body) => {
if (!err && apiRes.statusCode === 200) {
let i = body.indexOf("{");
const data = body.substr(i);
res.send(data);
} else {
res.sendStatus(500).json(err);
}
});
});
Nowadays this URL:
https://medium.com/#username/latest?format=json
sits behind Cloudflare's DDoS protection service so instead of consistently being served your feed in JSON format, you will usually receive instead an HTML which is suppose to render a website to complete a reCAPTCHA and leaving you with no data from an API request.
And the following:
https://medium.com/feed/#username
has a limit of the latest 10 posts.
I'd suggest this free Cloudflare Worker that I made for this purpose. It works as a facade so you don't have to worry about neither how the posts are obtained from source, reCAPTCHAs or pagination.
Full article about it.
Live example. To fetch the following items add the query param ?next= with the value of the JSON field next which the API provides.
const MdFetch = async (name) => {
const res = await fetch(
`https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/${name}`
);
return await res.json();
};
const data = await MdFetch('#chawki726');
To get your posts as JSON objects
you can replace your user name instead of #USERNAME.
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/#USERNAME
With that REST method you would do this: GET https://api.medium.com/v1/users/{{userId}}/publications and this would return the title, image, and the item's URL.
Further details: https://github.com/Medium/medium-api-docs#32-publications .
You can also add "?format=json" to the end of any URL on Medium and get useful data back.
Use this url, this url will give json format of posts
Replace studytact with your feed name
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/studytact
I have built a basic function using AWS Lambda and AWS API Gateway if anyone is interested. A detailed explanation is found on this blog post here and the repository for the the Lambda function built with Node.js is found here on Github. Hopefully someone here finds it useful.
(Updating the JS Fiddle and the Clay function that explains it as we updated the function syntax to be cleaner)
I wrapped the Github package #mark-fasel was mentioning below into a Clay microservice that enables you to do exactly this:
Simplified Return Format: https://www.clay.run/services/nicoslepicos/medium-get-user-posts-new/code
I put together a little fiddle, since a user was asking how to use the endpoint in HTML to get the titles for their last 3 posts:
https://jsfiddle.net/h405m3ma/3/
You can call the API as:
curl -i -H "Content-Type: application/json" -X POST -d '{"username":"nicolaerusan"}' https://clay.run/services/nicoslepicos/medium-get-users-posts-simple
You can also use it easily in your node code using the clay-client npm package and just write:
Clay.run('nicoslepicos/medium-get-user-posts-new', {"profile":"profileValue"})
.then((result) => {
// Do what you want with returned result
console.log(result);
})
.catch((error) => {
console.log(error);
});
Hope that's helpful!
Check this One you will get all info about your own post........
mediumController.getBlogs = (req, res) => {
parser('https://medium.com/feed/#profileName', function (err, rss) {
if (err) {
console.log(err);
}
var stories = [];
for (var i = rss.length - 1; i >= 0; i--) {
var new_story = {};
new_story.title = rss[i].title;
new_story.description = rss[i].description;
new_story.date = rss[i].date;
new_story.link = rss[i].link;
new_story.author = rss[i].author;
new_story.comments = rss[i].comments;
stories.push(new_story);
}
console.log('stories:');
console.dir(stories);
res.json(200, {
Data: stories
})
});
}
I have created a custom REST API to retrieve the stats of a given post on Medium, all you need is to send a GET request to my custom API and you will retrieve the stats as a Json abject as follows:
Request :
curl https://endpoint/api/stats?story_url=THE_URL_OF_THE_MEDIUM_STORY
Response:
{
"claps": 78,
"comments": 1
}
The API responds within a reasonable response time (< 2 sec), you can find more about it in the following Medium article.

Resources