What you need to know — Python; Django🙂let’s start🙂
1. First things first — Facebook App & its page!
To build a Facebook messenger bot, we must first create a new Facebook app. To do this, lets head to the Facebook developer site, create a new app and fill out the relevant details to get our App ID. You can select “Apps for Messenger” as its category. This will prepopulate the required products for the app in the dashboard.
You should be redirected to the dashboard that looks like this.
Next, our app must be associated with a Facebook page since it is the page that interacts with the users. If you don’t already have a page, go ahead and create one. You can spice up your page with pictures and relevant details or you can leave it as is for now. The page doesn’t have to be published for the bot to work.
To access the Facebook messaging API, our app will need a page access token. Go ahead and click on the “Messenger” tab on the control panel under “Products”. Then, select the page that the app will link to and a token will be generated. This token will later be used by your app to send messages to users!
2. Django server setup
This tutorial shows you how to use Django as the backend server. This can be replaced by any other framework.
Lets create a new virtual environment, install Django, create a new project and run the development server.
$ mkvirtualenv yomamabot
$ pip install django
$ django-admin.py startproject yomamabot
$ cd yomamabot
$ python manage.py runserver
Now you must have your django server running at 127.0.0.1:8000
. Go to the URL and you must see the “It worked!” page. Django projects are made up of small apps that perform specific functions. So lets create an app for our Facebook messenger bot by running
$ django-admin.py startapp fb_yomamabot
This must now create an app in the project directory with the relevant files. Go to the settings.py
file and add this app by appending the app name ‘fb_yomamabot
‘ into the INSTALLED_APPS
variable.
# yomamabot/yomamabot/settings.py
# ..... other settings .....INSTALLED_APPS = [
'django.contrib.admin',
# ...
'django.contrib.staticfiles',
'fb_yomamabot',
]
Next, lets set up the URLs. In the main urls.py
file, add this line.
# yomamabot/yomamabot/urls.py
from django.conf.urls import url, include
from django.contrib import adminurlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^fb_yomamabot/', include('fb_yomamabot.urls')),
]
This means, when a request like 127.0.0.1:8000/fb_yomamabot/<rest-of-the-url>
comes to the server, it strips away 127.0.0.1:8000/fb_yomamabot/
and forwards <rest-of-the-url>
to the urls.py
file in the fb_yomamabot
app directory to handle it. So lets create a urls.py
file in our fb_yomamabot
app directory and leave it empty for now.
# yomamabot/fb_yomamabot/urls.py
from django.conf.urls import include, url
urlpatterns = []
3. Webhook — time for your app and Facebook to hook up!
“A webhook is a way for an app to provide other applications with real-time information.” In this case, Facebook provides our app with real-time information i.e. whenever someone sends our page a message.
The first part is to decide exactly “where” our app and Facebook should “hook up”! Lets create a URL and tell Facebook about it so it can send updates there. Later, we can write code to handle these incoming requests. Keep in mind that we want this URL to be secret, unless you want intruders to know where we hook up!
Generate a long random sequence for our url. In a python interpreter, run this
import os, binascii
print binascii.hexlify(os.urandom(25))
Here is one such sequence, 66d2b8f4a09cd35cb23076a1da5d51529136a3373fd570b122
. Lets define our webhook URL in urls.py
file and create a view to handle it
# yomamabot/fb_yomamabot/urls.py
from django.conf.urls import include, url
from .views import YoMamaBotView
urlpatterns = [
url(r'^66d2b8f4a09cd35cb23076a1da5d51529136a3373fd570b122/?$', YoMamaBotView.as_view())
]
To ensure everything is working well, update our views.py
file to look like this
# yomamabot/fb_yomamabot/views.py
from django.views import generic
from django.http.response import HttpResponse
# Create your views here.
class YoMamaBotView(generic.View):
def get(self, request, *args, **kwargs):
return HttpResponse("Hello World!")
Now when you go to the following URL, you should see “Hello World!”.
http://127.0.0.1:8000/fb_yomamabot/66d2b8f4a09cd35cb23076a1da5d51529136a3373fd570b122
Next, we have to tell Facebook about our webhook and specify the URL. However, Facebook can only access web URLs. Since we are working locally, Facebook cannot reach us. Also, Facebook requires the endpoint to run over https
!
Ngrok to the rescue!
For development purposes, we will use Ngrok that sets up secure tunnels to our localhost i.e. Ngrok gives web accessible URLs and tunnels all traffic from that URL to our localhost! Easy, peasy! Go to Ngrok’s download page, download the zip file, unzip and simply run the command
ngrok http 8000
This should open up a terminal panel that looks like this. Ngrok also provides a neat web interface at 127.0.0.1:4040
to look at all the requests that are coming in!
Its that easy! Now any outside computer can reach your localhost server at https://36096fff.ngrok.io
which means so can Facebook! So lets set up the webhook for Facebook. Go to your app dashboard and click on Messenger (where you created your page access token previously). Click on “Setup Webhooks” right below “Token Generation” and fill the details as shown.
Note: In Django 1.10+, make sure you add the ngrok url to “ALLOWED_HOSTS” list in your settings.py
file. For this example, ALLOWED_HOSTS = ['36096fff.ngrok.io']
The “Verify Token” can be any value you wish. This is what Facebook will send along with a challenge token. Your server should make sure the “Verify token” matches and respond back with the challenge token. If you click on “Verify and Save” now, it won’t work because our server currently responds with a string “Hello World!”. Lets update our views.py
file.
# yomamabot/fb_yomamabot/views.py
class YoMamaBotView(generic.View):
def get(self, request, *args, **kwargs):
if self.request.GET['hub.verify_token'] == '2318934571':
return HttpResponse(self.request.GET['hub.challenge'])
else:
return HttpResponse('Error, invalid token')
Now click on “Verify and Save” and your webhook is setup! You should see the green tick. Next, select the page you want your app to be subscribed to and click on Subscribe. Facebook will now push any page events, in real time, to the URL you just created as POST requests.
(Initial release expected you to manually send a POST request with your Page access token using curl to subscribe your app to page events)
4. Send and Receive messages
Now that you are subscribed, Facebook will make POST requests every time the selected page event is triggered. Here is a brief description of what each even means. Feel free to look at the full API reference for more details.
messages
– This is the primary type of event we will be interested in. This event is triggered every time someone sends your page a message.message_deliveries
– Delivery reports for the messages you send.messaging_postbacks
– Facebook allows you to send more than text. It allows templates with buttons that, upon being clicked/tapped, can send the specified payload back to your webhook.
A simple example is a template with 2 buttons to subscribe or unsubscribe. When the user taps any of them, the postback event is triggered and Facebook sends the payload you set for the button, back to you.messaging_optins
– This is used for authentication and is trigged when someone uses Facebook’s Send-to-Messenger Plugin that may reside on your website as an entry point.
For this simple toy example, we will restrict ourselves to handling only messages
. Now lets write some code to simply echo a users message back.
Receive a message — First, in our views.py
, lets update the post
function to print the received message. Since django POST methods require csrf tokens by default, lets exempt the dispatcher method to handle Facebook callbacks. Update your views.py
as shown below.
# yomamabot/fb_yomamabot/views.py
# import required modules
class YoMamaBotView(generic.View):
# The get method is the same as before.. omitted here for brevity
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return generic.View.dispatch(self, request, *args, **kwargs) # Post function to handle Facebook messages
def post(self, request, *args, **kwargs):
# Converts the text payload into a python dictionary
incoming_message = json.loads(self.request.body.decode('utf-8'))
# Facebook recommends going through every entry since they might send
# multiple messages in a single call during high load
for entry in incoming_message['entry']:
for message in entry['messaging']:
# Check to make sure the received call is a message call
# This might be delivery, optin, postback for other events
if 'message' in message:
# Print the message to the terminal
pprint(message)
return HttpResponse()
Now open your Facebook page, click on message and type something. If everything goes well, it should look like this
Send a message — To send messages, you need to make POST calls using Facebook’s Graph API using your page access token. The json body will include the user’s id and the message payload. You can simply send text or use templates with images, lists, links etc. For details, look at Facebook’s Send API reference. For our toy project, we will only send back text.
To echo the recevied text back, we will use the excellent requests
package to make POST calls. Lets create a simple helper function that will make this POST call with the received text.
# yomamabot/fb_yomamabot/views.py
# This function should be outside the BotsView class
def post_facebook_message(fbid, recevied_message):
post_message_url = 'https://graph.facebook.com/v2.6/me/messages?access_token=<page-access-token>'
response_msg = json.dumps({"recipient":{"id":fbid}, "message":{"text":recevied_message}})
status = requests.post(post_message_url, headers={"Content-Type": "application/json"},data=response_msg)
pprint(status.json())
Now in our post
function, below the pprint(message)
line, call this function with the sender id and the received message.
# yomamabot/fb_yomamabot/views.py
def post(self, request, *args, **kwargs):
# .....code omitted for brevity......
if 'message' in message:
# Print the message to the terminal
pprint(message)
# Assuming the sender only sends text. Non-text messages like stickers, audio, pictures
# are sent as attachments and must be handled accordingly.
post_facebook_message(message['sender']['id'], message['message']['text'])
Go ahead and try it out. Send a few messages and it should echo back!
5. More than echo!
Now that we have out end to end pipe line set up, we can go ahead an start implementing some basic functionality into the bot. Since our bot is supposed to tell Yo Mama jokes, lets create a simple dictionary (for now) that has some jokes indexed by category.
jokes = {
'stupid': ["""Yo' Mama is so stupid, she needs a recipe to make ice cubes.""",
"""Yo' Mama is so stupid, she thinks DNA is the National Dyslexics Association."""],
'fat': ["""Yo' Mama is so fat, when she goes to a restaurant, instead of a menu, she gets an estimate.""",
""" Yo' Mama is so fat, when the cops see her on a street corner, they yell, "Hey you guys, break it up!" """],
'dumb': ["""Yo' Mama is so dumb, when God was giving out brains, she thought they were milkshakes and asked for extra thick.""",
"""Yo' Mama is so dumb, she locked her keys inside her motorcycle."""]
}
Next, lets update our post_facebook_message
function to search for one of the three keywords and send a joke to the user. If the keyword is absent, it’ll respond with a failure.
# yomamabot/fb_yomamabot/views.py
def post_facebook_message(fbid, recevied_message):
# Remove all punctuations, lower case the text and split it based on space
tokens = re.sub(r"[^a-zA-Z0-9\s]",' ',recevied_message).lower().split()
joke_text = ''
for token in tokens:
if token in jokes:
joke_text = random.choice(jokes[token])
break
if not joke_text:
joke_text = "I didn't understand! Send 'stupid', 'fat', 'dumb' for a Yo Mama joke!"
post_message_url = 'https://graph.facebook.com/v2.6/me/messages?access_token=<page-access-token>'
response_msg = json.dumps({"recipient":{"id":fbid}, "message":{"text":joke_text}})
status = requests.post(post_message_url, headers={"Content-Type": "application/json"},data=response_msg)
pprint(status.json())
Now when you chat, it will look like this.
6. A personal touch!
You can use Facebook’s API to query basic user information from the user id. You can get the user’s first name, last name and a link to their profile pic. Append the following code soon after the joke_text
is set.
# yomamabot/fb_yomamabot/views.py
def post_facebook_message(fbid, recevied_message):
# ...... code that selects and assigns the joke_text .... user_details_url = "https://graph.facebook.com/v2.6/%s"%fbid
user_details_params = {'fields':'first_name,last_name,profile_pic', 'access_token':'<page-access-token>'}
user_details = requests.get(user_details_url, user_details_params).json()
joke_text = 'Yo '+user_details['first_name']+'..!' + joke_text # ..... code to post message ...
Now the bot uses the user’s name in every text as seen below.
You are almost done!!!!!
7. What next?
Test, Test, Test!
While your bot approval might take several weeks, you don’t have to wait for that time to have real users interacting with your bot! You can add test users from your dashboard. Go to your “Roles” tab from the dashboard and then click on “Add testers”. You can now add anyone who is your Facebook friend. For users who aren’t but are interested to test your bot, you can add them using their fbid (numeric id) or their username. A Facebook username is NOT the display name. You can get it from the URL of the person’s profile page.
8. Submit for approval
Once you are happy with your application, deploy it onto your servers. Since https
is a requirement, you could either buy a certificate or use letsencrypt
to get a free one. Here is a tutorial from Digital Ocean on how to obtain an SSL certificate with letsencrypt and turn on https for nginx.
Then you can submit your app to Facebook for approval! Head to the Messenger tab and click on “Request permissions”. For messenger bots, your app at least needs the “pages_messaging” permission.
Once you select the permissions and Add them, you will be redirected to the App Review tab. If you have a red exclamation as shown below, it means that your app is currently ineligible for submission.
For the App details, at a bare minimum, you will need an App Icon and a privacy policy URL. You can submit any 1024×1024 image for your App icon and you can use an excellent service by IUbenda that generates Privacy policies for Facebook apps. Once you, enter this, head to the App Review where you should click on Edit Notes and fill out the details to submit your app for approval.
For the approval process, you must agree to their terms which includes not spamming your users with ads and promotional offers (understandable!) and submit a screencast of interaction with your bot.
9. Some tips.!
- Facebook provides a bot engine called Wit.ai that parses input text and converts it into structured information that you can then use to set responses. There are also several commercial and non-commercial information extraction software that could be used to this end. You could also use free NLP tools like NLTK, Stanford coreNLP and build your own query processor.
- Move away from words and use word vectors instead! Funny and Joke are two unrelated words for a computer if it is just text. So are words like stupid and dumb. Using word vectors from Google’s word2vec or Stanford’s GloVe, you can capture the relative closeness between any two words which eases the constraint on users to use the exact word a bot expects!
That’s it…………..!!!!!
I have written the same article on Medium as well.
If you also wish to share your knowledge with the TheCodeSpace fam kindly share your thoughts/article on rajparmar2308@gmail.com.
I have read so many posts about the blogger lovers however this post is really a good piece of writing, keep it up
http://slkjfdf.net/ – Iqajto Uzifumaf xpk.udcx.thecodespace.in.jrl.kx http://slkjfdf.net/
http://slkjfdf.net/ – Uxayoxif Uzepipj ycv.dibg.thecodespace.in.xnb.mc http://slkjfdf.net/
http://slkjfdf.net/ – Ocivujal Ifeviyiwa vem.gqju.thecodespace.in.oad.gb http://slkjfdf.net/
http://slkjfdf.net/ – Uuvuvawca Uokepew wxb.oyhr.thecodespace.in.htx.vj http://slkjfdf.net/
https://www.philadelphia.edu.jo/library/directors-message-library
fildena buy
how to get viagra gabapentin online pharmacy synthroid 88 mcg levitra best price
doxycycline capsule 100mg price
austria pharmacy online albuterol hfa inhaler cheap generic levitra
mypharmacy
viagra woman
aurogra 100mg tablets
vardenafil over the counter buy provigil 200 mg order cialis online in canada lasix 40mg robaxin/methocarbamol 500mg 06 tretinoin where to purchase azithromycin how much is strattera 10mg
canadian pharmacy online store
cost of strattera 40 mg
synthroid best price lasix prescription diflucan us
hq pharmacy online 365
clonidine medicine
buy fildena 100mg
synthroid 200 mcg tabs
dexamethasone 12 mg furosemide tablets uk
neurontin 800 mg tablet
albendazole 400 mg price in india colchicine uk ventolin tabs 4mg sildenafil 1.5 strattera 80 mg cost buy synthroid 0.0125 online lasix online 100 mg lisinopril
aurogra 200 where can you get doxycycline generic valtrex sale
best online pharmacy reddit
amoxicillin price in usa
buying albendazole online without a prescription
robaxin gold
pharmacy wholesalers canada
viagra non prescription
clonidine tablet price propranolol 5 mg coupon 90 furosemide lasix 100mg can you buy azithromycin over the counter in canada
buy cialis 100mg
online pharmacy birth control pills
5mg prednisone daily
colchicine 0.6 mg tablets
vardenafil 10mg tablets
antabuse price
prednisolone tablets buy online
mexico pharmacy order online buy furosemide 40 mg albuterol pills online dexamethasone 1.5 tablet generic for robaxin buying provigil in mexico order clonidine online zovirax online india
where to buy diflucan without prescription
zyban tablets cost where to get propecia in south africa synthroid purchase colchicine 500 mg tablets azithromycin 250mg coupon cheap combivent online pharmacy uk
clonidine capsule amoxil capsules 500mg furosemide 40 for sale canadian pharmacy prices southern pharmacy canadian pharmacy viagra 50 mg cheapest pharmacy to fill prescriptions without insurance
where to buy synthroid
gabapentin 800 mg pill
purchase doxycycline 100mg
cymbalta rx
where can you buy cipro
fildena 100 mg tretinoin 05 coupon lisinopril 12.5 synthroid 188
dexamethasone 0 5 mg
levitra canada online
where can i buy levitra without prescription
order lasix without a prescription
cost of zoloft 50 mg
canadian pharmacy sildenafil
lisinopril pill 40 mg
synthroid 100 mcg daily female viagra nz cheapest prescription pharmacy valtrex no prescription kamagra uk jelly acyclovir cream to united states
how to get neurontin
buy generic levitra 10mg
levitra 10 mg for sale
robaxin 500 mg generic
acyclovir 250 mg tablet
buy generic viagra online in usa
diflucan 200 mg price
albendazole 400
zovirax prescription cost world pharmacy india buy tadalafil online paypal fildena cost generic sildenafil cost buy fildena india can you buy antabuse over the counter
ventolin hfa 90 mcg
flomax sale mexican online mail order pharmacy canadian pharmacy meds buy prednisone from india
international online pharmacy
clindamycin phosphate topical
medicine baclofen 10 mg
albendazole 400 mg buy online from india
lyrica price canada
137 mg synthroid
order levitra over the counter
buy online viagra tablets in india
happy family rx zovirax genital herpes mexican pharmacy what to buy cheap prednisone online buy baclofen nz
pharmacy online australia free shipping
presnidone without a prescription
seroquel online professional pharmacy seroquel cost canada
viagra pills over the counter canada
buy augmentin online nz can you buy viagra otc generic albenza cost
zoloft 100mg price in india
cheap accutane online motilium pharmacy buy metformin 1000 mg drug robaxin 500mg lyrica 300 mg for sale gabapentin 400 mg price metformin 20 mg
generic prednisone without prescription
doxycycline prescription discount neurontin 800 mg capsules lasix drug brand name affordable pharmacy provigil 200 mg generic prednisone 12 mg reputable indian pharmacies
where to buy motilium
levitra best price
online modafinil prescription
baclofen otc 10mg ivermectin 1 where to buy accutane doxyhexal colchicine 1 mg tab 800 mg lyrica safe generic viagra
zovirax cream for genital herpes
ivermectin prescription
prazosin 8 mg 6 mg 8 mg
cheapest online sildenafil
best buspar generic
clonidine 0.1 mg tablet buy accutane in canada motilium 10 metformin buy australia seroquel 50 mg coupon how to buy viagra online in canada where to buy gabapentin
amoxicillin pill 500 mg
prednisolone cheap
canadian pharmacy cialis
medication lisinopril 5 mg
non prescription medicine pharmacy
zovirax cream 10g
doxycycline prescription discount
zovirax otc
amitriptyline 100 mg tablet price
gabapentin in canada
lexapro 10 mg price
prinivil 20 mg tablet
clonidine hcl 0.2mg buy metformin no prescription
buy discount levitra
prednisone 20 mg tablets
accutane canada cost
sildenafil 20 mg tablet brand name
tetracycline cream uk
dipyridamole aspirin azithromycin 250 mg price in india purchase azithromycin 500 mg tablets
ventolin for sale
I have read so many posts about the blogger lovers however this post is really a good piece of writing, keep it up
prices of metformin
zithromax for sale usa
buy generic viagra online in usa
buy diflucan without script
legitimate canadian online pharmacies
sildalis online
colchicine capsules cost for metformin
generic viagra in canada seroquel buy online where to buy prednisone online
motilium otc australia price for 5mg cialis how to get baclofen propecia buy usa tetracycline pills canadian pharmacy coupon
buspar 10 mg tablets
canadian pharmacy cialis 20mg
dexamethasone 4 mg tablet buy online generic cephalexin 500mg lisinopril 10 mg price
buy doxycycline south africa
albuterol canadian pharmacy amoxicillin prescription price robaxin 500mg cost colchicine 0.6 mg for sale valtrex 1g price
colchicine 6 mg price
which pharmacy is cheaper
where to buy diflucan pills
cheap neurontin
legal online pharmacy
cost of gabapentin 800 mg
clonidine 0.2 mg
prednisolone 0.5
pharmacy synthroid 50 mcg india retin a .1 cream
cipro cream
my canadian pharmacy
robaxin 800 mg
metformin price canada prednisolone 10 mg albendazole tablets 400 mg online pharmacy price checker
doxycycline 100mg tablet
cymbalta duloxetine hydrochloride
finasteride online usa
Excelente informaciĂłn, considero que una buena gestiĂłn ayuda a la notoriedad de la marca.
how to get cialis prescription
buy colchicine over the counter
dexamethasone 75 mg tablet
retin a moisturizer where to buy generic propecia cheap zithromax where to buy disulfiram
buy valrex online
cheap strattera online cephalexin 600 cheapest pharmacy to fill prescriptions with insurance clonidine brand name australia
levitra how to purchase over the counter generic robaxin from canada augmentin generic brand name
gabapentin cost of
propecia online prescription uk
amoxicillin online usa
cheap propecia 5mg
metformin price australia
pharmacy online uae
straterra order tretinoin buy india clonidine 0.15 mg levitra 50mg price albuterol inhalers
cipro medication over the counter
buy retin a cream cheap online
where can you buy prednisone
cheap propecia 1mg online pharmacy in turkey viagra 100mg buy online prednisolone 15 metformin 10 tablet azithromycin price in india zithromax 250 buy generic levitra in usa
can i buy cialis in canada vardenafil generic levitra combivent respimat inhaler buy cialis soft tabs online over the counter lisinopril
generic 10mg cialis
buy albuterol pills
seroquel no rx dexamethasone 1 tablet buy ventolin online nz medication robaxin 750 diflucan 200mg colchicine medication metformin 1 mg
clomid 100mg without prescription
can you buy gabapentin online
how to get neurontin cheap neurontin cap 300mg
buy metformin online pharmacy
no prescription prednisone
amoxicillin 875 mg metforfim without a prescription cephalexin 50 mg flomax blood pressure
colchicine 1 mg tab online prescription free zoloft northern pharmacy albuterol 0.41
brand name clonidine prescription
mail order pharmacy no prescription strattera 40 how to get antabuse prescription flomax coupon
albendazole tablets cost in india
40 mg levitra
neurontin 200 mg tablets zithromax 500mg australia online levitra sales pharmacy delivery cheap diflucan online
where can you buy diflucan over the counter
can you buy gabapentin otc
azithromycin 2 pills
amoxicillin 500mg price in canada over the counter propecia metformin australia
how to buy lyrica online clonidine generic cost azithromycin 600 mg tablet rx
retin a cream over the counter australia
neurontin 1200 mg
buy generic strattera online
strattera price uk where to get cialis over the counter robaxin price where to buy valtrex over the counter amoxicillin 825 mg
flomax pill
where to buy diflucan online
can you buy zoloft
ciprofloxacin tablet brand name
zestril 10 mg
buy valtrex online uk where to buy lisinopril online
20 mg zoloft
cafergot no prescription
buy propecia pills
gabapentin 600 mg capsule
methocarbamol robaxin 500mg
dexamethasone 3 mg
modafinil where to buy usa
lisinopril without an rx
ez pharmacy
lyrica medicine price
cheap fildena
order zovirax pills
can you order valtrex online
renova tretinoin cream 0.02 propranolol 120 capsule prednisolone tablets price buy ciprofloxacin robaxin 1700mg buy antabuse online zithromax cost 400mg modafinil
purchass of prednisolone tablets fildena buy tretinoin cost canada zovirax price nz online lisinopril synthroid 0.5 mcg robaxin for sale augmentin 825 mg 125mg
antabuse medication over the counter
online prednisone
lyrica 150 mg price viagra no prescription lyrica discount
robaxin generic south africa cipro flagyl prednisolone tablets 4mg cheap viagra online canadian pharmacy acyclovir cream india baclofen 25 mg
synthroid coupon
fildena 50
tretinoin gel cream
best online pharmacy no prescription
canadian pharmacy ltd
happy family pharmacy canada
pharmacy online 365
600 mg gabapentin coupon
amoxicillin 2g
generic cialis canada canadian pharmacy 365 buy valtrex usa over the counter neurontin gabapentin 1800 mg where to get viagra in usa
generic cialis 20 mg
furosemide 10 mg tadalis sx soft which online pharmacy is reliable augmentin tablets 1g augmentin 500mg coupon pharmacy gabapentin
can you buy colchicine over the counter in australia
buy albenza canada pharmacy in canada for viagra colchicine over the counter usa
cipro 5 mg
buy metformin online canada
accutane uk
albuterol 0.5
azithromycin 1000 mg tablets
lyrica 75 mg price
diflucan otc canada
dexamethasone sale
cipro price canada
gabapentin 30 mg capsules
zestril medication
augmentin 375 mg tablet
generic lasix online
azithromycin 787
where can i purchase metformin 1000 mg buy acyclovir cream online cheap diflucan canada online
ciprofloxacin 750 mg price
can i order lisinopril online
generic cialis for sale in usa
where can i buy gabapentin
cephalexin online canada
zoloft 225 synthroid prescription cost
generic acyclovir online
lisinopril comparison
zoloft 400 mg compare pharmacy prices cheap generic cialis 5mg
prednisone 20 mg online buy tretinoin 0.1 can i buy colchicine without a prescription buying antabuse online price of clomid buy robaxin without prescription with visa
buy neurontin uk
clonidine order
synthroid 75 mcg lowest price
order neurontin online
where to buy albuterol
clonidine 167 cost ventolin australia pharmacy discount coupons
synthroid tab 137 mcg foreign pharmacy online lyrica australia albuterol 117 mcg tretinoin 0.009 buy levitra without prescription prednisone 50 mg buy
gabapentin generic brand
prednisolone without prescription
cheap scripts pharmacy fildena 100 online india zovirax topical cream lasix price uk diflucan online purchase
gabapentin 200 mg tablets
otc propranolol clomid 50 mg for sale antibuse uk pharmacy gabapentin for sale buy valtrex in mexico colchicine 0.6 mg tablet price
amoxicillin mexico buy
megalis 20 for female in hindi
express pharmacy
pharmacy store
can you order cipro online
generic levitra from canada
cost of prednisolone uk
cheap fildena
erythromycin 50 mg cost
acyclovir 400 mg cost
tretinoin otc
bactrim 960 fildena in india prozac 40mg tablet drug tizanidine 4mg buy viagra new york azithromycin canadian pharmacy to us
propecia canadian pharmacy
wellbutrin australia
desyrel for sleep
where to buy cephalexin
propeciaoffers.com lexapro 10mg price in india where to get orlistat buy ampicillin no prescription buy acyclovir from mexico
ivermectin tablet 1mg
viagra canada fast shipping baclofen 20 mg price
buy tretinoin cream
generic viagra 200
arimidex tablets price
buy cheap doxycycline
where can i get clomid online
tretinoin 1.0
propranolol coupon fluoxetine prozac 20mg clomid over the counter uk zanaflex over the counter buy discount viagra online synthroid 150 mg coupon 1500mg amoxicillin
cheap amoxicillin 500mg online
celebrex 100 tablet
tizanidine generic buy diflucan medicarions compare prices of generic levitra cafergot price citalopram hbr tabs 40mg
erythromycin price in india
buy motilium nz
sildalis
where to buy sildalis
clopidogrel cost uk
cost of proscar
cheap cialis online australia
sildalis 120 mg
erythromycin cream buy online
whoah this blog is wonderful i really like reading your articles. Keep up the great paintings! You realize, a lot of people are hunting round for this info, you could help them greatly.
plaquenil medicine
buy erectafil
clindamycin rx
priligy over the counter usa
buy modafinil pills
provigil india
cheap cytotec online generic acyclovir bactrim tablet online orlistat canada cost
erectafil 5mg
doxycycline 2984 malegra dxt tablets
erectafil 40
azithromycin tablet price in india purchase metformin online buy ventolin over the counter australia erythromycin over the counter best generic finasteride brand can you buy zovirax cream over the counter in canada
metformin 2
fildena 200
motilium otc usa proair albuterol levitra buy online pharmacy buying levitra online from canada diclofenac gel brand name zanaflex online india best celexa generic
generic sildalis
acyclovir cream for sale
where to buy arimidex in india
plavix 175 mg
buy xenical nz
xenical without prescription online pharmacy 365 propecia cost rx albuterol where can i get metformin in south africa fluoxetine online cheap medication amoxicillin 500mg acyclovir australia
arimidex over the counter
where to buy cialis uk
avana 2
vardenafil uk tizanidine 4mg tab price albendazole buy online uk malegra dxt
generic tadalafil usa
baclofen 300 mg
tizanidine 2mg tablet price in india
generic diflucan 150 mg
diflucan 750 mg
buy priligy australia
discount sildalis 120mg
synthroid medicine
levitra buy online pharmacy where can i buy oral ivermectin malegra 120 mg doxycycline online canada without prescription albendazole tablets 400 mg price clindamycin 75mg tablets viagra 50mg price in india online cephalexin tablets 300 mg
where can i buy diflucan online
clopidogrel cost
cafergot canada
buy albuterol pills zanaflex muscle relaxer
trazodone 250 mg cost
valacyclovir valtrex
buy modafinil in us cheap acyclovir online inderal 10 mg tablet for sale online clomid medicine price retino 0.25 erythromycin 333 mg capsules retin a pill cost can you cut seroquel xr in half
stromectol cvs
buy retin a cream online australia clopidogrel 75 mg brand name flomax 400 mcg purchase gabapentin online propecia medicine price buy baclofen canada tadalafil online nz cheap prescription nexium
bupropion buy uk how can i get modafinil 02 retin a disulfiram pill gabapentin price in india prednisone 5 mg tablet rx 10mg baclofen tablet
where can i where to buy cafergot for migraines
prazosin online 500 mg gabapentin
provigil online cheap
propranolol online india 10mg
lisinopril brand name in india
gabapentin 216
levitra buy online usa
buy clomid from india
where can you buy viagra in canada
levitra cost in canada
generic nexium 40 mg cost
canadian cialis cheap online pharmacy fungal nail
buying nolvadex in canada
ivermectin 8000 mcg
advair generic brand name
wellbutrin cost without insurance
tretinoin cream 025 price
canadian pharmacy cialis malegra dxt without prescription viagra online no rx clonidine hcl 0.2 mg tablets
zithromax capsules buy
buy cafergot pills
zestril 20 mg tablet
purchase elavil
ampicillin drug
wellbutrin xl 300
buy tamoxifen 10 mg
amitriptyline medicine in india
buspar 40 mg canadian pharmacy coupon code safe online pharmacy
bactrim 250 mg
ventolin diskus
baclofen 25 mg
buy nolvadex india
motilium price in india
cost of nexium over the counter
advair generic best price
purchase propecia
dexona tablet
zanaflex for migraines
motilium over the counter usa
clonidine from canada
tizanidine 1mg paroxetine capsules 7.5 mg provigil generic canada generic for flomax elavil 10 mg tablet strattera cost ampicillin 150mg
rx cialis online
cost less pharmacy nexium 40 mg price australia ventolin tab 4mg propecia minoxidil provigil canada price vermox pharmacy amitriptyline 50 mg prices top 10 pharmacies in india
cafergot no prescription pharmacy shop nexium esomeprazole order online augmentin 400 mg tablet ampicillin 500 tablet prazosin bph flomax prescription cost
cleocin gel without prescription amitriptyline 5 mg
can i buy lisinopril over the counter in canada buy amitriptyline 10mg online can you buy modafinil over the counter uk medication cephalexin 500 zanaflex price in india 100mg bupropion coupon world pharmacy india where to buy retin a online
lyrica pills 50 mg
sildenafil online canadian pharmacy
zithromax 250 mg tablet
overseas online pharmacy
tizanidine cap 4mg
celebrex mexico
xenical 84 cap
prednisone pharmacy
ventolin pills
buspar price uk
strattera capsules canadian prescription pharmacy buspar price indian cialis fluoxetine 60 mg capsules clindamycin 1 gel in mexico no prescription vardenafil motrin 800 mg tablet
cheap generic nexium prednisone by mail order cafergot online xenical buy nz modafinil pharmacy price
how much is tamoxifen cost
levitra cost mexico
prednisone tablet 100 mg
tretinoin canada over the counter
discount celebrex online
plavix buy
80 mg lexapro
vermox online sale
where to get baclofen
vermox price in south africa
strattera
buy clindamycin online
cost of antabuse
all med pharmacy
elavil online
canadian pharmacy mall nolvadex purchase online buspar rx tizanidine 4 mg pill
provigil buy online india
Stromectol 12 mg: Can you create antibiotics