twilio-labs / dev-phone Goto Github PK
View Code? Open in Web Editor NEWA developer tool for testing SMS and Voice applications
License: MIT License
A developer tool for testing SMS and Voice applications
License: MIT License
If you start the dev-phone command and something fails it currently doesn't clean up after itself.
Way to replicate: have 50 Serverless Services in your Twilio account and run twilio dev-phone
.
If somebody is using an old version of the CLI, this plugin won't work. So let's check for the min version required for compatibility (I think this will be based on twilio-cli/core)
Can chat with the team building Flex Plugins CLI to see how this works
We avoid overwriting existing config in the user's account by warning or preventing them from using a PN with existing config. We check for existing config by checking incoming SMS webhook URL and incoming call webhook URL, which the plugin would overwrite. The plugin also writes to the call statusCallbackUrl, but we never check that when we're looking for existing config.
To support international developers, we could localize the UI to accommodate different languages.
This is related to #27, regional support, but more on a semantic level than an implementation one. But it does show that the dev phone may grow to involve some configurable settings - a language, a region, night mode, whether it persists, etc.
We can take a more functional approach to using the Twilio Client. One way to achieve this is through a refactor of the helper functions in dev-phone.js
to live in their own module.
One other thing to explore is using the Twilio Client as a top-level import, instead of inheriting from it. This could help simplify some of the scope issues that we're currently facing.
The Dev Phone should have a --port
flag that allows them to easily declare their own port. Additionally, the dev phone should have a stronger stance on which ports it uses and how those relate to standard ports used in web development.
This feels like a necessary first step for #24 and also a part of #110. We need to understand what port we're using (and potentially persist it) to handle multitenancy on a single machine, which eventually may scale to multiple machines working on the same account.
This involves some breaking changes i.e., profiles will now store API keys in the config file instead of using the system keychain. Any old profiles will have to be ported using the profiles:port command after the upgrade. For plugins, to be able to use profiles created using login after this upgrade, we need to upgrade the cli-core dependency and do a release after the MVR.
Problem: What should the phone number selection look like?
Some key issues include:
I'm testing the Dev Phone from a trial account. Do to trial account restrictions, the Dev Phone can't send SMS to phone numbers that aren't in the Verified Caller ID list. That's how it should be, but the Dev Phone shows the SMS as sent in the UI while logging an error in the console.
Console output:
SMS API threw an error TwilioCliError: Error code 21608 from Twilio: The number is unverified. Trial accounts cannot send messages to unverified numbers; verify at twilio.com/user/account/phone-numbers/verified, or purchase a Twilio number to send messages to unverified numbers.. See https://www.twilio.com/docs/errors/21608 for more info.
at CliRequestClient.request (/Users/nswimberghe/.twilio-cli/node_modules/@twilio/cli-core/src/services/cli-http-client.js:113:15)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
exitCode: 21608,
data: {
code: 21608,
message: 'The number is unverified. Trial accounts cannot send messages to unverified numbers; verify at twilio.com/user/account/phone-numbers/verified, or purchase a Twilio number to send messages to unverified numbers.',
more_info: 'https://www.twilio.com/docs/errors/21608',
status: 400
}
}
I suggest we should show the SMS as failed to send in the UI and if possible, show reason why, or refer to the console output.
I believe this could be pretty simple to implement using the Conversations API if it's scoped to inbound images. It should only require checking to see if the incoming message has Media on it, ensuring it's an image, and then rendering that media in an <img>
tag, or maybe using some Paste component.
Right now we are using .startsWith("dev-phone")
but we should change to .startsWith(this.devPhoneName)
before finish the project.
What are some key use cases that we can use to guide the features and usability of the dev phone? Dom has already provided some broad strokes, but a few concrete workflows could help make the idea of what the phone will do, and how it will feel to use, more concrete.
User should be able to enter a phone number and make a call from their softphone to that number using the JS SDK. Docs: https://www.twilio.com/docs/voice/tutorials/browser-calls
Similar to your calls app. Data for these should include to-number, from-number and duration. Data should persist between plugin invocations (similar to messaging history, Sync is probably the way here)
As there is no possibility of ngrok, when a user selects a phone number for the softphone to "be" we need to deploy a Function to handle incoming SMS for that number and put the details into Sync. Plugin backend should retrieve that data and surface it in the UI.
Using the JavaScript SDK and a Function deployed as the "when a call comes in" handler.
Not totally sure about this one yet, but Parcel may be a much simpler build tool - and that may be nice for us, since this tool doesn't really need to scale.
Additionally, it appears that parcel is fairly easy to replace with Webpack should we need more advanced configuration down the line. But for now, this could simplify a lot of our woes with react-scripts and our migration to typescript and npm workspaces
UPDATE: Parcel brings it own issues, NextJS, Webpack are alternatives
Our core issues include things like: Being blocked on #77, because the targeting for typescript and JS isn't being handled totally properly in the react-scripts config. Or being blocked on #79, because the frontend and backend are using different versions of eslint.
Webpack is maybe too much config for our needs, in some ways, but the flexibility it offers seems necessary for some of the things we're trying to do.
We can implement turborepo to make building + deploying more sensible. This will be a useful step for moving us towards CI/CD for the Dev Phone and is a helpful bit of tooling for managing the monorepo structure.
This includes inbound and outbound (which might mean adding sent messages to the sync list if that hasn't been done already).
UI should show conversation history per destination number, just like your messaging app really.
Oops!
During a voice call the user should be able to send DTMF tones from the softphone UI.
Use this as a foundation for a broader home for errors in the UI (e.g., you can't send a message because that number is janky)
https://docs.google.com/presentation/d/12cabcbAS5LAs_y8qyY__qmjxToHZH7Kdfnhw0vkjXR8/edit?usp=sharing
Tweek template presentation here ^
I say let's not get married to the presentation, but it's nice to have. :)
The Dev Phone's messaging capabilities should be available via the terminal.
--terminal-mode
, since --headless
already indicates that plugin should run without the UI--save
function in mind; we want to be able to store an interaction, perhaps with a name declared at the outset so that the interaction is easily referenceabledev-phone-plugin
is only responsible for understanding what Twilio resources need to be set up, and then it deploys a sub-service (UI, Terminal Mode) to handle the rest of the interactionAllow plugin to update itself, regardless of the Twilio CLI update command
e.g.,
Multiple browser tabs open that are associated with different soft phones
Configurable phone numbers - can change the phone number from the soft phone UI
Example use cases include testing regions (try a UK number, then a US number, or just US numbers from different area codes), etc.
const client = new Twilio(apiKey, apiSecret, {accountSid: '...', userAgentExtensions: ['@twilio-labs/plugin-dev-phone/1.0.0']})
const client = new Twilio(apiKey, apiSecret, {accountSid: '...', userAgentExtensions: ['@twilio-labs/plugin-dev-phone/1.0.0', 'dev-phone-headless']})
We can set this up to consume an array of tags - so there may be different modes that we want to support in the future, like Headless and Functions.
Note that this needs to be implemented with Functions as well as the extension client itself. Those should have separate tracking, because they can tell us different info (functions for Usage, extension for number of setups - interesting ratio!)
Example of implementation here: https://github.com/twilio-labs/twilio-firebase-extensions/blob/main/send-message/functions/src/utils.ts#L22-L24
What happens if developers is sharing the same project in a hackathon?
At the moment, the current code remove all API Keys names 'dev-phone', but that will block any other sessions from the same project.
Suggestion: use a random prefix and remove it when the dev-phone backend is closed on terminal.
The bug:
You'll see that the destination number field doesn't change in the UI, but the dialpad number is added to the actual value and submitted in the phone call.
There should be a single method for validating a number being added that gets applied to input from the keyboard OR the dialpad.
The following is the expected behavior:
Note that, absent a phone number validation library that handles international numbers, we should err on the side of optimism for phone number input (otherwise we risk, for example, calling a phone number from Switzerland invalid.
The width of the content in the page is a few pixels wider than the screen, this causes it to render a scroll bar at the bottom. (Bug bash doc has a screenshot.)
This was developed on a Macbook Pro, so we should get this to work more seamlessly on smaller screens. I think a "half screen mode" would be KILLER.
Some initial thoughts:
Voice Manager should handle the Reject event for incoming calls and reset state accordingly
Add a flag so that access tokens and API requests can be made relative to a more appropriate region
A wonderful conclusion to Tweek would be if this plugin was packaged and released so that everyone can use it.
From Phil Nash:
I was surprised to see it tear down all its resources when shutting down. Is there an option to keep them, and to store the config for the dev phone in CLI plugin config, allowing for quick start up the next time? Or, if you are going to tear it down, and the phone number previously had a voice/sms URL configured, put that back?
This seems related to #24, where there are some situations where the developer may want more environmental awareness about the dev phone BETWEEN sessions. These issues should be developed in parallel - if we persist the dev phone resources, that's also a way for us to know what should be torn down (i.e., we could store the dev phone resource URLs and have a boolean on whether a phone is persistent or not. If it's not persistent, we have a direct way to tear them down, including just the friendlyname of the dev phone being available locally.)
I think we SHOULD probably limit each CLI to having one persistent phone at a time, since the point is not really for them to be customisable.
Relates to #134. Outbound SMS would be easy to render (for images), but we would need a way to upload files and potentially would need to do some file validation. It's local, so I don't really think it matters, but I don't want the dev phone to crash or something.
We would also need to include an additional field in the SMS API call, so something like a MessageHasMedia()
function could be helpful - then we could just conditionally include the media parameter in the api call.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.