How to send a whatsapp message from python - python-3.x

I am trying to create a program which on certain conditions will send whatsapp message as notification. I want to perform this task without any third-party registration. Is there a way I can perform this using any python module or framework ?

Create a new file called "wasend.py" and write the following code on it:
import webbrowser
import pyautogui
from time import sleep
def send(text, phone):
webbrowser.open("whatsapp://send?text=" + text.replace('\n', '%0A') + "&phone=" + phone.replace('+', ''))
sleep(10)
pyautogui.click(x=1787, y=978)
sleep(0.2)
pyautogui.hotkey('enter')
sleep(1)
pyautogui.hotkey('alt', "f4")
Then, execute the following commands:
$ pip install pyautogui
$ pip install webbrowser
Create another file called "send.py". On it, write the following code:
import wasend
wasend.send("message", "phone")
I built this program. These are the params of the wasend.send() function:
wasend.send(message, number)
> message
The message in plain text. (Use * for bold, _ for italic, and plain Whatsapp formatting)
Write "\n" to make a line break.
> number
The phone number in the format: IIINNNNNNNNN (i = indicative, n = number, without the plus sign)
The program takes 11.5 seconds to execute (you can change the sleep to make it fast, but give some time to WhatsApp to load. If you already have WhatsApp loaded, change line 7 in wasend.py to sleep(1), so the program takes only 2.5 seconds to load.

You could do it in the following way, I hope it helps.
import requests
import json
PHONE_ID = "<whatsapp-phone-id>"
TOKEN = "<whatsapp-token>"
NUMBER = "<number>"
MESSAGE = "<message>"
URL = "https://graph.facebook.com/v13.0/"+PHONE_ID+"/messages"
headers = {
"Authorization": "Bearer "+TOKEN,
"Content-Type": "application/json"
}
data = {
"messaging_product": "whatsapp",
"to": NUMBER,
"type": "text",
"text": json.dumps({ "preview_url": False, "body": MESSAGE})
}
response = requests.post(URL, headers=headers, data=data)
response_json = response.json()
print(response_json)
You can find more details in the following source https://developers.facebook.com/docs/whatsapp/cloud-api/reference/messages#text-object

Related

Kucoin API get advanced orders

I've been using KuCoin API with python for a while now, but stuck trying to get advanced orders form the API. For reference, 'advanced orders' are what stop limit orders are called within KuCoin dash.
I've used the endpoint: api/v1/orders
. I've experimented with this but it only shows 'normal' orders or the order history if 'status' is set to 'done'. Ref: https://docs.kucoin.com/#list-orders
I'm wondering if instead I should use: /api/v1/limit/orders. This endpoint has an option to return stop_limit orders. But when I try, I get response:
{"code":"400007","msg":"Access denied, require more permission."}'
I checked my API permissions and its 'General' permission is set to 'read only' which is the only option. Read only would be fine for me because I only want to get the list of all 'Advanced orders'
See https://docs.kucoin.com/#recent-orders
Does anyone know how to get all open limit orders please? The reason I want this is I have placed many limit orders. I want to collect the orderid's of all stop limit orders so I can clean out just the ones not associated to an active trade.
my code is as follows:
import requests
import json
import hmac
import hashlib
import base64
from urllib.parse import urlencode
import time
from urllib.request import urlretrieve
'''working code to get active orders'''
api_key = 'api_key'
api_secret = 'api_secret'
api_passphrase = 'api_passphrase' # this is NOT trading password
base_uri = 'https://api.kucoin.com'
def get_headers(method, endpoint):
now = int(time.time() * 1000)
str_to_sign = str(now) + method + endpoint
signature = base64.b64encode(hmac.new(api_secret.encode(), str_to_sign.encode(), hashlib.sha256).digest()).decode()
passphrase = base64.b64encode(hmac.new(api_secret.encode(), api_passphrase.encode(), hashlib.sha256).digest()).decode()
return {'KC-API-KEY': api_key,
'KC-API-KEY-VERSION': '2',
'KC-API-PASSPHRASE': passphrase,
'KC-API-SIGN': signature,
'KC-API-TIMESTAMP': str(now)
}
#List Orders
method = 'GET'
endpoint = '/api/v1/limit/orders/' # main
# params = {'type': 'stop_limit'}
params = {}
# # if params :
qstr = '?' + urlencode(params)if params else ''
active_orders = requests.get(url=base_uri+endpoint+qstr, headers=get_headers(method,endpoint+qstr))

Urllib3 POST request with attachment in python

I wish to make a post request to add an attachment utilising urllib3 in python without success. I have confirmed the API itself is working in postman but cannot work out how to convert this request to python. Appreciating I'm mixing object types I just don't know how to avoid it.
Python code:
import urllib3
import json
api_key = "secret_key"
header = {"X-API-KEY": api_key, "ACCEPT": "application/json", "content-type": "multipart/form-data"}
url = "https://secret_url.com/api/"
http = urllib3.PoolManager()
with open("invoice.html", 'rb') as f:
file_data = f.read()
payload = {
"attchment": {
"file": file_data
}
}
payload = json.dumps(payload)
r = http.request('post', url, headers = header, fields = payload)
print(r.status)
print(r.data)
Postman - which works and properly sends file-name through also (I'm guessing it splits the bytes and filename up?)
Edit: I've also tried the requests library as I'm more familiar with this (but can't use it as the script will be running in AWS lambda). Removing the attachment element form the dict allows it to run but the API endpoint gives 401 presumably because it's missing the "attachement" part to the data structure as per postman below... but when I put this in I get runtime errors.
r = requests.post(url, headers = header, files={"file": open("invoice.html", 'rb')})
For anyone who stumbles upon this from Dr google a few points:
I was completely mis-interpreting the structure of the element. It's actually a string "attachment[file]" not a dict like object.
Postman has the ability to output python code in urllib/request syntax albeit not 100% what I was after. Note: the chrome version (depreciated) outputs gibberish code that only half works so the client version should be used. A short bit of work below shows it working as expected:
http = urllib3.PoolManager()
with open("invoice.html", "rb") as f:
file = f.read()
payload={
'attachment[file]':('invoice.html',file,'text/html')
}
r = http.request('post', url, headers = header, fields = payload)

Using Django to create Strava Webhook subscription

I am trying to create a Strava webhook subscription to recieve events from users who have authorised my Strava application. I was able to successfully create a subscription using the code in this Strava tutorial. However, I don't understand Javascript, so can't adapt the code to my needs. I am therefore trying to replicate it's functionality within Python using Django.
My basic approach has been to follow the setup outlined in the Django section of this webpage, then replace the code in the file views.py with the code below. I have tried to make the code function as similarly as possible to the Javascript function within the tutorial I linked above. However, I'm very new to web applications, so have taken shortcuts / 'gone with what works without understang why' in several places.
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.clickjacking import xframe_options_exempt
import json
#csrf_exempt
#xframe_options_exempt
def example(request):
if request.method == "GET":
verify_token = "STRAVA"
str_request = str(request)
try:
mode = str_request[str_request.find("hub.mode=") + 9 : len(str_request) - 2]
token = str_request[str_request.find("hub.verify_token=") + 17 : str_request.find("&hub.challenge")]
challenge = str_request[str_request.find("hub.challenge=") + 14 : str_request.find("&hub.mode")]
except:
return HttpResponse('Could not verify. Mode, token or challenge not valid.')
if (mode == 'subscribe' and token == verify_token):
resp = json.dumps({"hub.challenge":challenge},separators=(',', ':'))
return HttpResponse(resp, content_type='application/json; charset=utf-8')
else:
return HttpResponse('Could not verify mode or token.')
The Strava documentation says that the callback url must respond to a GET request within 2 seconds with a status of 200 and an echo of the hub.challenge json string. This function seems to do that. Yet when I try to create a POST request equivalent to the one below:
$ curl -X POST https://www.strava.com/api/v3/push_subscriptions \
-F client_id=[MY-CLIENT-ID] \
-F client_secret=[MY-CLIENT-SECRET] \
-F 'callback_url=http://[MY-IP-ADDRESS]:8000/webhooks/example/' \
-F 'verify_token=STRAVA'
I get the following response:
{
"message": "Bad Request",
"errors": [
{
"resource": "PushSubscription",
"field": "callback url",
"code": "not verifiable"
}
]
}
Does anyone have any idea what might be going wrong?
P.S. Please let me know if there's anything I can do to make this example more reproducible. I don't really understand this area well enough to know whether I'm leaving out some crucial info!

Facebook messenger chatbot with Flask and pymessenger

I have created a messenger chatbot with flask, pymessenger and wit.ai.
I want to add facebook provided templates (like buttons, adding images and sound media)(https://developers.facebook.com/docs/messenger-platform/reference/template/button/)
There using some curl and json thing which I do not understand. Can some one help me, where should I put these snippet in my python code.
#app.route('/', methods=['POST'])
def webhook():
data = request.get_json()
log(data)
if data['object'] == 'page':
for entry in data['entry']:
for messaging_event in entry['messaging']:
sender_id = messaging_event['sender']['id']
recipient_id = messaging_event['recipient']['id']
if messaging_event.get('message'):
if 'text' in messaging_event['message']:
messaging_text = messaging_event['message']['text']
else:
messaging_text = 'no text'
response = None
entity, value = wit_response(messaging_text)
if entity == 'newstype':
response = "OK. I will send you {} news".format(str(value))
elif entity == 'cust_greet':
response = get_message()
elif entity == 'cust_bye':
response = "Bye! Have a Good Day!".format(str(value))
elif entity == 'cust_option':
response = "Option 1: Option 2:"
bot.send_text_message(sender_id, response)
return "ok", 200
def log(message):
print(message)
sys.stdout.flush()
HTTP requests use one of these two formats:
GET: All the request information is in the url
POST: Some information is sent via a JSON format to the url
What we see in the Facebook API is a POST request: the url is defined as
https://graph.facebook.com/v2.6/me/messages?access_token=<PAGE_ACCESS_TOKEN>
...and there is POST request information in the JSON section underneath
Curl is a program used to send HTTP requests from the terminal. If you install Curl, you can fill in the JSON/url information, run the command (which sends the POST request), and see the buttons pop up for the recipient. Just as you want your chatbot to do!
However, Curl is a tool, not a Python library!
To do this in Python, you can send the request through Python's built in libraries, or install a package which makes this easier (such as requests), look into "sending http requests via python".
Below is an example (adapted from this question):
from urllib.parse import urlencode
from urllib.request import Request, urlopen
# the url we are sending the request to
url = "https://graph.facebook.com/v2.6/me/..."
# the POST request data
request_data = {
"recipient": {
"id": "<PSID>"
},
"message": {
"attachment": {
...
}
}
}
# create the request with the url and the data
post_request = Request(url, urlencode(request_data).encode())
# send it to Facebook! Response is the API response from Facebook
response = urlopen(post_request).read().decode()

python requests (form filling)

This is the link to a page
filling forms...
https://anotepad.com/notes/2yrwpi
where I have to enter the content in the text area (say)("hello world") and then press save, but all this is to be done with python request module (get, post etc)
and without the use of selenium and beautifulsoup module.
I tried something like:
url="https://anotepad.com/notes/2yrwpi"
txt = "Hello World"
#construct the POST request
form_data = {'btnSaveNote':'Save', 'notecontent' : txt}
post = requests.post(url,data=form_data)
But that doesn't seem to be working
Please help!
You need to login and post to the save url, you also need to pass the note number in the form data:
import requests
save = "https://anotepad.com/note/save"
txt = "Hello World"
login = "https://anotepad.com/create_account"
data = {"action": "login",
"email": "you#whatever.com",
"password": "xxxxxx",
"submit": ""}
# construct the POST request
with requests.session() as s: # Use a Session object.
s.post(login, data) # Login.
form_data = {"number": "2yrwpi",
"notetype": "PlainText",
"noteaccess": "2",
"notequickedit": "false",
"notetitle": "whatever",
"notecontent": txt}
r = s.post(save, data=form_data) # Save note.
r.json() will give you {"message":"Saved"} on success. Also if you want to see what notes you have, after logging in, run s.post("https://anotepad.com/note/list").text.

Resources