Forbidden error 403 in Unification Engine API while sending message - php

I am using #unificationengine API to send message on facebook.
Details I have given while registering my APP on facebook:
site url : http://localhost:3000
Email adress and other required details
In unificationengine API I have used all the curls mentioned in their documentation step by step as follows:
1. Created user using API key and Secret
2. Added connection
3. test connection
4. Refresh connection
5. Send message
All 4 gave 200 success code but send message gives 403 fobidden error.
The curl I am using for this is as below:
$post_msg = json_encode(
array(
'message' =>
array(
'receivers' =>
array(
array(
'name' => 'Me',
'address' => 'https://graph.facebook.com/v2.5/me/feed',
'Connector' => 'facebook'
),
),
'sender' =>
array('address' => ''),
'subject' => 'Hello',
'parts' =>
array(
array(
'id' => '1',
'contentType' => 'text/plain',
'data' => 'Hi welcome to UE',
'size' => 100,
'type' => 'body',
'sort' => 0
),
),
),
)
);
$ch = curl_init('https://apiv2.unificationengine.com/v2/message/send');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_USERPWD,'3f43c37b-a066-4cc4-a3be-33faf72d6a21:2722fc72d-5d347-4a3a-a82b-0c1ss51aafb4');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_msg);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// execute!
$response = curl_exec($ch);
// close the connection, release resources used
curl_close($ch);
// do anything you want with your response
var_dump($response);
return ['label' =>$response];
I am trying to figure this. But no success.
Again I like to mention that I am using this on localhost, could that be the reason for forbidden error? If so then facebook graph api from which we get access token should also give such error.
Earlier I have posted this question, here also I didn't find right solution. I added Curl options that is mentioned in comment of my question there but it didn't changed the things.
Any help would be highly appreciated.
Error Message:
{\"Status\":{\"facebook\":{\"status\":403,\"info\":\"Forbidden:
\"}},\"URIs\":[]}
UPDATE
Below is the json I get when I run me/permissions in facebook graph API explorer:
{
"data": [
{
"permission": "user_birthday",
"status": "granted"
},
{
"permission": "user_about_me",
"status": "granted"
},
{
"permission": "user_status",
"status": "granted"
},
{
"permission": "user_posts",
"status": "granted"
},
{
"permission": "email",
"status": "granted"
},
{
"permission": "manage_pages",
"status": "granted"
},
{
"permission": "publish_actions",
"status": "granted"
},
{
"permission": "public_profile",
"status": "granted"
}
]
}

I have resolved this problem:
public function facebookSharing($access_token) {
$app = new UEApp(env('UNIFICATION_APP_KEY'), env('UNIFICATION_APP_SECRATE'));
$user = new UEUser('unification_userkey', 'unification_usersecret');
$connection = $user->add_connection('FACEBOOK', "facebook", $access_token);
$options = array(
"receivers" => array(
array(
"name"=> "Me"
)
),
"message"=>array(
"subject"=>'testing',
"body"=> 'description',
"image"=> 'use any image url',
"link"=>array(
"uri"=> 'any web site url',
"description"=> "",
"title"=>"Title"
)
)
);
$uris = $connection->send_message($options);
}
Please use your keys like
facebook accesstoken
UNIFICATION_APP_KEY (its your unification keys)
UNIFICATION_APP_SECRATE (its your unification keys)
If this will not work then please let me know.

Can you please confirm if the "Connector" name that you have given is correct?
While I tried your sample code that you provided, I could sent the message to facebook via UE.
Can you please provide the exact error message that is returned while you execute the command?

Related

Import Document via CustomTranslator API in PHP

I'm trying to import a TMX file via the Microsoft Custom Translator API in PHP. Unfortunately, I keep running into the following error:
"DocumentDetails must follow type IEnumerable[ImportDocumentRequestDetails]."
I've managed to make other (though only GET) requests to the API successfully, so it's specifically this request I'm having trouble figuring out.
So far, I've tried various permutations of the request, mostly by trial and error. I've tried replicating the request by uploading the same file in the portal, which succeeds without problems, but I've not been able to replicate this in PHP (7.3).
I've also tried to reverse-engineer the C# API samples on GitHub. Unfortunately, my C# knowledge isn't that sharp and I'm sure there are nuances I'm missing. I have noticed the sample uses a 'Language' string, whereas the portal seems to use a 'LanguageCode', as well as other inconsistencies which haven't made solving this much easier.
A stripped-down version of my code, with only the relevant parts (one can assume a valid access token and local filepath to a valid .tmx) is the following:
Class CustomTranslator {
private $curl;
private $aAccessToken; // valid, working token
// Set up connection and login with initial user
public function __construct() {
$this->curl = curl_init();
$aOptions = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 60
);
curl_setopt_array($this->curl, $aOptions);
}
function ImportParallelDocument($strFilePath) {
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' => [
'DocumentName' => basename($strFilePath),
'DocumentType' => 'training',
'IsParallel' => true,
'FileDetails' => [
'Name' => $strFilePath,
'Language' => 'Dutch',
'Type' => pathinfo($strFilePath, PATHINFO_EXTENSION),
'OverwriteIfExists' => true
]
]
];
return $this->Request("v1.0/documents/import?workspaceId=".CUSTOMTRANSLATOR_WORKSPACEID, $aRequestContent, 'POST');
}
// Prototype request function
private function Request($strRequest, $aData = array(), $strMethod = 'GET') {
$strRequest = CUSTOMTRANSLATOR_API_URL.$strRequest;
// Reset between requests
curl_setopt($this->curl, CURLOPT_POST, false);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer '.$this->aAccessToken['access_token']]);
if(isset($aData['authorization'])) $aData['authorization'] = $this->aAccessToken['access_token'];
if ($strMethod == 'GET') {
$strRequest .= "?".http_build_query($aData);
}
else {
curl_setopt($this->curl, CURLOPT_POST, true);
curl_setopt($this->curl, CURLOPT_HTTPHEADER, ['Authorization: Bearer '.$this->aAccessToken['access_token'],
'X-HTTP-Method-Override: '.$strMethod]);
curl_setopt($this->curl, CURLOPT_POSTFIELDS, $aData);
}
curl_setopt($this->curl, CURLOPT_URL, $strRequest);
$strResponse = curl_exec($this->curl);
// Return the JSON array if it can be decoded, otherwise the actual curl response
return json_decode($strResponse, true)?:$strResponse;
}
}
As stated, when I try to upload a file using the above code, the exact error I'm receiving is {"message":"DocumentDetails must follow type IEnumerable[ImportDocumentRequestDetails].","display":false}, unfortunately without further specification of what's missing or incorrect. I'm hoping to achieve a successful file import of a TMX file which does successfully import via the portal itself, which I understand implements the same API.
I expect I'm simply missing something, or doing something not quite right, so any help would be appreciated!
With help from a colleague, figured out a will-do-for-now workaround, by simply providing the equivalent JSON of the call as it's used in the portal:
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' =>
'[{ "DocumentName": "",
"DocumentType": "training",
"FileDetails": [{
"Name": "'.basename($strFilePath).'",
"LanguageCode": "en",
"OverwriteIfExists": true }]
}]'
];
It's not the best solution, but for the purposes of a preview API, it'll work for now (until it inevitably ends up in production, sigh).
Examining the JSON a little closer led me to discover the nested array structure (presumably for multi-file uploads), which wasn't inherently obvious to me at first. However, the following array structure is sufficient for requests to be processed:
$aDocumentDetails = [[ // Note the nested array here, for index numbering
'DocumentName' => '',
'DocumentType' => ucfirst($strType),
'FileDetails' => [[ // As well as here
'Name' => basename($strFilePath),
'LanguageCode' => $strLanguageCode,
'OverwriteIfExists' => $bOverwrite
]]
]];
$aRequestContent = [
'Files' => new CURLFile($strFilePath, mime_content_type($strFilePath), basename($strFilePath)),
'DocumentDetails' => json_encode($aDocumentDetails)
];
In short, the API expects DocumentDetails (and FileDetails) in indexed sub-arrays:
[0 => [ 'DocumentName' => ...,
'FileDetails' => [0 => ['Name' => ...]
];
Understanding this tidbit helped me tremendously.

Assign Related Product In Magento 2 API

I am using magento 2 api for assigning product link like related or crosssell
using api /V1/products/{sku}/links
Here is My Sample Code
<?php
error_reporting(E_ALL);
define('mag_apiurl',"http://www.mywebsite.com/rest/V1/");
define('tn_webshopKey',"myshowpkey");
$sku1 = "sku1";
$sku2 = "sku2";
$productData = array(
"items" => array(
"sku" => $sku1,
"linkType" => 'related',
"linkedProductSku" => $sku2,
"linkedProductType" => "simple",
"position" => 0
)
);
$headers = array("Content-Type:application/json","Authorization: Bearer ".tn_webshopKey);
$requestUrl= mag_apiurl.'products/'.$sku1.'/links';
$ch = curl_init($requestUrl);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($productData));
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo $returnProductDetails = curl_exec($ch);
?>
But Every time i run the script its
response
{"message":"%fieldName is required filed.","parameters":{"fieldName":"linkType"}}
But the link type 'related' is already defined in my data (productData)
Does anyone knows the solution or related link which helps :)
Could you try setting "linkType" to 1 instead of "related"
$linkTypes = ['related' => 1, 'upsell' => 4, 'crosssell' => 5, 'associated' => 3];
Sorry Its my fault i'am reading the swagger api documentation for enterprise version of magento-2.2.* but i am working on magento-2.1.*
Actual Code Should be
$productData = array(
"items" => array(
array(
"sku" => $sku1,
"link_type" => 'related',
"linked_product_sku" => $sku2,
"linked_product_type" => "simple",
"position" => 0
)
)
);
/*
THE JOSN FORMAT START
{
"items": [
{
"sku": "string",
"link_type": "string",
"linked_product_sku": "string",
"linked_product_type": "string",
"position": 0,
"extension_attributes": {
"qty": 0
}
}
]
}
***************END************/
There are some differences ive noticed between those documentation that each document have different model schema declaration like some has snake_case and on other hand some has camelCase so do not begin confused between the documentation of swagger and select appropriate version of document for each store

Perl - LWP API Post

I'm trying to post a new item to a listing website using LWP. The listing website provides an example of how to post the data but using PHP, I’ve therefore tried to reproduce the solution but in Perl.
This is the PHP example.
$postData = array('type' => 'fixedPrice',
'item' => array(
'id_country' => 0,
'id_category' => 80,
'fixed_price' => '1.00',
'currency' => 'EUR',
'title' => 'My title',
'personal_reference' => 'My personal ref',
));
//RESOURCE CALL WITH POST METHOD
$url = 'http://correct.server.address/item?token=MyPersonalToken';
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_POST, true);
curl_setopt ($ch, CURLOPT_POSTFIELDS, http_build_query($postData) );
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
$xml_response = curl_exec($ch);
My Perl solution:
#!/usr/bin/perl
### Module requests ###
use strict;
use warnings;
use LWP::UserAgent;
use HTTP::Request::Common;
use XML::LibXML;
use Data::Dumper;
### Make Request to get the session Token ###
my $url = "http://correct.server.address/seller";
my $api = "APIKEY";
my $userAgent = LWP::UserAgent->new();
my $request = HTTP::Request->new(POST => $url . "?apikey=" . $api);
my $response = $userAgent->request($request);
### Display error if request to server fails ###
unless ($response->is_success) {
print "Content-type: text/html\n\n";
print "Error: " . $response->status_line;
exit;
}
### Assign response xml to $xml_token ###
my $xml_token = $response->content;
### Parse XML through XML::LibXML module ###
my $parser = XML::LibXML->new();
my $tree = $parser->parse_string($xml_token);
my $root = $tree->getDocumentElement;
my $token = $root->getElementsByTagName('token');
### Make Request to add Item - PROBLEM STARTS HERE ###
my $postURL = "http://correct.server.address/item" . "?token=" . $token;
my %item_data = (type => "fixedPrice",
item => {
id_country => "0",
id_category => "728",
fixed_price => "1.00",
currency => "GBP",
title => "Test item",
personal_reference => "12345"
}
);
my $userAgentReq2 = LWP::UserAgent->new();
my $requestReq2 = HTTP::Request->new(POST => $postURL);
$requestReq2->header(content_type => 'multipart/form-data');
$requestReq2->content(\%item_data);
my $responseReq2 = $userAgentReq2->request($requestReq2);
### Display error if request to server fails ###
unless ($responseReq2->is_success) {
print "Content-type: text/html\n\n";
print "<p>Error Message: " . $responseReq2->status_line;
print "</p><p>Output of test data sent: \n";
print Dumper(\%item_data);
print "</p><p>Dumped Response: \n";
print Dumper($responseReq2);
print "</p><p>\n";
print "Token: $token\n";
print "</p><p>\n";
print "Response: " . $responseReq2->as_string;
print "</p>\n";
exit;
}
### Assign response xml to $xml_responseReq2 ###
my $xml_responseReq2 = $responseReq2->content;
### Display Token ###
print "Content-type: text/html\n\n";
print "<p>Response: $xml_responseReq2</p>\n";
print Dumper($responseReq2);
exit;
My first post request to retrieve the session token works correctly and I receive the token. However my second post request trying to add the item fails.
This is the dumped response:
$VAR1 = bless( {
'_content' => 'Not a SCALAR reference at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 203.
',
'_rc' => 500,
'_headers' => bless( {
'client-warning' => 'Internal response',
'client-date' => 'Fri, 21 Mar 2014 12:13:34 GMT',
'content-type' => 'text/plain',
'::std_case' => {
'client-warning' => 'Client-Warning',
'client-date' => 'Client-Date'
}
}, 'HTTP::Headers' ),
'_msg' => 'Not a SCALAR reference',
'_request' => bless( {
'_content' => {
'item' => {
'currency' => 'GBP',
'id_category' => '728',
'id_country' => '0',
'personal_reference' => '12345',
'title' => 'Test item',
'fixed_price' => '1.00'
},
'type' => 'fixedPrice'
},
'_uri' => bless( do{\(my $o = 'http://correct.server.address/item?token=986aee823d54a7c2d50651c1b272c455')}, 'URI::http' ),
'_headers' => bless( {
'user-agent' => 'libwww-perl/6.05',
'content-type' => 'multipart/form-data'
}, 'HTTP::Headers' ),
'_method' => 'POST'
}, 'HTTP::Request' )
}, 'HTTP::Response' );
Please can someone help me as to where I’m going wrong, many thanks in advance!
The following appears to achieve what you want.
my %item_data = (type => "fixedPrice",
'item[id_country]' => "0",
'item[id_category]' => "728",
'item[fixed_price]' => "1.00",
'item[currency]' => "GBP",
'item[title]' => "Test item",
'item[personal_reference]' => "12345"
);
my $userAgentReq2 = LWP::UserAgent->new();
my $responseReq2 = $userAgentReq2->post($postURL,[%item_data]);
PHP allows you to create POST variables that get automatically deserialized into nested structures; for example, you can have form fields called item[0] and item[1] and so forth and those will appear in your server-side PHP script as an array of values. But HTTP does not have any concept of arrays; post data are simple key and value pairs.
The sample client-side PHP code is trying to build a nested array structure which PHP's curl interface will automatically translate into HTTP field names. It's been a million years since I've done any PHP, but I think the field names would end up being item[0][id_country], item[0][id_category], and so on. This is how PHP "cheats" HTTP to put complex structure into POSTs.
Perl's LWP library does not support building field names out of nested structures this way. That's why you're getting this error:
Not a SCALAR reference at /usr/lib/perl5/site_perl/5.8.8/LWP/Protocol/http.pm line 203.
'
In your POST arguments, the item key is pointing to a hash reference, but LWP expects to only see a plain scalar or scalar reference there.
So you'll need to change your LWP POST parameters to something like the following. (If this is not exactly right, you can use a HTTP sniffer on the PHP code to figure out what the actual field names are that it generates.)
my %item_data = (type => "fixedPrice",
'item[0][id_country]' => "0",
'item[0][id_category]' => "728",
'item[0][fixed_price]' => "1.00",
'item[0][currency]' => "GBP",
'item[0][title]' => "Test item",
'item[0][personal_reference]' => "12345"
);

Simple php function to send an email with Mandrill

What is the easiest way to send an email via Mailchimp's Mandrill service (using the API).
Here's the send method: https://mandrillapp.com/api/docs/messages.html#method=send
Here's the API wrapper: https://bitbucket.org/mailchimp/mandrill-api-php/src/fe07e22a703314a51f1ab0804018ed32286a9504/src?at=master
But I can't figure out how to make an PHP function that will send and email via Mandrill.
Can anyone help?
We also have an official API wrapper for PHP, which is available on Bitbucket or via Packagist, which wraps the Mandrill API for you.
If your Mandrill API key is stored as an environment variable, here's a simple example of sending using a template, with some merge variables and metadata:
<?php
require 'Mandrill.php';
$mandrill = new Mandrill();
// If are not using environment variables to specific your API key, use:
// $mandrill = new Mandrill("YOUR_API_KEY")
$message = array(
'subject' => 'Test message',
'from_email' => 'you#yourdomain.example',
'html' => '<p>this is a test message with Mandrill\'s PHP wrapper!.</p>',
'to' => array(array('email' => 'recipient1#domain.example', 'name' => 'Recipient 1')),
'merge_vars' => array(array(
'rcpt' => 'recipient1#domain.example',
'vars' =>
array(
array(
'name' => 'FIRSTNAME',
'content' => 'Recipient 1 first name'),
array(
'name' => 'LASTNAME',
'content' => 'Last name')
))));
$template_name = 'Stationary';
$template_content = array(
array(
'name' => 'main',
'content' => 'Hi *|FIRSTNAME|* *|LASTNAME|*, thanks for signing up.'),
array(
'name' => 'footer',
'content' => 'Copyright 2012.')
);
print_r($mandrill->messages->sendTemplate($template_name, $template_content, $message));
?>
Mandrill take HTTP POST requests for all of their API methods, and they take your input as a JSON string. Here's a basic example of sending an email. It uses cURL to do the HTTP request:
$uri = 'https://mandrillapp.com/api/1.0/messages/send.json';
$postString = '{
"key": "YOUR KEY HERE",
"message": {
"html": "this is the emails html content",
"text": "this is the emails text content",
"subject": "this is the subject",
"from_email": "someone#example.com",
"from_name": "John",
"to": [
{
"email": "blah#example.com",
"name": "Bob"
}
],
"headers": {
},
"track_opens": true,
"track_clicks": true,
"auto_text": true,
"url_strip_qs": true,
"preserve_recipients": true,
"merge": true,
"global_merge_vars": [
],
"merge_vars": [
],
"tags": [
],
"google_analytics_domains": [
],
"google_analytics_campaign": "...",
"metadata": [
],
"recipient_metadata": [
],
"attachments": [
]
},
"async": false
}';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $uri);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
$result = curl_exec($ch);
echo $result;
// Simply Send Email Via Mandrill...
require_once 'Mandrill.php';
$mandrill = new Mandrill($apikey);
$message = new stdClass();
$message->html = "html message";
$message->text = "text body";
$message->subject = "email subject";
$message->from_email = "address#example.com";
$message->from_name = "From Name";
$message->to = array(array("email" => "recipient#example.com"));
$message->track_opens = true;
$response = $mandrill->messages->send($message);
This is the most basic piece of code I could give you, I just craft it seconds ago for a client and it's working smooth.
require_once 'path/to/your/mandrill/file/Mandrill.php';
try {
$mandrill = new Mandrill('your-API-key');
$message = array(
'html' => $htmlMessage,
'subject' => $subject,
'from_email' => $fromEmail,
'from_name' => $fromName,
'to' => array(
array(
'email' => $toEmail,
'name' => $toName,
'type' => 'to'
)
)
);
$result = $mandrill->messages->send($message);
print_r($result);
} catch(Mandrill_Error $e) {
echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();
throw $e;
}
Also check their send method for more options like headers, meta-data, attachments etc. https://mandrillapp.com/api/docs/messages.php.html#method-send
Include the PHP API: https://bitbucket.org/mailchimp/mandrill-api-php
Code: https://mandrillapp.com/api/docs/messages.php.html#method-send
You can use ZF's autoloading for including the wrapper class or Composer: https://mandrillapp.com/api/docs/index.php.html

Publish post with picture and link on event's wall

Is there a way to publish a post with a picture and a link on an event's wall? Currently I can publish only statuses (messages). On the user's wall there is no such issue. I've tried the new Graph API as well as the old REST API ('stream.publish' method) with no success (using PHP SDK).
Thank you in advance.
The code I use for Graph API:
$attachment = array(
'message' => 'my message',
'name' => 'This is my demo Facebook application!',
'caption' => "Caption of the Post",
'description' => 'this is a description',
'picture' => 'link to an image',
'actions' => array(array('name' => 'See recipe',
'link' => 'http://www.google.com'))
);
$facebook->api('/'.$eventID.'/feed/','post',$attachment);
The code for REST API:
$url = "https://api.facebook.com/method/stream.publish?".$access_token;
$attachment = array('name' => 'This is my demo Facebook application!',
'href' => 'http://news.google.com',
'description' => 'It is fun!',
'media'=> array(array(
'type'=> 'image',
'src' => 'link to an image',
'href' => 'http://www.google.gr'))
);
$params = array();
$params['message'] = "my message";
$params['attachment'] = json_encode($attachment);
$params['target_id'] = $eventID;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$result = curl_exec($ch);
curl_close($ch);
As I mentioned above, both is working if I publish on user's wall. On event's wall a status message is published showing only the content of 'message' parameter.
I have the same problem. The event wall post only appears as text message, it is not possible to post a "link" or a "post" to the event wall via any API.
The same post appears differently on the users wall or on the event wall.
The behavior can be tested here:
http://developers.facebook.com/docs/reference/rest/stream.publish/
Just fill out the form and post the same message with a valid attachment once to the users wall and once with a target id (for an event) and see the difference.
This behavior is not documented and also google gives not much help.
Any workarounds or explanations would be appreciated.
Here is a demo attachment (working on the users wall):
{
"name": "Test name",
"href": "http://www.google.com",
"description": "Test Desc",
"media": [
{
"type": "image",
"src": "(any image)",
"href": "http://www.google.com"
}
]
}

Categories