make a decision based on response of webhook in mautic - python

I was wondering if there is any way to make decisions based on webhook responses in Mautic. To elaborate, I post a request via webhook and the corresponding API responds with an error (e.g. 411). I want to create a campaign that has a block depending on the response of that webhook if it receives 200 decision 1 is made and if it receives 411, another decision is made.
how can I implement this?

I don't think such feature exists by default, but there can be alternative ways to do this.
sending an api call from the system in question(like on success make a call do set some tag or field) same goes for error. However this is practical as long as you have control over that system.
Create a custom campaign Decision node which will listen to the responses of the webhook(in this case you will need to send the webhook using campaign only), Again the block here is that you will need to know how to code a custom campaign decision or will need to look for a developer who can do it.

Related

Sipgate how to handle incoming VOIP calls Python

I Have been wondering , how can we handle incoming calls with sipgate https://api.sipgate.com/v2 API using python. I am able to initiate calls but I've no idea how to handle incoming calls , i can't even find anything on api doc.
After doing some research I came to know that , we can handle incoming calls via sipgate.io. If anyone have any previous experience with it , please help me to get start with incoming calls.
This is what i'm looking for in my app :
Handle incoming calls
Handle dtmf(when a user makes an entry of digits during a call like options 1-9)
on the basis of selection , Python script needs to perform some actions
To get DTMF data, you need to use the Push-API from sipgate.io.
Your server needs to supply a URL, which can then be setup in the sipgate web interface.
Every time you get an incoming call, you will get an incoming Webhook (HTTP) request, which supplies you with information about the call, like its call-id.
The call-id can then be used in the REST-API.
After receiving the Webhook, send a Gather-Follow Up XML-response to get DTMF data.
Here is the example Response you can send to play a sound file and receive follow up events for DTMF data:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Gather onData="http://localhost:3000/dtmf" maxDigits="3" timeout="10000">
<Play>
<Url>https://example.com/example.wav</Url>
</Play>
</Gather>
</Response>
Afterwards you will receive onData-events.
In case node.js is an option for you, you could consider using the sipgate.io node-library.
There also exists an example for your use-case utilising the library.
To use the Push API, you have to book the sipgate.io package, that includes 100 free API Calls per Month.

How can I configure a Flask API to allow for token-protected user-specific responses?

If I have a server end point that say does a simple task like initializes an API with a token that I generate client side, and then print the users account info.
Can I initialize() the API globally so the user can do other tasks after printing account info?
and
How does that affect other users initializing() and printing info if they do it at the same time?
I don't understand how this server works and any help would be great. Thank you!
If I'm understanding you correctly, it sounds like the easiest way to accomplish what you're trying to do is to use the flask-login module.
You will want to create an endpoint / Flask route (for example, '/login') that the user will send a POST request to with a username (and usually also a password). When the login is successful, the user's browser will have a cookie set with a token that will allow them to access Flask routes that have a #login_required decorator attached.
In your Python code for those routes, you will be able to access the "current_user", which will allow you to tailor your response to the particular user sending the request.
This way of doing things will allow you to deal with your first question, which seems to be about saving a user's identity across requests, and it will also allow you to deal with your second question, which seems to be about the problem of having different users accessing the same endpoint while expecting different responses.
Nathan's answer points you in the right direction, but I'll make a comment about state and scope because you asked about multiple users.
Firstly, the normal way to do this would be for the server to generate the random token and send it back to the user.
client request 1 > init > create token > store along with init data > return token to user
client request 2 > something(token) > find data related to token > return data to user
When you run Flask (and most webapps) you try to make it so that each request is independent. In your case, the user calls an endpoint and identifies themselves by passing a token. If you make a record of that token somewhere (normally in a database) then you can identify that user's data by looking up the same token they pass on subsequent requests.
Where you choose to store that information is important. As I say a database is the normal recommended approach as it's built to be accessed safely by multiple people at the same time.
You might be tempted to not do the database thing and actually store the token / data information in a global variable inside python. Here's the reason why that's (probably) not going to work:
Flask is a wsgi server, and how it behaves when up and running depends on how it's configured. I generally use uwsgi with several different processes. Each process will have its own state that can't see one another. In this (standard / common) configuration, you don't know which process is going to receive any given request.
request 1 > init(token) > process 1 > store token in global vars
request 2 > other(token) > process 2 > can't find token in global vars
That's why we use a database to store all shared information:
request 1 > init(token) > process 1 > store token in db
request 2 > other(token) > process 2 > can find token db

Django, global variables and tokens

I'm using django to develop a website. On the server side, I need to transfer some data that must be processed on the second server (on a different machine). I then need a way to retrieve the processed data. I figured that the simplest would be to send back to the Django server a POST request, that would then be handled on a view dedicated for that job.
But I would like to add some minimum security to this process: When I transfer the data to the other machine, I want to join a randomly generated token to it. When I get the processed data back, I expect to also get back the same token, otherwise the request is ignored.
My problem is the following: How do I store the generated token on the Django server?
I could use a global variable, but I had the impression browsing here and there on the web, that global variables should not be used for safety reason (not that I understand why really).
I could store the token on disk/database, but it seems to be an unjustified waste of performance (even if in practice it would probably not change much).
Is there third solution, or a canonical way to do such a thing using Django?
You can store your token in django cache, it will be faster from database or disk storage in most of the cases.
Another approach is to use redis.
You can also calculate your token:
save some random token in settings of both servers
calculate token based on current timestamp rounded to 10 seconds, for example using:
token = hashlib.sha1(secret_token)
token.update(str(rounded_timestamp))
token = token.hexdigest()
if token generated on remote server when POSTing request match token generated on local server, when getting response, request is valid and can be processed.
The simple obvious solution would be to store the token in your database. Other possible solutions are Redis or something similar. Finally, you can have a look at distributed async tasks queues like Celery...

How to secure a webhook in Django using Stripe

I have a webhook view which receives POST requests from a payment gateway. It identifies the customer and updates the amount with the provided data.
This can be exploited very easily if the webhook URL somehow gets leaked.
For e.g.
curl --data "cust_no=xxxxxxxxxx&amount=1000" https://example.com/wallet/payment_webhook/
How can I make it secure so that it doesn't accept such requests? It should validate that the request is coming only from the payment gateway.
Update:
The webhook request contains transaction details along with the customer number.
It's explicitly documented on the webhooks documentation:
Best practices
[...]
For optimum security, you can confirm the event data with Stripe before acting upon it. To do so:
Parse the JSON data as above.
Grab the received Event object ID value.
Use the Event object ID in a retrieve event API call.
Take action using the returned Event object.
See also Webhook-Mailer for a working example. Pay particular attention to this line:
# Retrieving the event from the Stripe API guarantees its authenticity
event = Stripe::Event.retrieve(data[:id])

Testing Django Responses to Stripe Webhooks

I'm trying to figure out an effective way to test how my server handles webhooks from Stripe. I'm setting up a system to add multiple subscriptions to a customer's credit card, which is described on Stripe's website:
https://support.stripe.com/questions/can-customers-have-multiple-subscriptions
The issue I'm having is figuring out how to effectively test that my server is executing the scripts correctly (i.e., adding the correct subscriptions to the invoice, recording the events in my database, etc.). I'm not too concerned about automating the test right now, I'm just struggling to effectively run any good test on the script. Has anyone done this with Django previously? What resources and tools did you use to run these tests?
Thanks!
I did not use any tools to run the tests. Impact the stripe has a FULL API REFERENCE which display the information you have send to them and they also display the error. Stripe is very easy to setup, cheap, and have full details in documentation.
What I did is?
First I create a stripe account. In that account, they will give you:
TEST_SECRET_KEY: use for sending payment and information in stripe (for testing)
TEST_PUBS_KEY: identifies your website when communicating with Stripe (for testing)
LIVE_SECRET_KEY: use for sending payment and information in stripe (for live)
LIVE_PUBS_KEY: identifies your website when communicating with Stripe (for live)
API_VERSION: "2012-11-07" //this is the version for testing only
When you login you will see Documentation at the top. Click the documentation and they will give you step by step tutorial on how to create a form, how to create subscription, how to handle errors and many more.
To check if your script is executing and connecting to stripe. Click FULL API REFERENCE then choose Python. In that page you will see the information you have send and error that you have encountered.
What I really like is, if the Stripe detect an error the system will point out that and give you a solution. The solution is in the left side and checking the information send is on the right side.
Stripe is divided into two worlds: the test mode and the live. In test mode, you can perform creating new customer, add new invoices, set up your subscription, and many more. What ever you do in test mode, is the same when your Stripe is live.
I really love that stripe provides the logs for the web hooks, however, it is difficult to view the error responses from them, so I set up a script using the Requests library. First, I went to the Stripe dashboard and copied one of the requests they were sending.
Events & Webhooks --> click on one of the requests --> copy the entire request
import requests
data = """ PASTE COPIED JSON REQUEST HERE """
# insert the appropriate url/endpoint below
res = requests.post("http://localhost:8000/stripe_hook/", data=data).text
output = open("hook_result.html", "w")
output.write(res)
output.close()
Now I could open hook_result.html and see any django errors that may have come up (given DEBUG=True in django).
In django-stripe-payments I have a test suite that while far from comprehensive is meant to be a start at getting there. What I do is just copy a real webhook's data, scrub it for sensitive data and add it as a data to the test.
testing stripe webhooks is a pain. I don't use Django, so my answer will be more general.
My php webhook handler parses the webhook data and dispatches handler functions accordingly. In my handler class, I set up class properties with legitimate data for all the ids that the test webhooks mangles. Then I have a condition in each of my handler functions that tests for livemode. If false, I replace the mangled ids with legit test ids.
I also have another class property called $fakeLiveMode, which I set to true when I'm testing. This allows me to force the code to process as though in live mode.
So, for example, when testing the customer.subscription.updated event, the plan id and customer id get botched. So in that handler I would do this:
if ($event->livemode === true || $this->fakeLivemode)
{
if ($this->fakeLivemode)
{
// override botched data returned by test webhook
$event->data->object->plan->id = $this->testPlanId;
$event->data->object->customer = $this->testCustomerId;
}
// process webhook
}
Does that help?

Categories

Resources