How to send a text message with Whatsapp Cloud API - python

I'm having troubles using Whatsapp Cloud API (which was released to the public on May 22). I did everything in the getting started in "Set up Developer Assets and Platform Access" section, that way I was able to send the template hello world in Ubuntu 20.04.4 LTS with:
curl -i -X POST \
https://graph.facebook.com/v14.0/my_number/messages \
-H 'Authorization: Bearer my_token' \
-H 'Content-Type: application/json' \
-d '{ "messaging_product": "whatsapp",
"to": "my_reciever",
"type": "template",
"template": { "name": "hello_world", "language": { "code": "en_US" } }
}'
or with Python 3.10 and requests 2.27.1 with:
from requests import Session
import json
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
BASE_URL = "https://graph.facebook.com/"
API_VERSION = "v13.0/"
SENDER = "my_number/"
ENDPOINT = "messages"
URL = BASE_URL + API_VERSION + SENDER + ENDPOINT
API_TOKEN = "my_token"
TO = "my_reciever"
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
parameters = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": TO,
"type": "template",
"template": {"name": "hello_world", "language": {"code": "en_US"}}
}
session = Session()
session.headers.update(headers)
try:
response = session.post(URL, json=parameters)
data = json.loads(response.text)
print(f"data: {data}")
except (ConnectionError, Timeout, TooManyRedirects) as e:
print(e)
Then, I tried to send a text message with this:
from requests import Session
import json
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
BASE_URL = "https://graph.facebook.com/"
API_VERSION = "v13.0/"
SENDER = "my_number/"
ENDPOINT = "messages"
URL = BASE_URL + API_VERSION + SENDER + ENDPOINT
API_TOKEN = "my_token"
TO = "my_reciever"
headers = {
"Authorization": f"Bearer {API_TOKEN}",
"Content-Type": "application/json"
}
parameters = {
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": TO,
"type": "text",
"text": {
"preview_url": "false",
"body": "MESSAGE_CONTENT"
}
}
session = Session()
session.headers.update(headers)
try:
response = session.post(URL, json=parameters)
data = json.loads(response.text)
print(f"data: {data}")
except (ConnectionError, Timeout, TooManyRedirects) as e:
print(e)
And, even though the response is correct, something like this:
{'messaging_product': 'whatsapp', 'contacts': [{'input': 'my_reciever', 'wa_id': 'my_reciever'}], 'messages': [{'id': 'wamid.HBgMNTchangingMDYyM0I2AA=='}]}
I don't recieve any message in my_reciver. I don't know what I'm doing wrong, I might have to configure the webhook for this to work? Do I need to opt-in before recieve the message (this can be read in get-started page)?
I even tried using some unofficial wrappers in python like heyoo, but I got the same result.
Hope someone can help me with this, thanks.
Note: this is a similar post, but that one is with node, not Python or Curl, so I guess this does not count as repost.

I have written a brief article on WhatsApp Cloud API like how to send and receive WhatsApp messages and also set up a never expiry access token. Please have a look WhatsApp Cloud API
You need to send the WhatsApp message from your personal number to your WhatsApp business number after that you can send the message from your business number to your personal number. Basically, WhatsApp has a template message concept within 24h session and according to your question, I think you are trying to send a normal unsession message from a business number to your personal number. So, to avoid this case you need to first message from your personal to your business number then you can receive the message to your personal number. Full details in the article regarding template message.
Here is the CURL request for normal message
curl --location --request POST 'https://graph.facebook.com/v13.0/<Your Phone number ID>/messages' \
--header 'Authorization: Bearer <Your Temporary access token>' \
--header 'Content-Type: application/json' \
--data-raw '{"messaging_product":"whatsapp","recipient_type":"individual",
"to":"918587808915","type":"text","text": {"body":"Hello Rishabh!"}
}'

The official META-whatsapp documentation indicates that in order to send such messages, the conversation must be initiated by the user. https://developers.facebook.com/docs/whatsapp/conversation-types

Related

python put requests a file

i'm trying to interact with a website's APIs--specifically how to requests.put() a file (JPEG) to it. the Swagger API has a "try it out" function where I successfully can push a file from its "try it out" but when I try to run it in python it throws a 500 internal server error.
this is the successful curl put request from the Swagger "try it out":
curl -X PUT "https://some_website.com/api/v2/documents" -H "accept: /" -H "Content-Type: multipart/form-data" -H "Authorization: Bearer auth tokenp089u098u08j98jasdfsadgfasdg" -d {"file":{},"metadata":"{ "docType":"BILL_OF_LADING", "docTypeNamespace":"platform", "fileType":"IMAGE", "docReferences":{ "name":"bill o lading pal" }, "identifiers":{ "consignment":{ "carrierBookingNumber":"9876smg", "billOfLadingNumber":"1234smg" } } }"}
url = "https://some_website.com"
auth_token = "Bearer auth tokenp089u098u08j98jasdfsadgfasdg"
headers = {"Content-Type": "multipart/form-data",
"Accept": "*/*",
"Authorization": sa_token}
file_loc = "C:/location/of/file/I/want/to/put/Capture.JPG"
metadata = {
"docType":"doc_file",
"docTypeNamespace": "platform",
"fileType":"IMAGE",
"docReferences": {
"name": "this is the form to confirm receipt"
},
"identifiers": {
"consignment": {
"carrierBookingNumber":"9876smg",
"billOfLadingNumber":"1234smg"
}
}
}
body = {
"file": {},
"metadata": metadata
}
resp = requests.put(url=url, headers=headers, data=body)
You should probably send it via json as thats very easy...
import requets
file = "C:\somedir\somedir\somefile.somext"
with open(file, "rb") as f:
fileData = f.read()
putFile(fileD, site, port=3000):
requets.post(site, json='{"file": "' + str(fileD) + '"}'
But you'll need to convert it back to a file.

Forming a request.post from a curl on python

I have a small project i need a tempmail for, so i found this site https://mail.tm/en, so i was trying to acess the post via the api and instructions given here https://api.mail.tm/.
As I am new at working with curl and so on I have a lot of problems authorizing into an account there.
First of all i got an CURL link on site like this one:
curl -X POST "https://api.mail.tm/accounts" -H "accept: application/ld+json" -H "Authorization: testing" -H "Content-Type: application/ld+json" -d "{\"address\":\"test\",\"password\":\"stackoverflow\"}"
I tried to form it all in a post request, so i did this
headers = {"accept": "application/ld+json", "Authorization": "header", "Content-Type": "application/ld+json"}
data = "{\"address\":\"zashyganii\",\"password\":\"chertila\"}"
mail = requests.post("https://api.mail.tm/accounts", data = data, headers = headers)
print(mail.status_code)
the error code is 400, noted on the api site like this.
400 Error:
Response body
Download
{
"#context": "/contexts/ConstraintViolationList",
"#type": "ConstraintViolationList",
"hydra:title": "An error occurred",
"hydra:description": "address: This value is not a valid email address.\naddress: The domain \"\" is not valid.",
"violations": [
{
"propertyPath": "address",
"message": "This value is not a valid email address."
},
{
"propertyPath": "address",
"message": "The domain \"\" is not valid."
}
]
}
Could you please turn this curl in to a request.post on python so it will work for this api
Seems like there are not any problem with the request. It's a validation fail.

Dialogflow query HTTP Request

I am trying to create a very simple chatbot using dialogflow that I can ask a question and get a fulfillment message back. I was able to use python's dialogflow library to get this working, but when I tried to change it to a regular request it did not work. Here is the working code:
import os
import dialogflow
from google.api_core.exceptions import InvalidArgument
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = PATH_TO_JSON
DIALOGFLOW_PROJECT_ID = PROJECT_ID
DIALOGFLOW_LANGUAGE_CODE = 'en'
SESSION_ID = 'me'
text_to_be_analyzed = "How are my stocks"
session_client = dialogflow.SessionsClient()
session = session_client.session_path(DIALOGFLOW_PROJECT_ID, SESSION_ID)
text_input = dialogflow.types.TextInput(text=text_to_be_analyzed, language_code=DIALOGFLOW_LANGUAGE_CODE)
query_input = dialogflow.types.QueryInput(text=text_input)
try:
response = session_client.detect_intent(session=session, query_input=query_input)
except InvalidArgument:
raise
#print(response)
print("Response:", response.query_result.fulfillment_text)
and it prints
your stocks are good
Using the request library I tried a similar setup and wrote this:
my_key = CLIENT_ACCESS_TOKEN
url = "https://api.dialogflow.com/v1/query?v=20170712"
headers = {
'Authorization': 'Bearer ' + my_key ,
'Content-Type' : 'application/json'
}
body = {
"lang": "en",
"query": "how are my stocks",
"sessionId": "me",
}
r.post(url,headers=headers,data=body).text
and I get an error:
{
"status": {
"code": 400,
"errorType": "bad_request",
"errorDetails": "Cannot parse json. Please validate your json. Code: 400"
}
}
I am getting my example from this url for the query post request. The reason I want this to work as an http request is because I would like to be able to use it in other applications and want to have a consistent way of accessing my intents. Thanks for the help!
Upon more research I found the error at this link. So the question was less about integration with dialogflow and more about making a request in python.

MSGraph subscription create error: "message": "Operation: Create; Exception: [Status Code: Unauthorized; Reason: ]", "code": "ExtensionError"

I need to create subscription to users using Microsoft Graph.
I have all rights in Aure Active Directory:
User.Read.All.
My subscription method:
def create_subscription_to_users(self):
t = datetime.utcnow() + timedelta(minutes=settings.MAX_TIME_DELTA_IN_MINUTES)
payload = {
"changeType": "updated",
"notificationUrl": "{0}/webhooks/azure".format(settings.AZURE_WEBHOOKS_CALLBACK_BASE_URL),
"resource": "users",
"expirationDateTime": t.strftime("%Y-%m-%dT%H:%M:%S.%fZ")
}
response = self.graph_client.post(url='{0}/subscriptions'.format(settings.GRAPH_URL), json=payload).json()
self.add_log(url='{0}/subscriptions'.format(settings.GRAPH_URL),
method='POST', payload=payload, response=response)
return response
My validation class:
class AzureHook(View):
def post(self, request):
url = request.get_full_path()
parsed_url = parse_qs(urlsplit(url).query)
validation = dict(parsed_url).get('validationToken')[0]
return HttpResponse(validation.encode('utf-8'), content_type='text/plain')
But I still receive as response for creating subscription:
{"error": {"innerError": {"date": "2019-07-03T11:29:39", "request-id": "5e7f1fc3-8ef4-4511-b661-35bf7d146cc3"}, "message": "Operation: Create; Exception: [Status Code: Unauthorized; Reason: ]", "code": "ExtensionError"}}
Could someone please help me with this?
So as to get rid of this error add following scopes in the application. User.Read.All&offline_access, User.ReadWrite.All, Group.ReadWrite.All, Group.Read.All, Directory.ReadWrite.All, Directory.AccessAsUser.All, openid.
To get the authorization code try this url in your browser. https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=&response_type=code&redirect_uri= http://localhost:4200/api/auth/callback/AzureAD&response_mode=query&scope=User.Read.All &User.ReadWrite.All&Group.ReadWrite.All&Group.Read.All&Directory.ReadWrite.All&Directory.AccessAsUser.All&openid&offline_access&state=12345&prompt=login
Try this request first using postman, I am attaching curl request for your reference.
curl -X POST \
https://graph.microsoft.com/v1.0/subscriptions \
-H 'Authorization: Bearer ' \
-H 'Content-Type: application/json' \
-d '{
"changeType": "updated",
"notificationUrl": "https://5690e074.ngrok.io",
"resource": "groups",
"expirationDateTime": "2019-07-13T10:19:03.170Z",
"clientState": "secretClientValue"
}'

logging into the MATCHBOOK API with Python Requests

I am trying (legitimately and with the go ahead from the site)to log into the betting exchange matchbook.com through their api.
The documentation states:
To Login: https://www.matchbook.com/bpapi/rest/security/session
and
Example Request
POST /security/session
{
"username": "j_henry",
"password": "******"
}
Example Response
{
"session-token": "1418_1234567890",
"user-id": 1418,
"account": { // Same as GET /account API response.
...
}
}
I am using Requests and have the following code:
payload = {"username": "********", "password": "************"}
r = requests.post('https://www.matchbook.com/edge/rest/security/session', data=payload)
print (r.status_code)
I get error code 415? I must be getting the wrong type of response??
I have looked at a lot of very similar posts on here, and I am about to ask matchbook's team, but before I do has anybody got any ideas?
You might have to specify Content-Type, try to add a header to tell the server it's JSON formatted:
payload = {"username": "********", "password": "************"}
headers = {"Content-Type": "application/json;"}
r = requests.post('https://www.matchbook.com/edge/rest/security/session', data=payload, headers=headers)
print (r.status_code)
It does not appear from your code that you are JSON-encoding your payload. The endpoint is likely expecting JSON.
Try this:
payload = '{"username": "********", "password": "************"}'

Categories