Comments (7)
OK, go for it.
from receiver.
Interesting! Out of the box I'd say you could hack it by returning something generic for the event
value and then all of your events for the data
value, but your handler would have to just process the lot of them... which seems counter-productive.
It could be an option to allow for a collection of events instead of a single event (as a new feature). Is that something that would interest you?
from receiver.
The issue with Xero, is that the events are not all the same. So in one webhook request, events could be a mixture of contacts.update
, contacts.create
, invoice.update
or invoice.create
.
I have got around it so far by overriding the provider handle
method which essentially ignores the getEvent
and getData
methods of the provider.
Here is my custom XeroProvider
:
<?php
namespace App\Http\Receivers;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Receiver\Providers\AbstractProvider;
class XeroProvider extends AbstractProvider
{
public function verify(Request $request): bool
{
if (! is_string($this->secret) || empty($this->secret)) {
throw new \Exception('Xero webhook secret not found');
}
// Compute the payload with HMACSHA256 with base64 encoding
$computedSignatureKey = base64_encode(
hash_hmac('sha256', (string) $request->getContent(), $this->secret, true)
);
return hash_equals($computedSignatureKey, $request->header('X_XERO_SIGNATURE') ?? '');
}
public function getEvent(Request $request): string
{
$events = $request->collect('events');
/**
* For Xeros' 'Intent to receive' validation.
* @see https://developer.xero.com/documentation/guides/webhooks/configuring-your-server/#intent-to-receive
*/
if ($events->isEmpty()) {
return '';
}
/** @var array $firstEvent */
$firstEvent = $request->collect('events')->first();
// We never use this but we have to return a string
return Str::lower("{$firstEvent['eventCategory']}.{$firstEvent['eventType']}");
}
protected function handle(): void
{
/** @var Collection<string, Collection> $events */
$events = $this->request
->collect('events')
->mapToGroups(fn ($item, $key) => [Str::lower("{$item['eventCategory']}.{$item['eventType']}") => $item]);
foreach ($events as $eventName => $data) {
$class = $this->getClass($eventName);
if (class_exists($class)) {
$instance = new $class($eventName, $data->toArray());
$this->dispatched = dispatch($instance);
}
}
}
}
I have not looked at how to implement this in the package but think there would need to be a step that transforms the data into collections of events and then each collection is handled as an event.
The other way I thought of handling this was to transform the data in the webhook controller and then loop through the event collections and call the provider multiple times.
Would be interested in your thoughts and think it would be a great addition if this package could handle this situation.
from receiver.
Currently I'm building a receiver for Soketi websockets that can send webhooks to my server. Soketi also passes multiple events as an array to the webhook, like:
{
"time_ms": 1697717045179,
"events": [
{
"name": "channel_occupied",
"channel": "admin",
"data": {}
},
{
"name": "member_added",
"channel": "admin",
"data": {}
}
]
}
Maybe a solution is to allow the getEvent()
-method also return an array instead of a string only, and if that's the case handle the hook as multiple event?
I've managed with this code now, but this colors a bit outside the lines compared to your implementation.
protected function handle(): static
{
collect($this->request->collect('events'))->each(function ($event) {
$data = $event['data'];
$class = $this->getClass($event = $event['name']);
if (class_exists($class)) {
$class::dispatch($event, $data);
$this->dispatched = true;
}
});
return $this;
}
from receiver.
Thanks @ashleyhood and @jeffreyvanhees
I finally took a stab at a change here. Check it out in this PR: #26
If you'd be willing to pull that branch into your project and try it out I'd be grateful!
from receiver.
Thanks @ashleyhood and @jeffreyvanhees
I finally took a stab at a change here. Check it out in this PR: #26
If you'd be willing to pull that branch into your project and try it out I'd be grateful!
That's fast @hotmeteor! Thanks for that. I'll give it a try and let you know! :)
from receiver.
Actually, give me one second... I missed something. I'll update you when it's ready.
from receiver.
Related Issues (11)
- Stripe Driver Not Recognized? HOT 3
- IDE: Undefined method 'receive' HOT 2
- Authenticate postmark webhooks by IP HOT 2
- Extract providers out from core package to be installable independently
- Unclear documentation HOT 1
- Support for fallback handlers when event-specific class doesn't exist HOT 3
- Tests are failing HOT 1
- Breaking change in v0.1.15, classes not constructed the same? HOT 2
- Best way to validate $driver string in a request? HOT 1
- Clarify configuration requirements, provide examples
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from receiver.