I am building an application using the WhatsApp Business Cloud API. Essentially I want to know if it's possible to build an application that collects all the messages from the day and downloads it. Specifically the media attached to it using the API. As far as I know you can use webhooks to get incoming messages. But in order to do this the application has to be run forever, and my cousin has a problem with this as it could cause problems to run an application forever vs just run it once a day. I'm able to send messages using the API and a python wrapper but that's much more simple than what I'm trying to do. Aditionally, there is an option of using selenium but that's not really an automated solution to what we're trying to do because everytime selenium executes the browser we'd need to log in using the QR code. If anyone has any idea if this is possible (or not possible) I'd be very appreciative!
from heyoo import WhatsApp
import logging
import requests
from dotenv import load_dotenv
from flask import Flask, request, make_response
app = Flask(__name__)
token = 'EAAVk5rqOCsABAAcPPrZC6GnlZAJuykdFIQd4DhkuRVNeGntfFOU5jaK4jG2yCZBS6i7kFQGk3kRvDP0fExBXRsFyqWUqfVVJsSxeQdcA9XHWpRuUsnnuwqLcZAQpwTiuoZCXv4ixCcHYlPEe6NGHupCalHvWw9NQRoZAVnegU5ZCBvX6eO9E8vyum1lQ2SSt7OuUpdpIkmkyBK8tiEL8rpGwM8RrqZA3A10ZD'
messenger = WhatsApp(token, phone_number_id='100398242927044')
messenger.send_message('Hey its JJ ', '1xxxxxxxx')
logging.basicConfig(
level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
print("hello")
#app.route("/", methods=["GET", "POST"])
def hook():
//some code that isn't working yet
I'm new to all of this stuff so I don't really know how to set up a webhook either but my cousin who's business I'm building this app for doesn't ideally want to use a webhook.
You can use ngrok server, which provides:
how to use ngrok to integrate your localhost app with WhatsApp by using Webhooks. WhatsApp webhooks can be used to notify an external application whenever specific events occur in your WhatsApp account
https://ngrok.com/docs/integrations/whatsapp/webhooks
Related
I'm currently struggling with Azure Function logs.
I'm trying to redirect all the default logs to the app insight, including metrics and so on.
Here is my architecture:
an App Insight, where the Local authentication is disabled
an azure function, which is "Monitoring Metrics Publisher" on the App Insight
I found the following code on the Azure Microsoft documentation :
from azure.identity import ManagedIdentityCredential
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.trace.samplers import ProbabilitySampler
from opencensus.trace.tracer import Tracer
credential = ManagedIdentityCredential()
tracer = Tracer(
exporter=AzureExporter(credential=credential, connection_string="InstrumentationKey=<your-instrumentation-key>;IngestionEndpoint=<your-ingestion-endpoint>"),
sampler=ProbabilitySampler(1.0)
)
It let me create a tracer. But it does not redirect any metrics.
The second code I found let me add a handler, but without including the ManagedIdentityCredential.
import logging
from opencensus.ext.azure.log_exporter import AzureLogHandler
logger = logging.getLogger(__name__)
# TODO: replace the all-zero GUID with your instrumentation key.
logger.addHandler(AzureLogHandler(
connection_string='InstrumentationKey=00000000-0000-0000-0000-000000000000')
)
I try to merge both snippets of code. The function is running but it doesn't send any metrics.
My goal is to get all azure logs I get before disabling the app insight Local authentication.
How can I achieve this?
Thank you very much for your help.
I recently made a discord bot and ran in on repl.it as it has free hosting (I use uptime robot). But, when I run main.py the uptime robot says that the website that I use for keep_alive() is "Down" and when I try to access the website from my browser it doesn't load either saying that the site "can't be reached". When I close the repl.it tab my bot goes offline as well.
Repl.it is not made for hosting discord bot's it's prone to rate limits.
It's good for writing code online and hosting basic web apps or collaborating with others while coding.
You should definitely invest in a proper host like PebbleHost, PloxHost and etc if you need something to write code online. However, a VPS provider like Linode, Digitalcoean or even PloxHost would be more beneficial as you have your own dedicated IP and are not affected by rate limits from other users. However, this does require knowledge of Linux.
For your issue of your keep_alive you should try this:
from flask import Flask
from threading import Thread
import time
app = Flask('')
#app.route('/')
def home():
return "Hello World!"
def run():
app.run(host='0.0.0.0',port=8080)#127.0.0.1 or ::
def keep_alive():
t = Thread(target=run)
t.start()
Then in your main.py:
from keep_alive import keep_alive
keep_alive()
You should take a look at UptimeRobot to send pings to the URL of the web server associated with the repl. This video is for node.js but should apply to python as well on the UptimeRobot chunk
I'm working on updating an existing university department internal website to run using Flask. Before we completely release the project where it will use shibboleth to manage authentication, I've been trying to setup authentication for testing using htpassword using this tutorial. I'm able to get authentication using htpasswords working for a single file, but I can't figure out how to add the authentication to separate files. Currently, the project looks like this:
This is my main file called app.py:
#app.py
from flask import Flask
from flask_htpasswd import HtPasswdAuth
app = Flask(__name__)
app.config['FLASK_HTPASSWD_PATH'] = '.htpasswd'
app.config['FLASK_SECRET'] = "Super secret key that I will change later"
htpasswd = HtPasswdAuth(app)
import exampleRoute
#app.route('/')
#htpasswd.required
def home(user):
return "This is the homepage"
This is an example of one of my route files called exampleRoute.py:
# exampleRoute.py
from app import app
from flask import Flask
#app.route('/exampleRoute')
def exampleRoute():
return "This is an example route in another file"
When I place the #htpassword.required decorator in front of exampleRoute(), I get an error saying that htpassword is not defined (which makes sense). I've tried to import the app configuration a few different ways and at best, I end up with a circular dependency. I know that I could place the authentication code in a separate file and then import that into all my endpoints, but I didn't think this was possible since this method is incorporated into the app configuration.
I ended up getting an answer from the reddit user alexisprince. The solution was to use Blueprints that import htpasswd from another file (called extensions.py).
I'm having some trouble understanding and implementing the Google Directory API's users watch function and push notification system (https://developers.google.com/admin-sdk/reports/v1/guides/push#creating-notification-channels) in my Python GAE app. What I'm trying to achieve is that any user (admin) who uses my app would be able to watch user changes within his own domain.
I've verified the domain I want to use for notifications and implemented the watch request as follows:
directoryauthdecorator = OAuth2Decorator(
approval_prompt='force',
client_id='my_client_id',
client_secret='my_client_secret',
callback_path='/oauth2callback',
scope=['https://www.googleapis.com/auth/admin.directory.user'])
class PushNotifications(webapp.RequestHandler):
#directoryauthdecorator.oauth_required
def get(self):
auth_http = directoryauthdecorator.http()
service = build("admin", "directory_v1", http=auth_http)
uu_id=str(uuid.uuid4())
param={}
param['customer']='my_customer'
param['event']='add'
param['body']={'type':'web_hook','id':uu_id,'address':'https://my-domain.com/pushNotifications'}
watchUsers = service.users().watch(**param).execute()
application = webapp.WSGIApplication(
[
('/pushNotifications',PushNotifications),
(directoryauthdecorator.callback_path, directoryauthdecorator.callback_handler())],
debug=True)
Now, the receiving part is what I don't understand. When I add a user on my domain and check the app's request logs I see some activity, but there's no usable data. How should I approach this part?
Any help would be appreciated. Thanks.
The problem
It seems like there's been some confusion in implementing the handler. Your handler actually sets up the notifications channel by sending a POST request to the Reports API endpoint. As the docs say:
To set up a notification channel for messages about changes to a particular resource, send a POST request to the watch method for the resource.
source
You should only need to send this request one time to set up the channel, and the "address" parameter should be the URL on your app that will receive the notifications.
Also, it's not clear what is happening with the following code:
param={}
param['customer']='my_customer'
param['event']='add'
Are you just breaking the code in order to post it here? Or is it actually written that way in the file? You should actually preserve, as much as possible, the code that your app is running so that we can reason about it.
The solution
It seems from the docs you linked - in the "Receiving Notifications" section, that you should have code inside the "address" specified to receive notifications that will inspect the POST request body and headers on the notification push request, and then do something with that data (like store it in BigQuery or send an email to the admin, etc.)
Managed to figure it out. In the App Engine logs I noticed that each time I make a change, which is being 'watched', on my domain I get a POST request from Google's API, but with a 302 code. I discovered that this was due to the fact I had login: required configured in my app.yaml for the script, which was handling the requests and the POST request was being redirected to the login page, instead of the processing script.
I am trying to create a trivial python script that allows me to bulk add a list of youtube videos to a playlist of mine.
The problem I am having is getting this script to get authenticated to the google api with my apps credentials.
I am basically just using the sample authentication script at https://developers.google.com/google-apps/calendar/quickstart/python
and this stackoverflow question (Adding youtube video to playlist using Python)
The main stopping point is that I keep getting an Error: redirect_uri_mismatch. Since I am calling the script from the commandline on my laptop, the error is saying: The redirect URI in the request: http://localhost:8080/ did not match a registered redirect URI.
I have set http://localhost:8080 as the JavaScript origins and http://localhost:8080/oauth2callback as the Redirect URIs
And i am using the following (as run from the python shell):
from oauth2client.client import flow_from_clientsecrets
from oauth2client.file import Storage
from oauth2client import tools
from oauth2client.tools import argparser, run_flow
import argparse, sys, os
flow = flow_from_clientsecrets('path to my CLIENT_SECRETS.json file', scope='https://www.googleapis.com/auth/youtube')
store = Storage('config/%s-oauth2.json' % sys.argv[0])
parser = argparse.ArgumentParser(parents=[tools.argparser])
flags = parser.parse_args()
credentials = run_flow(flow, store, flags)
then the terminal opens my browser and in the browser I get the 400 error. The following gets printed to the terminal:
Your browser has been opened to visit:
https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&client_id=my-CLIENT-ID&access_type=offline
If your browser is on a different machine then exit and re-run this
application with the command-line parameter
--noauth_local_webserver
I am not sure what I am really supposed to be putting as the redirect URIs and javascript origins, but I don't intend to run this anywhere else other than as a python script from the terminal of my laptop. The documentation provides https://example.com/ and https://example.com/oauth2callback as pre populated values, but clearly that's not where I am running this "app" from and I know that's just placeholder stuff.
UPDATE: not sure why, but i realize that the url the app is sending me to has the redirect_uri parameter set to just http://localhost:8080/, if i add oauth2callback to the uri than i get sent to the screen where it asks me to accept management of the youtube account. so that's odd.
UPDATE 2: and if I change my redirect uris to just http://localhost:8080/ via the developer console, i can get my credentials, but I am sure this is not the best way to be going about this.
If you are just running this through you terminal than you can use the native host by creating a client ID as an installed app and then selecting other. If you are trying to do this using the web app client ID and only want it to be local then you would use these:
JavaScript origins: http://localhost:your_port_here/
Redirect URIs: http://localhost:your_port_here/url_path
where url_path is the place you want google to send you after authentication.
Edit: the tutorial code only works if you are using a native app. If you are indeed planning to create a web app there are separate instructions.
The redirect_uri parameter set to just http://localhost:8080/ is by design. When you call tools.run_flow() it is spinning up a server of it's own behind the scenes and initiating the oauth flow. It is then expecting the redirect_uri to redirect back to the server it spun up (which is listening on port 8080) so that it can use the access_token it receives to create the credentials and put them in storage.