Sending Text Messages with Python and Twilo

So this is a major departure from shaders, vfx and art tools but I’ve started playing around with sending SMS messages from python and wanted to keep a record.

I have a love of spooky internet mysteries, conspiracies and ARGs, and have been thinking about how I would make my own game like this. Being able to send texts to a users real phone seemed like a much cooler method of delivery than an android game that looked like an SMS app (though a spooky app as part of the game would not go remiss!).

Twilio

A quick google search turned up that my best bet for something like this is Twilio, a service that gives you a phone number and allows you to send messages directly from their web page, or using their python module with your account’s authentication in your own scripts.

I was able to use the sample script they provide in their python quickstart tutorial to send myself a message! Numbers that you can send to must be registered, and there is a charge for each text. Thankfully their trial version gives you $15 of credit, and a text is $0.08, so I’m good for now.

twilio

from twilio.rest import Client
# Your Account Sid and Auth Token from twilio.com/console
account_sid = ‘ACb430d70d81ec0db4a6d563726a2cb121’
auth_token = ‘your_auth_token’
client = Client(account_sid, auth_token)

message = client.messages \
.create(
body=”Testing….testing…123.”,
from_=’phonenumber’,
to=’phonenumber’
)

print(message.sid)

Virtual Environment 

A virtual environment allows you to keep your base python instillation vanilla, while installing modules and updates per project. This prevents updates for new projects affecting older ones still in use.

Twilio suggests setting this up manually, but luckily for me, PyCharm does this by default when creating a new project.

virtual

Flask

Flask is a web application module for python and I used this to setup a tiny web app that will be used to take incoming requests. This allows me to see when a reply to an sms has come through, and do something in return.

I started off by just making the app.

1

from flask import Flask

app = Flask(__name__)

@app.route("/sms")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug = True)

Ngrok

In order to have my flask application and twilio talk, I needed to make my app available over the internet. To do this I used a tool called Ngrok.

To get this working, I had to edit my PATH environment var to include the folder where Ngrok lives. Once that was done, I could access it via command line.

23

Running this with the port that I was using with flask, I got a public tunnel to the server. Accessing this showed me the hello world script I’d written earlier.

45

Sending a Reply

Now that all the web stuff was setup, all I needed to do was use the twilio module to send a reply!

They have a message response class already setup, so all I had to do was import that and extend the original script to give it a string to reply with.

Screenshot_20190213-212533_Messages

from flask import Flask
from twilio.twiml.messaging_response import MessagingResponse

app = Flask(__name__)

@app.route(“/sms”, methods=[‘GET’, ‘POST’])
def sms_reply():
reply = MessagingResponse()
reply.message(“Thankyou. It has been noted.”)
return str(reply)

if __name__ == “__main__”:
app.run(debug = True)

This is super cool! Hopefully I can use this to do something fun and ARG like!

Sim’Py Framework

I’ve been playing a lot of simulation style games recently and its made me interested in the idea of making one again. This is something I’ve wanted to do for a while, but have generally got too caught up in the system without a good story, or vice versa.

To prevent that happening, I decided to write a framework so that when I did feel like writing I could jump right in, and I could satisfy the coding interest until I got to that point. This framework is written in python and extends the functionality of Ren’Py, a visual novel engine.

1

Stat and Relationship Systems

The sort of game I’m interested in making is one like Long Live The Queen or Magical Diary, where you build stats that factor into events within the game.

591133785bafe3158054d8fe

I built a stat class that handles the display name of the stat, its current value and has functions for incrementing and decrimenting the stat. I then made a stat manager, which takes stat objects and does things like compares them with one another or against a value.

2

I then built a relationship class, which is similar to the stat, but has additional variables such as “is_romantic”. This allows for the player to have a relationship value with this character, but also to track weather the relationship is platonic or romantic, eventually locking this choice based on the points gained in each throughout the game. For example, the player could have completed every scene with one character, maxing out their relationship points, but weather they chose to be flirty or not during dialog options will change the value of is_romantic, changing the scenes the player sees.

This is similar to Persona, where you can have a max social link that is platonic or romantic.

maxresdefault

Date/Time System

To create stat building and the daily event style gameplay, I made a date/time system. I have a class that tracks the current day, time and calendar, as well as ren’py labels that check the time and date and jump to the correct events. To check which events should be played, I have a dictionary that is populated during run time. Instead of checking every day if certain vars are true and then playing the event if so (a common way to track events in ren’py), I add the event to the dictionary when the inciting event occurs, with the day as the key and the time and label to jump to in a list as the value. When the system recognizes a day that is in the dictionary, it then checks the time until it sees the correct time, and displays the event.

43

Proper Nouns

The other thing I added was a file called “Proper Nouns”. In here I’m storing all character, place and object names as variables, with the codename as the variable name. This just makes things easier to develop and edit. I don’t need to worry about getting anything correct first time and don’t have to edit the code of the game to change the writing.

Having these in place makes writing a game like this much more manageable, and sets up base systems that are not likely to change. Ren’py is a fun engine to use, but without a bit of extra python love, debugging and editing can get really tough. Hopefully this has alleviated some of those issues!

Using Specific Browsers with the Webbrowser Module

Fixed my issue where the blog link in Nucleus would point to IE instead of chrome!

def open_webpage(self, webpage):
    webbrowser.register('chrome', None, webbrowser.GenericBrowser("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"))
    webbrowser.get('chrome').open(webpage, new = 0, autoraise = True)

By using the register function and adding a reference to a predefined browser, a constructor (which can be None because we’ve provided an instance) and an instance. The instance is using the GenericBrowser function to open our browser executable.

This of course wouldn’t work if I was rolling out the tool to others, I’d need to use the %PROGRAMFILES(x86)% environment variable to find path.

Additions to Nucleus

Added a link to this blog to Nucleus! I used the webbrowser module, which is a nice and easy way to open a webpage.

The new flag tells us weather to use a current window if available, or open a new one, with the values 0 and 1 respectively. Autoraise tells us weather to pop up the window.

webbrowser.open(webpage, new = 0, autoraise = True)

Had an interesting gotcha when trying to convert my new .ui file. I’d moved the directory of the script from C:/Users/Amy/Documents… to E:/My Docs/Projects/Pyscripts…
Having the space in the filename meant I couldn’t use pyside-uic.exe without getting the error:

Error: One input ui-file must be specified

The fix is simple – just put double quotes around the filepath! Thought it was worth noting as this is something I will forget it future!

Here’s the new tool! Made myself a nifty wee chrome-wordpress logo. (Though its opening in IE right now – the module is supposed to use your default browser, so I’ll work out what’s going on there later…)

blog

 

 

Merging Edges in Maya

Its always fun when something you’ve been trying to do for a couple of hours turns out to be a one line command! That was my experience today trying to merge border edges through Maya python. I guess you can tell its been a while for Maya python and I…

I’m working on some modular character related scripts at the moment and wanted to make sure my characters were sewn together properly. All I needed was:

cmds.polySewEdge(t = 10)

Its not perfect, but if character pieces are modeled to a rig with the same amount of loops in border edges, it should work as expected.

I thought I’d share some interesting commands I looked at while looking for this one line command!

Choose all border edges in selection, where mode is which selections to apply to, type is edge, vertex etc and where is borders, inside, all etc:

cmds.polySelectConstraint(mode = 3, type = 0x8000, where = 1)

This returns a string of edges, so to get edge id integers:

edge = int(edge.split(“]”)[0][-1]

To merge selected edges, specifying first and second edge by id:

cmds.polyMergeEdge(fe = border_nums[0], se = border_nums[1])

 

Nucleus 2.0

Got annoyed at not being able to find a lot of folders whilst working yesterday, so decided to make a new, stripped down version of my Nucleus launcher tool.

The original tool set default save paths for specific projects that users could edit, and relied on ini and json files to work. This ended up being somewhat unstable and a little over complicated for day to day use.

The new version of the tool just has links to various commonly used programs and folders.

29

The script is pretty unsophisticated – just a couple of functions with partial used to call them with arguments when each button is pressed. At a later date I might move the .exe paths out into a const file and use environment variables to find the root rather than hard coding it. For now though this is just a quick set of links for my own personal use.

30

An interesting thing I came across whilst working on this is that the pyside-uic.exe for converting Qt designer .ui files into .py files does not work if you have a space in the .ui file’s path – it interprets this as multiple ui files.

2728

Houdini Basic Smoke Setup and Frame Removal Script

I wanted to have a go at getting a simulation from houdini into a flipbook texture for use in UE4. To do that I’ve made an incredibly simple billowy smoke that I can play around with in engine.

I started with a basic off the shelf billowy smoke, generated from a sphere with a mountain modifier, and then made some tweaks to make it more suitable for a flipbook texture.

12

The basic shelf tool smoke looked like this.

3

I added a basic three point light setup to bring out the individual shapes . This wasn’t great as I don’t have a great deal of experience with the artistic side of lighting, all I’ve really done with is annoy lighting artists about budgets! This is something I’d like to work on when I have some time. I made this base setup into a digital asset so I can come back to it quickly later.

456

I then made a few improvements to the rendering of the sim – upping the stochasic and pixel samples, as well as changing the volume filter to reduce noise on the edges of the smoke.

7

89101113

After this, it was time to edit the simulation. I started by setting the boyancy lift on the pyrosolver to 0, to create a growing sphere shape that would be easier to work with in engine.

14

I made the container size unlimited, then upped the temp diffuse and viscosity. I added the lift back in and set the direction to 1,1,1, giving me a strong upwards draft in all directions. I also upped dissipation to create more shapes within the sim and get large variance in my texture sheet.

17

1918

I then set up a camera that animated away from the sim over time in order to get the sim to take up as much space on the screen as possible. This will help to reduce the amount of overdraw produced by the final in engine simulation as there will be less wasted transparent space.

There were 128 frames in my original sim, I took every second frame to make an 8×8 texture sheet with 64 frames. The issue with however was that the mosaic setup expected to see each frame named in sequence. 001,002 not 002, 004.

I renamed the files by writing a quick python script – thank goodness I didn’t need to do this by hand!

20

Unfortunately the original renders were not square, so I couldn’t put these into a sheet. While I waited for the new render, I elaborated on the script so that it would also delete the number of frames you wanted. Also neatened things up a bit!

23

The render still isn’t finished, so I’ll show the new texture sheet in another blog post!

Houdini Python Environment Setup

I’ve been spending some time in Houdini recently, so thought I’d share how to setup your python environment for best results when working with your own scripts and sharing them with others.

Getting Environment Variables and Folder Locations

You might have noticed that a lot of file paths in Houdini look something like:

2

This is because Houdini is getting locations from your environment variables, so that it can point to everyone’s home folder regardless of where that may be.

To view these we can open a textport window and use the echo command.

1

For example, the text below will print your user directory.

echo $HIP

3

If you see a variable like this that you don’t recognize, try using echo to find out what it is!

 

Editing Environment Variables

You can edit environment variables for Houdini by changing the .env file found in your Houdini 16.0 folder. To get this folder type in the textport:

echo $HOME

In this file you can define whatever variables you might like. A list of environment variables can be found in the official documentation. 

4

As an example, here I’ve set my python version to use 2.7.

5

Where do Python Scripts Live? 

To import your own python scripts into Houdini’s python editor, the scripts must be stored in the home directory. Navigate to the home directory and create a folder called “Python 2.7 Libs” (or whatever is appropriate to your python version). You’ll need to open Houdini again every time you make a change to this folder, but if you restart you should now be able to import your own scripts!

8

Editing Environment Variables for Multiple Users

This is all great, but what about multiple users working with version control? How do we share scripts and digital assets between users?

The best way to do this is to set the $HSITE variable in windows. This points to a home directory that contains a “Houdini 16.0” (or other version) folder. This folder can be versioned and contains your python library, digital assets and environment variables. With HSITE set and the folder kept up to date, these settings can be shared between users.

To do this, go to System in your control panel, open “Advanced System Settings” and click the Environment Variables button.

6

With this open, click new and enter “HSITE” as your variable name and the directory containing the “Houdini 16.0” folder as the value.

7

Houdini will now take all scripts, assets and variables from this location!

Nucleus – Launcher Tool Finished

I’ve finally finished my launcher tool! It now has support for photoshop and project folder, and I’ve made some nice UI tweaks as well as a lot of bug fixing!

Here’s a video of the tool in action! Excuse the horrible quaility…trying to find a free recorder and editing program that would use the same codec was maddening and I was also full of the cold at the time, so I have a snuffly voice!

Nucleus Project Manager from Amy Stevens on Vimeo.

Photoshop and Folder Support

I added support for opening photoshop and a project folder. The folder was no fuss, but photoshop was a pain!
I really wanted to be able to define a defualt save location for any new file created in photoshop, but couldn’t find a way to do it outside of photoshop. There’s no file I can edit in the same was as 3Ds max. Most suggestions online involved opening a file and saving it or using photoshop actions. Opening a file goes against what I want to do with the tool, and photohop actions are a topic to learn another day.

Hopefully the ability to open the project folder means the user can at least copy the folder location when they first save.

Bug Fixing

Next time I do a script classes and functions will actually be planned…
This whole script was hack on top of hack becuase I didn’t have a defined plan or scope and it caused loads of bugs. A lesson learned!

UI

So I discovered Qt Designer stylesheets…

lol

…and posted this on facebook to annoy everyone I know.

On a more serious note, stylesheets in designer are great to use. I just used the dropdown options here, which don’t offer a great deal of customization, but were enough for my needs.

2

1

I added a nice dark grey colour scheme and an icon, because its not finished until it has an icon! Had some trouble getting this to work until I remembered to include it in my setup file for packaging, oops! The icon could probably be more detailed/interesting but it does its job.

Packaging

This time I wanted to package my project into an .exe that could be run independently of python. To do this I used the cx_Freeze module. I created a setup file that specified which files I’d like included in my build, and then ran:

setup.py build

from the command line, in the scope of the folder that setup.py was in. This was easier than expected, especially considering I’d had problems before trying to use pyinstaller, which seems to be the recommended packaging module.

This made me a lovley wee .exe with a folder that had the json files required for running the program, along with all the associated python modules! Very pleased with this result.

Engine Options for Launcher Tool

My launcher can now launch an engine project along with max!
This one was much simpler – rather than looking to set a folder to save in, I’m just opening a project file.

The tricky part with this was knowing which project was associated with which profile. (The tool has multiple “profiles” for switching between different projects) I had made some real nasty non-scale-able code, using the same name for various entries in the json to iterate over them. This seemed good at the time, but is useless when I need to read multiple entries! I’ve done another hacky tack on to fix it (no doubt I’m going to kick myself for it later) by adding a list with every profile in it that is populated from the json file. The index of these is then used to look up a specific file name in the json. (Writing it down makes me realize how badly planned this whole script was…ugh.)

Oh well! Onwards to more hacky nonsence! Got some fixes to the edit feature to do, bit of clean up with error messages and then onto photoshop support I guess!

launcher