Here is the repository with better directions.
EDIT: Re-pasting the code as a --record option was added...
First you have to get your Twilio credentials and number and set some environment variables:
TWILIO_NUMBER=18885551234
TWILIO_ACCOUNT_SID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TWILIO_AUTH_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
EDIT: Re-pasting the code as a --record option was added...
First you have to get your Twilio credentials and number and set some environment variables:
TWILIO_NUMBER=18885551234
TWILIO_ACCOUNT_SID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
TWILIO_AUTH_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#!/usr/bin/env python3 # rootVIII # robocall101 - Robovoice/SMS command-line tool # pycodestyle/pep8 validated from argparse import ArgumentParser from json import loads from os import environ, getcwd from sys import exit, argv from time import sleep from urllib.request import Request, urlopen, urlretrieve from urllib.error import URLError try: from twilio.rest import Client except ImportError: print('Unable to import Twilio module, exiting.') exit(1) class TwilComm(object): def __init__(self): self.my_twilio = environ['TWILIO_NUMBER'] self.client = Client( environ['TWILIO_ACCOUNT_SID'], environ['TWILIO_AUTH_TOKEN']) self.url = 'https://www.restwords.com/api/post_markup' self.message = '' @staticmethod def exit_on_error(e): print(type(e).__name__ + ': ' + str(e)) exit(1) def post(self): request = Request(self.url) request.add_header('Content-type', 'text/xml; charset="utf-8"') rbody = '<?xml version=\"1.0\" encoding=\"utf-8\"?><Response>' rbody += '<Pause/><Say>' + self.message + '</Say></Response>' request.data = rbody.encode() try: result = urlopen(request) except URLError as e: self.exit_on_error(e) else: self.url = loads(result.read().decode())['url'] class Call(TwilComm): def __init__(self, outgoing, message, rec_call): TwilComm.__init__(self) self.outgoing = outgoing self.message = message self.rec_call = rec_call self.sid = '' def make_call(self): self.sid = self.client.calls.create( to=self.outgoing, from_=self.my_twilio, record=self.rec_call, url=self.url).sid def poll_call(self): print('retrieving recording... please wait for call to complete') # poll until Rec. SID has been created: rsid = [r.sid for r in self.client.recordings.list(call_sid=self.sid)] print('polling....') while not rsid: sleep(1) rsid = [r.sid for r in self.client.recordings.list(call_sid=self.sid)] print('recording SID found...') # poll until call has finished: status = [r.status for r in self.client.recordings.list(call_sid=self.sid)] while status != ['completed']: sleep(1) status = [r.status for r in self.client.recordings.list(call_sid=self.sid)] print('call completed... fetching your recording') url = 'https://api.twilio.com/2010-04-01/Accounts/' url += environ['TWILIO_ACCOUNT_SID'] url += '/Recordings/' + rsid[0] + '.mp3' try: urlretrieve(url, '%s/%s.mp3' % (getcwd(), rsid[0])) except URLError as url_err: self.exit_on_error(url_err) print(rsid[0] + '.mp3 downloaded to the current working directory') print('deleting recording from Twilio logs...') [r.delete() for r in self.client.recordings.list(call_sid=self.sid)] print('FINISHED') class Text(TwilComm): def __init__(self, outgoing, message): TwilComm.__init__(self) self.outgoing = outgoing self.message = message def send_text(self): self.client.messages.create( to=self.outgoing, from_=self.my_twilio, body=self.message) class ArnoldsHavingABadDay(Call): def __init__(self, outgoing, rec_call): Call.__init__(self, outgoing=outgoing, message=None, rec_call=rec_call) self.url = 'https://blue-platypus-3554.' self.url += 'twil.io/assets/arnold.mp3' self.outgoing = outgoing self.rec_call = rec_call class Arguments: def __init__(self): description = 'Robocall and Robotext via the command line.\n' self.parser = ArgumentParser(description=description) self.parser.add_argument( '-n', '--number', required=True, help='Outgoing phone number') self.parser.add_argument( '-c', '--call', help='Robocall - enter text to be spoken') self.parser.add_argument( '-t', '--text', help='Text - enter text to send as SMS') self.parser.add_argument( '-a', '--arnold', action='store_true', help='ArnoldsHavingABadDay') self.parser.add_argument( '-r', '--record', action='store_true', help='Record Call') @classmethod def help_menu(cls): return """ Obtain your Twilio Credentials and Twilio Number. Set the following environment variables: TWILIO_NUMBER=18885551234 TWILIO_ACCOUNT_SID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX TWILIO_AUTH_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX REQUIRED: -n <outgoing number> -| Target phone number PICK ONE: -c/--call <text/string here> -| Robocall on thy fly -t/--text <text/string here> -| Send an SMS -a/--arnold -| Call with Arnold recording ADDITIONAL OPTION: -r/--record -| Record Call/Save to .mp3 in CWD """ def get_args(self): return self.parser.parse_args() def main(): # Print better help menu if no args if len(argv) < 2: print(Arguments.help_menu()) exit(1) args = Arguments().get_args() if not args.number.isnumeric(): print(Arguments.help_menu()) exit(1) if args.call: call = Call(args.number, args.call, args.record) call.post() call.make_call() if args.record: call.poll_call() elif args.text: text = Text(args.number, args.text) text.send_text() elif args.arnold: arnold = ArnoldsHavingABadDay(args.number, args.record) arnold.make_call() if args.record: arnold.poll_call() else: print(Arguments.help_menu()) if __name__ == '__main__': main()