Receiving mail using Bottle on Google App Engine - google-app-engine

I'm new to programming. I'm using Bottle on GAE. I want to receive and read mails (if it's possible).
This is my app.yaml file:
- url: /_ah/mail/contact#appid.appspotmail.com
script: main.py
login: admin
inbound_services:
- mail
This is (should be) my mail handler in the main.py file:
from google.appengine.api import mail
from google.appengine.ext.webapp.mail_handlers import InboundMailHandler
#route('/_ah/mail/contact#appid.appspotmail.com', method = 'POST')
def receive_mail():
pass
When I send an email to the above address in logs appears:
2012-09-03 17:03:00.878 /_ah/mail/contact#appid.appspotmail.com 200 187ms 0kb
0.1.0.20 - - [03/Sep/2012:07:03:00 -0700] "POST /_ah/mail/contact#appid.appspotmail.com HTTP/1.1" 200 59
How can I read/parse the mail?
Thank you in advance for any answer or comment.

You should be able to decode the POST body using mail.InboundEmailMessage like in webapp.InboundMailHandler
from google.appengine.api import mail
#route('/_ah/mail/contact#appid.appspotmail.com', method = 'POST')
def receive_mail():
message = mail.InboundEmailMessage(request.body)
logging.info("received email from: %s" % message.sender)

Related

React and Flask with Socket.IO - CORS problem

I'm trying to make a Flask server (port 5000) that has a socket.io connection with a React client (port 3000). When I try to execute the server script (shown below), I get an error that says "http://localhost:3000 is not an accepted origin" even though I am using CORS.
server-test.py:
from flask import Flask
from flask_socketio import SocketIO, emit
from flask_cors import CORS, cross_origin
import os
from dotenv import load_dotenv, find_dotenv
load_dotenv(find_dotenv())
app = Flask(__name__)
app.config['CORS_HEADERS'] = 'Content-Type'
app.config['SECRET_KEY'] = os.environ.get('SECRET')
socketio = SocketIO(app)
CORS(app)
#socketio.on('connect')
#cross_origin()
def handle_connection():
emit('server-client', 'Test message')
#socketio.on('client-server')
#cross_origin()
def handle_client_msg(msg):
print("\n" + str(msg))
if __name__ == '__main__':
app.run(host="localhost", port=os.environ.get('PORT'))
socketio.run(app)
App.jsx:
import { io } from 'socket.io-client';
// ...
useEffect(() => {
const socket = io('http://localhost:5000');
socket.on('server-client', msg => {
alert(msg);
socket.emit('client-server', 'Client: Message received!');
});
}, []);
Error message in WSL terminal:
* Serving Flask app 'server-test' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://localhost:5000/ (Press CTRL+C to quit)
http://localhost:3000 is not an accepted origin. (further occurrences of this error will be logged with level INFO)
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZQ HTTP/1.1" 400 -
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZS HTTP/1.1" 400 -
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZR.0 HTTP/1.1" 400 -
127.0.0.1 - - [16/May/2021 00:27:31] "GET /socket.io/?EIO=4&transport=polling&t=NboMpZR HTTP/1.1" 400 -
The Flask SocketIO documentation says this:
If an incoming HTTP or WebSocket request includes the Origin header, this header must match the scheme and host of the connection URL. In case of a mismatch, a 400 status code response is returned and the connection is rejected.
and this:
If necessary, the cors_allowed_origins option can be used to allow other origins. This argument can be set to a string to set a single allowed origin, or to a list to allow multiple origins. A special value of '*' can be used to instruct the server to allow all origins, but this should be done with care, as this could make the server vulnerable to Cross-Site Request Forgery (CSRF) attacks.
So instead of this:
socketio = SocketIO(app)
you could do this:
socketio = SocketIO(app, cors_allowed_origins="*")
Unrelated to the cors issue, but I also added return statements to the functions. Without returning something I got:
TypeError: The view function did not return a valid response.
Seems to be required if using the #cross_origin() decorators, so you could also remove those and then you don't need the return statements.

500 error while deploying telegram bot to google app engine

I'm new to telegram bot development, and I got stuck, while deploying project to GAE and creating webhooks
I have a simple bot, which I took from here https://github.com/sooyhwang/Simple-Echo-Telegram-Bot:
from flask import Flask, request
import telegram
import config
import logging
bot = telegram.Bot(config.token)
app = Flask(__name__)
URL = 'my-service-dot-kristik-160312.appspot.com/'
#def sendPhotoToServer() -> Bool:
# sending photo to server
# return
#app.route('/HOOK', methods=['POST'])
def webhook_handler():
if request.method == "POST":
update = telegram.Update.de_json(request.get_json(force=True))
chat_id = update.message.chat.id
text = update.message.text.encode('utf-8')
bot.sendMessage(chat_id=chat_id, text=text)
logging.getLogger().setLevel(logging.INFO)
logging.info('===============TEXT=================')
return 'ok'
#app.route('/set_webhook', methods=['GET', 'POST'])
def set_webhook():
s = bot.setWebhook('https://my-service-dot-kristik-160312.appspot.com/HOOK')
if s:
return "webhook setup ok"
else:
return "webhook setup failed"
#app.route('/')
def index():
return 'App is ready'
When I go to https://my-service-dot-kristik-160312.appspot.com/set_webhook I get 500 error.
What am I doing wrong?
Server logs:
5.254.65.88 - - [04/Mar/2017:00:53:54 +0300] "GET /set_webhook HTTP/1.1" 500 264 - "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36" "my-service-dot-kristik-160312.appspot.com" ms=12 cpu_ms=18 cpm_usd=2.9504e-8 loading_request=0 instance=00c61b117c22a1c62e3fac7b35862e68e42b61f0284c2de4c4f50e319bcfa0d57efafc3b4e58 app_engine_release=1.9.48 trace_id=28ae78361cb2dde6bf4f6388ba535198
00:53:54.036
Entering: setWebhook
00:53:54.040
[2017-03-03 21:53:54,039] ERROR in app: Exception on /set_webhook [GET]
00:53:54.040
Traceback (most recent call last):
00:53:54.040
File "/base/data/home/apps/e~kristik-160312/my-service:20170303t195857.399582377782761728/lib/flask/app.py", line 1982, in wsgi_app
00:53:54.040
response = self.full_dispatch_request()
00:53:54.040
File "/base/data/home/apps/e~kristik-160312/my-service:20170303t195857.399582377782761728/lib/flask/app.py", line 1614, in full_dispatch_request
00:53:54.040
rv = self.handle_user_exception(e)
00:53:54.040
File "/base/data/home/apps/e~kristik-160312/my-service:20170303t195857.399582377782761728/lib/flask/app.py", line 1517, in handle_user_exception
00:53:54.040
reraise(exc_type, exc_value, tb)
00:53:54.040
File "/base/data/home/apps/e~kristik-160312/my-service:20170303t195857.399582377782761728/lib/flask/app.py", line 1612, in full_dispatch_request
Telegram Bot API Webhooks are not made to support redirections.
When you set the Webhook URL as the GAE, nothing works. Upon checking getWebhooInfo, you will get the last_error_message as Wrong response from the webhook: 302 Moved Temporarily
And yes, Google Script Content Service documentation says, content returned by the Content service isn't served from script.google.com, but instead redirected to a one-time URL at script.googleusercontent.com. This means that if you use the Content service to return data to another application, you must ensure that the HTTP client is configured to follow redirects
So, you cannot use Google Script URL as webhook

GAE TaskQueue hitting Endpoints API

I have an endpoint api named "gameApi"
I have an api called:
#ApiMethod(name = "startNewRound", path = "evaluateRound", httpMethod = HttpMethod.POST)
I'm trying to run the following task queue:
queue.add(
ofy().getTransaction(),
TaskOptions.Builder.withUrl("/_ah/api/gameApi/v1/evaluateRound")
.param("gameId", gameId.toString())
.method(TaskOptions.Method.POST)
.countdownMillis(5000));
I'm getting a 404 in the logs:
0.1.0.2 - - [14/Nov/2014:14:58:28 -0800] "POST /_ah/api/gameApi/v1/evaluateRound HTTP/1.1" 404 234 "https://some-appspot-123.appspot.com/_ah/spi/com.appspot.some_appspot_123.spi.GameAPI.playCard" "AppEngine-Google; (+http://code.google.com/appengine)" "some-appspot-123.appspot.com" ms=8 cpu_ms=21 cpm_usd=0.000026 queue_name=default task_name=62689306220576549071 instance=00c61b117c54ec2fb802c51c19fe26523ec51854 app_engine_release=1.9.16
It looks like it's hitting the HTTP and not the HTTPS page. Is there a way I can force it to use HTTPS?
In endpoints, HTTP 404 corresponds to com.google.api.server.spi.response.NotFoundException.
Is it possible that the method has not been defined in the API class, or that it doesn't have a correct annotation?
Also, it doesn't seem like it's hitting http, the trace clearly shows https as the protocol. I think it's only possible to use http on localhost.

GAE Cloud endpoints not showing in the explorer

i'm new to the cloud endpoint of GAE. I've made a small example, but it does not work,
this is the terminal output:
INFO 2014-04-17 16:34:50,293 sdk_update_checker.py:242] Checking for updates to the SDK.
INFO 2014-04-17 16:34:51,227 sdk_update_checker.py:286] This SDK release is newer than the advertised release.
WARNING 2014-04-17 16:34:51,240 api_server.py:374] Could not initialize images API; you are likely missing the Python "PIL" module.
INFO 2014-04-17 16:34:51,244 api_server.py:171] Starting API server at: http://localhost:64102
INFO 2014-04-17 16:34:51,248 dispatcher.py:182] Starting module "default" running at: http://localhost:8080
INFO 2014-04-17 16:34:51,253 admin_server.py:117] Starting admin server at: http://localhost:8000
INFO 2014-04-17 16:34:58,926 module.py:627] default: "GET /_ah/api/static/proxy.html?jsh=m%3B%2F_%2Fscs%2Fapps-static%2F_%2Fjs%2Fk%3Doz.gapi.en.5SU5w8-2ONg.O%2Fm%3D__features__%2Fam%3DAQ%2Frt%3Dj%2Fd%3D1%2Fz%3Dzcms%2Frs%3DAItRSTMA_WMz6FduGUvb6_l_lrFfWB57ig HTTP/1.1" 200 7327
INFO 2014-04-17 16:34:59,038 module.py:627] default: "POST /_ah/spi/BackendService.getApiConfigs HTTP/1.1" 404 -
INFO 2014-04-17 16:34:59,038 module.py:627] default: "GET /_ah/api/discovery/v1/apis HTTP/1.1" 500 60
as you see there's a 404 and a 500, which i don't know why
this is the code i wrote:
import endpoints
from protorpc import messages
from protorpc import message_types
from protorpc import remote
package = 'mypackage'
class YourResponseMessageClass(messages.Message):
message = messages.StringField(1)
#endpoints.api(name='myendpoint', version='v1')
class ExampleAPI(remote.Service):
#endpoints.method(message_types.VoidMessage,
YourResponseMessageClass,
name='foo.bar')
def user_get(self, request):
return YourResponseMessageClass(message="ciao")
APPLICATION = endpoints.api_server([ExampleAPI])
i've all the file in the same folder (can i move the api in subfolder btw?), and my yaml file looks like this:
application: ls-gae-api
version: 1
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /favicon\.ico
static_files: favicon.ico
upload: favicon\.ico
# Endpoints handler
- url: /_ah/api/.*
script: myfile.APPLICATION
libraries:
- name: webapp2
version: "2.5.2"
- name: endpoints
version: 1.0
Correct path for Endpoints handler must be the following:
# Endpoints handler
- url: /_ah/spi/.*
script: myfile.APPLICATION
Note the spi part (you have api).

App Engine Backends and Taskqueue URL login Error

I'm getting this error from a request called from the task queue. It suggests I need to change the app.yaml handler but I think I have the correct handler
Here is the error log entry:
2011-11-17 13:30:35.849 /tasks/kacher 302 209ms 0kb
0.1.0.1 - - [17/Nov/2011:13:30:35 -0800] "GET /tasks/kacher HTTP/1.1" 302 0 - - "rawload.XXX.appspot.com" ms=209 cpu_ms=0 api_cpu_ms=0 cpm_usd=0.000032 queue_name=default task_name=cf2e2f1d39d108b3972a1da8c6532fea
W2011-11-17 13:30:35.842
Request failed because URL requires user login. For requests invoked within App Engine (offline requests like Task Queue, or webhooks like XMPP and Incoming Mail), the URL must require admin login (or no login).
This is the code to call the task:
taskqueue.add(url='/tasks/kacher',target='rawload',method='GET')
Here is my app.yaml, with the task urls as login:admin which seems correct (to me):
- url: /tasks.*
script: main.py
login: admin
- url: .*
script: main.py
login: required
secure: always
There's a known bug in the dev_appserver with tasks that require admin login sometimes failing like this. Try logging your browser session in as an admin before accessing the URL that enqueues the task, or try uploading your app to production to see if you experience the issue there.

Resources