Django-Twilio sending SMS on button click - python

OK possible noob question here: While learning Django, I thought it might be cool to explore telephony with Twilio. My immediate goal is to create a page with a button that, when clicked, causes a "Hello World" SMS to be sent to my phone. After sorting that out I have some ideas for cooler stuff.
I've completed several Django tutorials so far, and made a few little apps with simple views. But nothing I've learned has particularly shed any light on how to do something like this. I've also investigated (and installed) the Django-Twilio app and the Twilio Python Helper Library, but the docs for neither of these show how to send "hello world" SMS's.
Can anyone point out a resource that might show how to do this? Or, if it's trivially easy, just post some example code?
Edit in response to Kevin Burke:
Thanks for getting back to me, Kevin.
After modifying my urls.py to include:
urlpatterns = patterns('',
# ...
url(r'^sms/$', 'django_twilio.views.sms', {
'message': 'Hello world',
'to': '+12223334444',
'sender': '+18882223333',
'status_callback': '/sms/completed/',
}, name = 'send_message'),
# ...
)
and pointing my browser at
http://127.0.0.1:8000/sms/
the following error arises:
Exception Type: TwimlException at /sms/
Exception Value: Invalid method parameter, must be 'GET' or 'POST'
Perhaps this is because I have failed to make appropriate modifications to the view. But I don't have a good way of figuring out what I'm doing wrong from the minimal examples in the tutorial.
/Edit

twilio employee here.
The problem here is that the built in views for django_twilio run through a series of validation checks to make sure they're receiving content from twilio.com and only twilio.com. This is a security measure built into django-twilio.
There are two things you can do:
Make sure your settings.DEBUG = True in your Django settings, this will turn off the validation. You can then send a cURL request on your local machine whilst it is running like this in your terminal:
$ curl http://localhost:8000/sms/
This should return some TWiML like so:
<Response><Sms>Hello world</Sms></Response>
When you're running this online and you want to do to test this, set up your twilio number to point to http://mywebsite.com/sms/ and text the number. Ensure that settings.DEBUG = False and you should get back a message.
If you have anymore problems, let me know.

Here's the official docs: django-twilio official docs. More specifically, read this part about sending SMS: Sending sms messages

Here is a simple solution :
django startproject projectname
urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('message_api.urls')),
]
settings.py
TWILIO_ACCOUNT_SID = TWILIO_ACCOUNT_SID
TWILIO_AUTH_TOKEN = TWILIO_AUTH_TOKEN
DJANGO_TWILIO_FORGERY_PROTECTION = False
DJANGO_TWILIO_BLACKLIST_CHECK = True
Start new application
python manage.py startapp appname
Inside the app folder:`
urls.py
from django.conf.urls import url
import django_twilio
from . import views
urlpatterns = [
url(r'^api/$', views.home),
url(r'^send/', views.sms),
]
views.py
from django.shortcuts import render
from twilio.rest import Client
from twilio_api import settings
def home(request):
return render(request, 'index.html', {})
def sms(request):
client = Client(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN)
message = client.messages.create(to='TO NUMBER', from_='YOUR TWILIO NUMBER', body='This message is sent through twilio api using django framework by akshat.')
print(message.sid)
return render(request, 'thankyou.html')
Make a templates directory inside your app folder
index.html
<body>
<button class="btn btn-outline-primary">Send Message</button>
</body>
thankyou.html
<body>
<h1>Success</h1>
</body>
`

Related

DRF does not reverse Django url pattern: NoReverseMatch

There is a complex app (not possible to just paste the code). Going to try to explain.
Django
There is a urls.py file from the native Django app. The urlpatterns defines and register its urls. The ^foo/ defines a group of related urls and the foonamepsace.
urlpatterns = patterns('',
...
url(r'^foo/', include('foo.urls', namespace='foonamespace')),
...
Now there is a method generate_report which does some logic inside and then uses render_to_string to return the HTML:
def generate_report(..):
...
return render_to_string('foo/foo_report.html', args)
Everything works inside the app, the url get reversed successfully.
Django Rest Framework (DRF)
Now there is a DRF implementation and one of its resources is supposed to return a report in a binary format.
class PDFReportViewSet(APIView):
renderer_classes = (BinaryFileRenderer, )
def get(..):
...
pdf = generate_report() # <-- fails with NoReverseMatch
...
return response
Problem
The ViewSet calls the generate_report, however one gets an error when trying to parse the HTML:
NoReverseMatch: foonamespace' is not a registered namespace
Question
Any clues why DRF cannot reverse the namespcae/url from the the core of Django app? How to make sure DRF can reverse a namespace from the core urls.py urlpattern?
Added
After investigation, inside the foo_report.html any usage of the url, for example {% url 'foonamespace:123' %} or {% url 'barnamespace:123' %} produces the error - only if ran from the DRF (running the same page using native Django works fine).
URLS
foo.urls.py
from django.conf.urls import patterns, url
from foo.views import (FooListView, FooDetailView...)
urlpatterns = patterns('',
url(r'^$', FooListView.as_view(), name='foo_list'),
url(r'^(?P<pk>\d+)/$', FooDetailView.as_view(), name='foo_details'),
Important note. The app is served at some.domain.com/, while the REST is served from some.domain.com/rest. So may be this way /rest just don't include anything because it is a parent of the root (which includes the foo.urls.py)
I was managed to resolve my issue with the help from #dirkgroten. It was difficult to see the problem without looking at the source code.
Solution
Updated the routers.py file:
urlpatterns = router.urls
urlpatterns += patterns('',
url(r'^foo/', include('foo.urls', namespace='foonamespace')),
)
Explanation
Basically, the app was serve from the root url / while the rest was served from /rest. The DRF router simply didn't include any of the root routes. Adding them manually like it is shown in solution resolved the problem and made foonamespace visible for all DRF elements.

Django2 not connecting to Local Host

I'm new to Django/Python. I'm currently taking a beginners course and I'm having difficulty setting up my URLs and connecting to a local server. I'm using Python version: 3.7.0 and Django v.2
The command line does not give any errors (0), it tells me to go here:
Starting development server at http://127.0.0.1:8000/
Which I believe is the local host, however the site says
This site can’t be reached
127.0.0.1 refused to connect.
Can anyone let me know what I'm missing I would greatly appreciate it so that I can continue on with my studying. I'm using tutorials on YT Django Tutorial and the guy is using an older Django so I think that may be why I'm having trouble. He says we should still be okay to follow through even on the new version of Django.
urls.py
from django.contrib import admin
from django.urls import path
from.import views
urlpatterns = [
path('', views.homepage),
path('admin/', admin.site.urls),
path('about/', views.about),
]
views.py
from django.http import HttpResponse
def homepage(request):
return HttpResponse('homepage')
def about(request):
return HttpResponse('about')
Got it to work. This is what was needed:
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
Took me forever to figure this out. :)
There is a little modification is required in your code:
Instead of path('about/', views.about),
write this:
path('about/', views.about,name='about'),
after modify this line , run the server and open this http://127.0.0.1:8000/ URL and add /about and then press enter.
http://127.0.0.1:8000/about
Hope it will work in your case

Django Custom error page's giving error

I'm trying to make custom error page general 404 and 500.
I'm not trying to raise just making a default if it happens for a user, but every place I'm trying to search and follows a tutorial and so on I always ends up in getting an internal error on both 500 and 404
I'm running django=1.11.6, and I'm running debug False because I need to see if it work of course.
How can I fix this issue and make it work?
And how can I make it so it also gives the user the error text so they can send it to me?
Views.py (In my app folder)
# Error Handlers
def handler404(request):
return render(request, 'handlers/404.html', status=404)
def handler500(request):
return render(request, 'handlers/500.html', status=500)
Urls.py (in my main config folder)
from django.conf.urls import include, url, handler404, handler500
from django.contrib import admin
handler404 = 'staff.views.handler404'
handler500 = 'staff.views.handler500'
urlpatterns = [
url(r'^', include('staff.urls')),
url(r'^admin/', admin.site.urls),
]
Firstly, you don't need custom handlers if you just want to use your own templates - just put your own 404.html and 500.html files in your root templates directory.
Secondly, rather than getting users to send you the error codes manually, you can configure Django to send you errors by email.

custom handler404 => standard error page

When I try to use my own view for error 404, I instead get a standard error page. So, what I've done by now:
# root settings.py
DEBUG = False
ALLOWED_HOSTS = [
'*'
]
# blog urls.py
handler404 = 'views.custom_404'
# blog views.py
def custom_404(request):
return HttpResponse("Hello world, I'm a custom error 404")
And, besides, to try it locally on Django test server, I run it like this:
python manage.py runserver --insecure
But what I get when I go to some page which does not exist is:
Not Found
The requested url blablabla
So, for some reason I do not see my own message Hello world, I'm a custom error 404.
404 handlers are not per app, they can only be set from the main urls.py.

Django url parameter passing

I am not even sure what category in Django this question falls in and I am very new to django. I have tried looking for Django post requests, parameter passing and even checked under Django APIs but have not found what I am looking for. What I am trying to do is create an API for my client but it must be done in Django. If I was to do this in .Net I could use http post and http get and web services but I am not at all sure how this is done in Django. What my client wants to do is to be able to see:
Enter username and password in url with parameters for date and id and be able to view rooms available based on what is entered
Enter username, password and dates and room code to be able to book the room
No interface needed just simple parameter passing through url. Is this possible with Django and if yes can somebody please point me in the right direction.
What you're looking for are captured parameters
Below is a code snippet from the above link.
# urls.py
from django.conf.urls import patterns, url
urlpatterns = patterns('blog.views',
url(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
)
# views.py
def year_archive(request, year, foo=None):
# view method definition
As of Django 1.10, patterns was removed from Django.
Here is a 2019 Django 2.2 solution.
It looks like re_path is the current recommended tool for capturing parameters via regular expressions:
https://docs.djangoproject.com/en/2.2/ref/urls/#re-path
# urls.py
from django.urls import re_path
from myapp import views
urlpatterns = [
re_path(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
]
# views.py
def year_archive(request, year, foo=None):
# view method definition

Categories

Resources