Right now I have a program that receives an SMS message, posts the body of the message, and then forwards the SMS to another number. However I'm receiving an error from Twilio about the "Scheme validation." The code functions exactly as it should, but I'd like to fix the error.
Initially I had the following code:
import RUAlertsTwilioWEBSERVER
import twilio.twiml
import time
import praw
from flask import Flask, request, redirect
from twilio.rest import TwilioRestClient
from passwords import *
from twilio import twiml
def login():
r = praw.Reddit(app_ua)
r.set_oauth_app_info(app_id, app_secret, app_uri)
r.refresh_access_information(app_refresh)
return r
r=RUAlertsTwilioWEBSERVER.login()
client = TwilioRestClient(account_sid, auth_token)
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
def AlertService():
TheMessage=request.form.get("Body")
if (TheMessage != None):
print(TheMessage)
client.messages.create(to=ePhone,from_=tPhone,body=str(TheMessage))
r.submit(*submit to reddit code*)
return str(TheMessage)
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0")
The Twilio debugger gives me
Content is not allowed in prolog.
Warning - 12200
Schema validation warning
The provided XML does not conform to the Twilio Markup XML schema.
I tried to get the XML needed for the post by changing my code to the following (Only the relevant part)
#app.route("/", methods=['GET', 'POST'])
def AlertService():
TheMessage=request.form.get("Body")
if (TheMessage != None):
print(TheMessage)
resp = twiml.Response()
XML = resp.say(TheMessage)
client.messages.create(to=ePhone,from_=tPhone,body=XML)
r.submit(*submit to reddit code*)
return str(resp)
return str(TheMessage)
This code didn't work so I changed body=XML to body=str(XML). However now it just sends the XML as the body and I receive the error:
cvc-complex-type.2.4.a: Invalid content was found starting with element 'Say'. One of '{Sms, Message, Redirect}' is expected.
Warning - 12200
Schema validation warning
The provided XML does not conform to the Twilio Markup XML schema.
How can I fix this?
Twilio evangelist here.
<Say> is not a valid TwiML verb to include in response to a request made to a Message Request URL. Its only valid for Voice Requests.
If you want to send a message back to the person who sent the text message to Twilio use the <Message> verb.
resp = twilio.twiml.Response()
resp.message(message)
Also, it looks like you are sending the TwiML as the message of the new outbound SMS message. I think you can replace that with just the Body param.
client.messages.create(to=ePhone,from_=tPhone,body=TheMessage)
Hope that helps.
Related
I have extracted my message history from Twillio - it prints it to python's shell. However, I cannot find a reasonable way to place it into a data structure or a text file for further analysis of the messages. My account sid and account token are hidden just for this post. Nothing is written to my txt file either.
from twilio.rest import Client
account_sid = 'XXXX'
auth_token = 'XXXX'
client = Client(account_sid, auth_token)
from twilio.twiml.messaging_response import Message, MessagingResponse
from flask import Flask, request, redirect
app = Flask(__name__) #creating a flask app
#app.route("/sms", methods=['GET', 'POST']) #creating an sms route
def sms_reply():
"""Respond to incoming calls with a simple text message."""
# Start our TwiML response
resp = MessagingResponse()
# Add a message
resp.message("The Robots are coming! Head for the hills!")
return str(resp)
text = []
messages = client.messages.list()
for record in messages:
text.append(record.body.encode("utf-8"))
My message history:
Sent from your Twilio trial account - Your verification code is: 219042
Test
Twilio developer evangelist here.
As my teammate Phil mentioned above, you seem to be conflating responding to an incoming webhook with hitting the API and fetching message history.
These Twilio docs mention how to retrieve message history in Python.
The following code writes message history to a .txt file called "chathistory.txt".
from twilio.rest import Client
account_sid = 'XXXX'
auth_token = 'XXXX'
client = Client(account_sid, auth_token)
messages = client.messages.list(limit=20)
writetofile = open("chathistory.txt", 'w')
for record in messages:
print(record.body)
writetofile.write(record.body + '\n')
writetofile.close()
Let us know if this helps at all!
New to Twilio, have followed the SMS Python Quickstart guide successfully, and have combined two bits together, but now have some redundant code that I can't seem to get rid of without getting errors.
I have Python code that takes in coordinates from a text message, converts this into a Google Maps link, and sends that link to a different phone number.
However, currently it is also sending this reply to the original sender phone number, as that is what the original guide has you set up.
I only want it to send the message to the specified number, not reply to the original sender.
run.py:
# /usr/bin/env python
# Download the twilio-python library from twilio.com/docs/libraries/python
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client
# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'account_sid'
auth_token = 'auth_token'
client = Client(account_sid, auth_token)
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
def sms_reply():
messages = client.messages.list()
print(messages[0].body)
coord = messages[0].body
lat,lon = coord.split(":")
mapURL = "https://www.google.com/maps/search/?api=1&query=" + lat + "," + lon
message = client.messages.create(
body=mapURL,
from_='+442030954643',
to='+447445678954'
)
"""Respond to incoming messages with a friendly SMS."""
# Start our response
resp = MessagingResponse()
# Add a message
resp.message(mapURL)
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
Whenever I take out the lines I think are to do with the replying message to sender, it seems to break some of the other lines that I still need.
Any help much appreciated, thanks!
Twilio developer evangelist here.
You don't need to reply back to the incoming message and you can avoid this by returning an empty TwiML response.
As an extra win here, you don't have to call the API to get the body of the last message that was sent. That will be available in the POST request parameters to the endpoint. You can access those via request.form so the Body parameter will be available at request.form['Body'].
Try something like this:
# /usr/bin/env python
# Download the twilio-python library from twilio.com/docs/libraries/python
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
# Download the helper library from https://www.twilio.com/docs/python/install
from twilio.rest import Client
# Your Account Sid and Auth Token from twilio.com/console
account_sid = 'account_sid'
auth_token = 'auth_token'
client = Client(account_sid, auth_token)
app = Flask(__name__)
#app.route("/", methods=['GET', 'POST'])
def sms_reply():
coord = request.form['Body']
lat,lon = coord.split(":")
mapURL = "https://www.google.com/maps/search/?api=1&query=" + lat + "," + lon
message = client.messages.create(
body=mapURL,
from_='+442030954643',
to='+447445678954'
)
# Start our empty response
resp = MessagingResponse()
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
It's because your output in your sms_reply function is returning a TwiML that sends a message. I think it's normal to have some feedback from the service. If you don't want to reply with the mapURL you can just say somethink like "Thank you".
Otherwise, you can take a look to TwiML documentation to see what other actions you can do.
I am new to API, and get a tasks of creating POST API. I have created a code somehow.
I want to add data to the hello.txt through post API, So how will I do it?
Here is my code:
import flask
from flask import request, jsonify
app = flask.Flask(__name__)
app.config["DEBUG"] = True
#app.route('/api/v1/resources/messages', methods = ['POST'])
def api_message():
if request.headers['Content-Type'] == 'text/plain':
return "Text Message: " + request.data
elif request.headers['Content-Type'] == 'application/octet-stream':
return "Binary message written!"
elif request.headers['Content-Type'] == 'application/json':
f = open('F:\Asif_Ahmed\Projects\api\hello.txt',"w")
f.write(request.data)
f.close()
return "JSON Message: " + json.dumps(request.json)
else:
return "415 Unsupported Media Type ;)"
app.run()
from flask import Flask, jsonify, render_template, request #import flask library
from flask_basicauth import BasicAuth # import flask library for create basic authentication if needed
from flask_cors import CORS # import flask library Cross-Origin Resource Sharing that is a mechanism that uses additional HTTP headers to tell a browser to let a web application running at one origin (domain) have permission to access selected resources from a server at a different origin
app = Flask(__name__)
CORS(app) #set-up cors for my app
#if you want use basic authentication you need set-up username and password
app.config['BASIC_AUTH_USERNAME'] = 'admin'
app.config['BASIC_AUTH_PASSWORD'] = 'password'
basic_auth = BasicAuth(app)#set-up username and password for my app but in this case I'm not specifying yet in which API use them
#app.route('/api/v1/resources/add_messages', methods=['POST'])#create my POST api
#basic_auth.required# set-up basic authentication for this API, comment out if not needed
def update_credential ():
json_credential=request.get_json()#get the JSON sent via API
print (json_credential["message"])#get the node "message" of my JSON
###########
#code to write in your file, you need write the json_credential["message"]
###########
return ("ok")
if __name__ == '__main__':
app.run(host='0.0.0.0', port=1024, threaded=True)#start my flask app with local_host IP and specific port, if you don't specify the port it will run in the default port
In this case the JSON Input should be:
{"message":"your text"}
Please let me know if something is not clear, I even try this code on my local and the JSON is passed without problems.....
So you need run your python script and see that the API is running, if you had no JSON to send and was just a simple API that give back information you should have used even Chrome but in this case that you need send some JSON data I would advice you to use Postman.
See screenshot example:
Following the Twilio SMS Python Quickstart guide found here:
https://www.twilio.com/docs/sms/quickstart/python
I can get up to the "Receive and reply to inbound SMS messages with Flask" section perfectly fine, with both my http://localhost:5000/ and ngrok URL showing the correct "Hello World" message.
However, as soon as I replace the run.py file code with the instructed code to reply to the sender with an sms, both URLs become dead with a "404 Not Found" error.
Have tried restarting everything etc.
run.py:
# /usr/bin/env python
# Download the twilio-python library from twilio.com/docs/libraries/python
from flask import Flask, request
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
#app.route("/sms", methods=['GET', 'POST'])
def sms_ahoy_reply():
"""Respond to incoming messages with a friendly SMS."""
# Start our response
resp = MessagingResponse()
# Add a message
resp.message("Ahoy! Thanks so much for your message.")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
Any ideas?
As soon as I change the run.py code back to the original "Hello World" code both URLs run fine.
Also, the ngrok server does show an attempted connection when I send an sms message to the twilio number too, but with a "404 Not Found" message next to it.
I'm learning python and as a project I'm trying to create a program that will recieve an SMS message, process it, and then depending on what is in that message, send back information.
I am using Twilio in python with Flask and ngrok to do all the SMS stuff, but I am still not sure how to actually receive an SMS as data that I can read and process, as there is no documentation that I can find on it. It would be great if someone could help me with this.
I already know how to receive and send SMS with Twilio, I just need to know how to get the precise message that was sent to my Twilio number.
I believe you already know how to configure Twilio to hit your endpoint when a message comes in. If you configure at Twilio for a POST request, then the data passed to you from Twilio will be in request.form.
If you take a look at Twilio's example here:
(https://www.twilio.com/docs/sms/tutorials/how-to-receive-and-reply-python)
indeed the example makes no use of the data that is coming in.
The modified code below shows some data that is available from the request (and you can write your code depending on what you'd like to do with it).
the number from where the message was sent request.form['From'],
your Twilio number request.form['To']
and the body of the message request.form['Body']
from flask import Flask, request, redirect
from twilio.twiml.messaging_response import MessagingResponse
app = Flask(__name__)
#app.route("/sms", methods=['POST'])
def sms_reply():
"""Respond to incoming calls with a simple text message."""
# Use this data in your application logic
from_number = request.form['From']
to_number = request.form['To']
body = request.form['Body']
# Start our TwiML response
resp = MessagingResponse()
# Add a message
resp.message("The Robots are coming! Head for the hills!")
return str(resp)
if __name__ == "__main__":
app.run(debug=True)
Some other parameters are also available in the request:
MessageSid
SmsSid
AccountSid
MessagingServiceSid
From
To
Body
NumMedia
Docs: (https://www.twilio.com/docs/sms/twiml#request-parameters)
Also you can find more examples if you google for "twilio blog python flask"