I have a weird issue with microsoft graph api v1.
I am trying to setup a subscription, so that I get webhook notification after a new outlook email arrives.
$body = [
"changeType" => "created,updated",
"notificationUrl" => route('api.outlook.push'),
"resource" => "me/messages",
"expirationDateTime" => now()->addMinutes(self::SUBSCRIPTION_EXPIRATION_MINUTES),
];
$response = null;
try {
$response = $this->service->createRequest('POST', '/subscriptions')
->attachBody(json_encode($body))
->setReturnType(Subscription::class)
->execute();
} catch (Exception $exception) {
logger()->info('outlook subscription exception', ['message' => $exception->getMessage()]);
}
This seems to be working correctly as microsoft is sending a notification to specified url with verification code, that I'm returning and the message says that subscription was created. The issue is that even though it was set up properly - I am not getting a single one webhook. Did any of you guys had this issue and manage to fix it?
Related
I have an AWS Elastic Beanstalk Worker Environment setup using SQS. The SQS is posting to a URL, which is an endpoint to a codebase that uses Laravel. From this endpoint, it takes up the message and process the payload. Some of my processes are time-consuming and is taking more than 20 minutes to complete. I am sending back a success response from the endpoint, but as it takes a lot of time to complete the process, most of the time, the messages are going to the inflight mode in SQS. I am trying to make a deleteMessage() call using PHP SDK, but I need to pass ReceiptHandle for deleting a message. As per the documentation here, SQS is not posting ReceiptHandle to my application and so I can't make a delete call. The problem with messages in inFlight mode is that it will be called again in the next time the and so the process is duplicated.
How can I delete a message once the process is completed ?
My current code is as follows :
$worker->process(
$request->header('X-Aws-Sqsd-Queue'), $job, [
'maxTries' => 0,
'delay' => 0
]
);
return $this->response([
'Processed ' . $job->getJobId()
]);
Where worker is an instance of
Illuminate\Queue\Worker;
and the response function is json encoding the data and respond with 200
You must have ReceiptHandle to delete a message in queue. In core PHP below is the function to read and delete a message in queue.
function ReadMessages($client,$queueUrl){
try {
$result = $client->receiveMessage(array(
'AttributeNames' => ['SentTimestamp'],
'MaxNumberOfMessages' => 1,
'MessageAttributeNames' => ['All'],
'QueueUrl' => $queueUrl, // REQUIRED
'WaitTimeSeconds' => 0,
));
if (count($result->get('Messages')) > 0) {
var_dump($result->get('Messages')[0]);
//to delete a message pass the receipt Handle
$result = $client->deleteMessage([
'QueueUrl' => $queueUrl, // REQUIRED
'ReceiptHandle' => $result->get('Messages')[0]['ReceiptHandle'] // REQUIRED
]);
} else {
echo "No messages in queue. \n";
}
}
catch (AwsException $e) {
// output error message if fails
return 'error';
error_log($e->getMessage());
}
}
Do some workaround so you get a ReceiptHandle to delete a message in queue.
Description
I'm getting an error when attempting to create a stripe subscription using Laravel + the API.
Before you create the subscription you must get the token by requesting it, I have successfully created this token and I'm now using the "createSubscription()" method from the API (referenced in my code), but this is where the error is occurring.
Code
public function create()
{
$user = Auth::user();
$plan = 'prod_**********';
// Do some checks
if ($user->subscribed('main')){
return [
'status' => 'failed',
'message' => 'You are already subscribed!',
];
}
// Set the stripe Key
Stripe::setApiKey(env('STRIPE_SECRET'));
// Create the stripe token
try {
$stripeToken = Token::create([
'card' => [
'number' => str_replace(' ', '', Input::get('number')),
'exp_month' => Input::get('exp_month'),
'exp_year' => Input::get('exp_year'),
'cvc' => Input::get('cvc')
]
]);
}
catch (\Stripe\Error\InvalidRequest $e)
{
return [
'status' => 'failed',
'message' => $e->getMessage(),
];
}
try{
// This is the line thats failing
$user->newSubscription('main', $plan)->create($stripeToken);
} catch (\Stripe\Error\InvalidRequest $e) {
dd($e->getMessage());
}
return [
'status' => 'success',
'message' => 'Subscription was successful!',
];
}
The Error
The error in full is:
Invalid request. Hint: check the encoding for your request parameters
and URL (http://en.wikipedia.org/wiki/percent-encoding). For
assistance, email support#stripe.com.
I've spoken to stripe support and they're saying they think the error is on my end, everything seems good on the stripe end.
I've checked the card detailed and customer details are correct (This is why the token being created).
I've searched this error but nothing seems to come up for this, there are other questions somewhat similar but no answers.
I've uninstalled / reinstalled laravel-cashier package to no success.
Whats strange is how i've managed to solve this problem. It would seem that passing the entire stripe token does not work and instead I only needed to pass the token ID.
Simply changing
$user->newSubscription('main', $plan)->create($stripeToken);
to this
$user->newSubscription('main', $plan)->create($stripeToken->id);
Solved this error
Invalid request. Hint: check the encoding for your request parameters
and URL (http://en.wikipedia.org/wiki/percent-encoding). For
assistance, email support#stripe.com.
I'm sure that nowhere in either documentation is states that this is the solution? Or maybe I overlooked this somewhere... but this has solved it for me.
Our code sends twilio sms messages by doing the following:
// send the text message to the member's mobile phone
try {
// attempt to send the message through Twilio
$tw_msg = $twilio_client->messages->create(
"+1".$recipient['address'],
array (
'From' => "+1".$org['twilio_number'],
'Body' => $txtmsg,
'StatusCallback' => CALLBACK_LINK.'/text_message_handler.php'
)
);
// else trap the error since the message could not be sent and the callback routine is not called
} catch (Exception $e) {
// process the text message error
process_text_msg_error($db, $e, $org, $msg, $recipient);
}
In the v4 library we would get the error code by doing the following:
// get the twilio error components
$twilio_error_status = $e->getStatus();
$twilio_error_code = $e->getCode();
$twilio_error_msg = $e->getMessage();
This is not giving us what we expected using the V5 library. How do we get the error status and code using the V5 lib?
Twilio developer evangelist here.
It looks to me like you need to update one of the methods you call on the exception to get the status code. The exception is now a RestException and has the method getStatusCode(). You should update to:
// get the twilio error components
$twilio_error_status = $e->getStatusCode();
$twilio_error_code = $e->getCode();
$twilio_error_msg = $e->getMessage();
Let me know if that helps at all.
I have an application both in Android and iOS platforms. Both of them are registered with Amazon SNS. This is successfully done, because if I have the device tokens, then I can login to my applications dashboard in Amazon, and can send SNS from their console.
I want it make it automated. I mean have my own PHP admin site (and API) for the applications. I want add another page to the admin site, that can request the amazon SNS to send single payload with device identifier, registration keys and message body provided with the request.
First question - Is it possible? I have seen Urban Airship allows it, so it is usual that amazon also does?
Second question - What is the process? Since I am working on this for one of my client and all the docs are not accessible to me. My client is unable to explain it to amazon.
When I have registered my apps to amazon, shouldn't they provide me some keys and secrets that I can use to call their service over http?
Yes, it is possible.
Download the Amazon Web Service (AWS) PHP SDK from here and follow their instructions to use this in you web server API. Get the Platform Application ARN's for both iOS and android, access key id and the secret key from Amazon console. And then try the code below and follow the commented out instructions:
<?php
require '<path to this file>/aws.phar';
use Aws\Sns\SnsClient;
if(isset($_POST['submit']))
{
$push_message = $_POST['push_message'];
if(!empty($push_message))
{
// Create a new Amazon SNS client
$sns = SnsClient::factory(array(
'key' => '<access key>',
'secret' => '<app secret>',
'region' => '<region code>'
));
// region code samples: us-east-1, ap-northeast-1, sa-east-1, ap-southeast-1, ap-southeast-2, us-west-2, us-gov-west-1, us-west-1, cn-north-1, eu-west-1
$iOS_AppArn = "<iOS app's Application ARN>";
$android_AppArn = "<android app's Application ARN>";
// Get the application's endpoints
$iOS_model = $sns->listEndpointsByPlatformApplication(array('PlatformApplicationArn' => $iOS_AppArn));
$android_model = $sns->listEndpointsByPlatformApplication(array('PlatformApplicationArn' => $android_AppArn));
// Display all of the endpoints for the iOS application
foreach ($iOS_model['Endpoints'] as $endpoint)
{
$endpointArn = $endpoint['EndpointArn'];
echo $endpointArn;
}
// Display all of the endpoints for the android application
foreach ($android_model['Endpoints'] as $endpoint)
{
$endpointArn = $endpoint['EndpointArn'];
echo $endpointArn;
}
// iOS: Send a message to each endpoint
foreach ($iOS_model['Endpoints'] as $endpoint)
{
$endpointArn = $endpoint['EndpointArn'];
try
{
$sns->publish(array('Message' => $push_message,
'TargetArn' => $endpointArn));
echo "<strong>Success:</strong> ".$endpointArn."<br/>";
}
catch (Exception $e)
{
echo "<strong>Failed:</strong> ".$endpointArn."<br/><strong>Error:</strong> ".$e->getMessage()."<br/>";
}
}
// android: Send a message to each endpoint
foreach ($android_model['Endpoints'] as $endpoint)
{
$endpointArn = $endpoint['EndpointArn'];
try
{
$sns->publish(array('Message' => $push_message,
'TargetArn' => $endpointArn));
echo "<strong>Success:</strong> ".$endpointArn."<br/>";
}
catch (Exception $e)
{
echo "<strong>Failed:</strong> ".$endpointArn."<br/><strong>Error:</strong> ".$e->getMessage()."<br/>";
}
}
}
}
?>
The code is tested and it works, feel free to change as your need.
If you want to send alert sound and badge number with custom payload replace this code block // iOS: Send a message to each endpoint
foreach ($iOS_model['Endpoints'] as $endpoint)
with this code block
foreach ($iOS_model['Endpoints'] as $endpoint)
{
$endpointArn = $endpoint['EndpointArn'];
try
{
$sns->publish(array(
'TargetArn' => $endpointArn,
'MessageStructure' => 'json',
'Message' => json_encode(array(
'default' => $title,
'APNS_SANDBOX' => json_encode(array(
'aps' => array(
'alert' => $title,
'sound' => 'default',
'badge' => 1
),
// Your custom payload if needed
'whatever' => 'here',
'andwhatever' => 'here'
))
))
));
echo "1";//Success push
}
catch (Exception $e)
{
echo "2";//Failed push
}
}
i believe the simplest way to send push notification to single device or user is by this code
$snsClient = Aws\Sns\SnsClient::factory(array(
'credentials' => array(
'key' => AMAZON_KEY,
'secret' => AMAZON_SECRET,
),
'region' => AMAZON_REIGON
));
//you should have variable that have user end single point .
$result = $snsClient->publish(array(
'Message' => "push text message",
'TargetArn' => $user_end_point
));
I was wondering if someone could help me with a problem I have been having some trouble researching related to Laravel and inbound email processing through Mandrill.
Basically I wish to be able to receive emails through Mandrill and store them within my Laravel database. Now i'm not sure if i'm reading through the documentation with the wrong kind of eyes, but Mandrill says it deals with inbound email as well as outbound, however i'm starting to think that Mandrill deals with inbound email details as opposed to the actual inbound email, such as if the message is sent etc.
I've created a new Mandrill account, created an API key, created an inbound domain and corresponding subdomain of my site (e.g. inboundmail.myproject.co.uk), set the MX record and the MX record is showing as valid. From there i have set up a route (e.g. queries#inboundmail.myproject.co.uk), and a corresponding webhook (myproject.co.uk/inboundmail.php) and within this webhook tried a variety of the examples given in the API (https://mandrillapp.com/api/docs/inbound.php.html), such as adding a new route, checking the route and attempting to add a new domain. All of them worked and produced the correct results, so my authentication with Mandrill is not in question, but my real question is is there a specific webhook for dealing with accepting incoming mail messages?
I cant help but feel like an absolute idiot asking this question as i'm sure the answer is either staring me in the face or just not possible through Mandrill.
Thanks in advance.
Thanks to duellsy and debest for their help, in the end i found a script and expanded on it to add the mail to my own database and style / display it accordingly. Hope this helps someone who may have the same trouble:
<?php
require 'mandrill.php';
define('API_KEY', 'Your API Key');
define('TO_EMAIL', 'user#example.com');
define('TO_NAME', 'Foo Bar');
if(!isset($_POST['mandrill_events'])) {
echo 'A mandrill error occurred: Invalid mandrill_events';
exit;
}
$mail = array_pop(json_decode($_POST['mandrill_events']));
$attachments = array();
foreach ($mail->msg->attachments as $attachment) {
$attachments[] = array(
'type' => $attachment->type,
'name' => $attachment->name,
'content' => $attachment->content,
);
}
$headers = array();
// Support only Reply-to header
if(isset($mail->msg->headers->{'Reply-to'})) {
$headers[] = array('Reply-to' => $mail->msg->headers->{'Reply-to'});
}
try {
$mandrill = new Mandrill(API_KEY);
$message = array(
'html' => $mail->msg->html,
'text' => $mail->msg->text,
'subject' => $mail->msg->subject,
'from_email' => $mail->msg->from_email,
'from_name' => $mail->msg->from_name,
'to' => array(
array(
'email' => TO_EMAIL,
'name' => TO_NAME,
)
),
'attachments' => $attachments,
'headers' => $headers,
);
$async = false;
$result = $mandrill->messages->send($message, $async);
print_r($result);
} catch(Mandrill_Error $e) {
// Mandrill errors are thrown as exceptions
echo 'A mandrill error occurred: ' . get_class($e) . ' - ' . $e->getMessage();
// A mandrill error occurred: Mandrill_PaymentRequired - This feature is only available for accounts with a positive balance.
throw $e;
}
?>
Like using webhooks from other mail parsing services, you'll need to make use of
file_get_contents("php://input")
This will give you the raw data from the webhook, which you can then json_decode and work with the results.