For some reason I'm unable to create a room directly out of JS API like this:
TwillioVideo.connect(twillioToken, {name: 'my-name'})
.then(room => {
....
}, error => {
console.error('Unable to connect to Room: ' + error.message);
})
.connect method only works for me if the room was previously created, for instance:
I create the room first with C# like this:
public string CreateRoom(string roomName) {
TwilioClient.Init(_twilioSettings.AccountSid, _twilioSettings.AuthToken);
RoomResource room = RoomResource.Create(uniqueName: roomName);
return room.Sid;
}
then after it is created i can connect to it no problem.
So I'm forced to create a room in C# api and then use it in JS API. But i would rather avoid this step.
Also I did not find a way to determine if the room with the unique name already exist prior to calling RoomResource.Create(uniqueName: roomName) because if it does exist this method throws an exception. But i would rather return an SID of existing room in that case
Please advise
Twilio developer evangelist here.
In order to create rooms via the JS SDK, you need to have to have Client-side room creation enabled in your video settings in the Twilio console.
Related
I'm working on a project now within Twilio, using Twilio Functions, where I'm trying to set up SMS messaging so that if we receive an incoming keyword, we respond with a specific message, including a URL. The plan is to have multiple incoming keywords, with different responses so if someone sends an SMS to one of our numbers, depending on that key word, we respond with a basic message and a URL. I'm trying to figure out the best way to handle this within Twilio Functions.
I have this working for a single incoming keyword/response, as seen below.
if (incomingMessage.includes('testpark')) {
twiml.message('StartMyParking:\n\nTo start your parking, please click this link: https://blahblah.com');
} else if (incomingMessage.includes('bye')) {
twiml.message('Goodbye!');
} else {
twiml.message('Please check your zone/code and try again.');
}
While that works, I want to add in more incoming words, along with responses, such as an incoming message of 'testpark2' and a response of 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah2.com'.
Then I would want to include another one with 'testpark3' and a response of 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah3.com' and so on, all within the same script.
Can someone help me understand how to achieve this?
There are a lot of ways to achieve your desired outcome, but here's the most straightforward to begin with.
Instead of creating an else if statement for every possible keyword, you could define the keyword/response pairs up front using a JavaScript Map.
The keys of the Map will be your keywords, the values of the Map will be your responses:
const keywordResponseMap = new Map([
['testpark2', 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah2.com'],
['testpark3', 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah3.com'],
['testpark', 'StartMyParking:\n\nTo start your parking, please click this link: https://blahblah.com'],
]);
const keywords = Array.from(keywordResponseMap.keys());
let keyword;
if (incomingMessage.includes('bye')) {
twiml.message('Goodbye!');
}
else if (keyword = keywords.find(k => incomingMessage.includes(k))) {
const response = keywordResponseMap.get(keyword);
twiml.message(response);
} else {
twiml.message('Please check your zone/code and try again.');
}
Also note that I'm putting the bye case up front because it is more performant than looking for the keywords in the incomingMessage, thus you avoid unnecessarily doing that processing when a user says bye.
You can use find to search for any keyword that is in the incomingMessage, then you can use the keyword that you found to retrieve the response from the map.
If your response will always be the same except for the URL, you could further optimize this by only storing the URL in the map and using string interpolation like this:
const keywordUrlMap = new Map([
['testpark2', 'https://blahblah2.com'],
['testpark3', 'https://blahblah3.com'],
['testpark', 'https://blahblah.com'],
]);
const keywords = Array.from(keywordUrlMap.keys());
let keyword;
if (incomingMessage.includes('bye')) {
twiml.message('Goodbye!');
}
else if (keyword = keywords.find(k => incomingMessage.includes(k))) {
const url = keywordUrlMap.get(keyword);
twiml.message(`StartMyParking:\n\nTo start your parking, please click this link: ${url}`);
} else {
twiml.message('Please check your zone/code and try again.');
}
It is also important to note that I'm putting testpark last in the map because testpark matches to testpark2 and testpark3. If you'd put it first, it would always resolve to testpark even with a user submits testpark2 or similar values.
Also, I'm using the Map type because it guarantees the order in which the keys are returned, which is again important for the previous point.
When you have a lot more keywords and responses, you may have to start looking at a solution to store them externally like a database, and query the database by keyword to resolve the response.
Good luck, we can't wait to see what you build!
I´m developing a chatbot using Twilio Studio and at some point, I need to collect the data inputs from the clients that talk to my bot, and then post it into an airtable base.
I don´t have much coding skills, so my guide was this Dabble Lab tutorial: https://www.youtube.com/watch?v=xjt9YhNFrno
However, the Twilio function proposed in the video isn´t working. Here is the code:
exports.handler = function(context, event, callback) {
let member = {
name : event.name,
email : event.email,
date : Date.now()
};
var Airtable = require('airtable');
var base = new Airtable({apiKey: context.AIRTABLE_API_KEY}).base('appISrkMnNdL65Lzj');
base('Members').create(member, function(err, record) {
if (err) { console.error(err); return; }
console.log(record.getId());
callback(null, member);
});
};
When I try to make a POST request via Postman, this is what happens in my Twilio Console
And this is the capture of Postman response
As I´m using Twilio Studio Flow for developing the chatbot, I guess I could use the HTTP Request Widget but I really don´t know how to configure it.
The columns in my base are: Id - name - email - date
Any idea how can I solve this?
There are a couple of good Twilio/Airtable blogs recently posted. It looks like you are getting an error back but your error condition isn't calling the callback and thus the timeout.
Could it be some issue is with the Airtable field types not liking the type of the data you are posting, in particular the date.
Maybe you need something like this instead?
const today = new Date();
const date = `${(today.getMonth()+1)}/${today.getDate()}/${today.getFullYear()}`;
Writing to Airtable from your Twilio app
Using Airtable as a database for your Twilio app
I am developing a 1:1 chat application. I use a PHP server to create the private channel before starting the application. The channels are created correctly.
The user tokens are genereated, chat client also created correctly. I see that the user is also created in the service.
When joining the private channel, it throws the error.
code:50400 message:"User not member of channel" status:403
Javascript code:
Twilio.Chat.Client.create(token,clientOptions).then(client => {
chatClient = client;
showMessage('Connecting.....');
chatClient.getChannelBySid(channelid)
.then(function(chosenChannel) {
showMessage('Joining Chat.....');
myChannel=chosenChannel;
joinChannel();
})
.catch(function(err) {
console.log(err);
})
});
It shows the message 'Connecting....' and then stops with the error.
PHP Code:
$client = new Client("sid", "token");
$channel = $client->chat->services("serviceid")->channels
->create(array('friendlyName' => $friendlyName, 'uniqueName' => $uniqueName, 'type' => 'private'));
Twilio developer evangelist here.
When you create a private channel there's no way to define at that stage who is allowed to enter the channel. From the documentation:
Private Channels are not visible to Users that have not been invited or added to them. Private Channel Members can only be added by other Members with sufficient permissions, or via the REST API as controlled by your business logic.
So, in order for a user to join a private channel you need to either:
Add them to the channel using the REST API
Invite the user to the channel from a channel admin of the private channel
Let me know if that makes sense at all
How to call to a phone number using Twilio.Device?
I am doing the click to call feature for my widget.
I am able to get the Capability token required in setting up the Twilio.Device. I am able also to connect the Twilio.Device to twilio by setup function provided in client javascript library.
What can I use to call a number using Twilio.Device?
Its been a while since I played with it, but looking back at the code then once you have the token and are connected to Twilio it's just a case of setting the number you want to call and then initiating the call. Something like this:
document.getElementById('button-call').onclick = function () {
// get the phone number to connect the call to
var params = {
Caller: document.getElementById('phone-number').value
};
console.log('Calling ' + params.Caller + '...');
Twilio.Device.connect(params);
};
You have to make sure your token allows outgoing calls. My token.php file contains the following:
$capability = new ClientToken($TWILIO_ACCOUNT_SID, $TWILIO_AUTH_TOKEN, 'ttl=20');
$capability->allowClientOutgoing($TWILIO_TWIML_APP_SID);
$token = $capability->generateToken();
I think this is all fairly standard stuff from the quickstart files. I only had a quick go with it, but I don't remember it being complicated. Have fun!
I'm trying to use Slack's users.info API to retrieve users information, but I need to find users by email, is there a way to do that?
Yes!
https://slack.com/api/users.lookupByEmail
Using this we can find a user if email id is available.
More : https://api.slack.com/methods/users.lookupByEmail
Currently you can only look up users with users.info by their ID.
An alternative solution to your problem would be to call users.list and filter within your client by the profile.email for whichever email you're looking for.
An undocumented API can do this job:
https://slack.com/api/auth.findUser?team=&email=&token=xoxp-XXXXXXXXX
If this is being done on behalf of a Slack slash command, one can configure the command to expand #username, #channels, etc...
This can be done under the command section of the Slack app. See the following screenshot:
You should use this scope users:read.email, the users:read is no longer a sufficient scope for email field.
Check this to get more infos: https://api.slack.com/scopes/users:read.email
That's worked for me as wanted !
This was useful for me.
My setup: I am part of an enterprise, so the legacy token does not have users:read.email scope to it.
Solution: I created an app with users:read.email scope and other scopes needed. Got the app approved from my admin, installed the app to my workspace, retrieved the OAuth token, used it with https://slack.com/api/users.lookupByEmail.
you can get the userid with message.user from main calling method
getUsername(userID).then((output) => { username = output.user.name });
function getUsername(userid){
return new Promise((resolve, reject) => {
//get token from https://api.slack.com/methods/users.info
options.uri = "https://slack.com/api/users.info?token=********&userid=" +userid+ "&pretty=";
rp(options).then(function (body) {
resolve(body);
console.log('Retrieved Info slack --- ' + JSON.stringify(body));
})
.catch(function (err) {
resolve(err);
console.log('aborted - slack ' + JSON.stringify(err));
});
});
}
refer link : https://github.com/hassifow/Slack.API-User.info/blob/master/LambdaFunction.js
https://api.slack.com/methods/users.lookupByEmail
POST https://slack.com/api/users.lookupByEmail?email=seunggabi#gmail.com
form-data
token=xoxb-############-#############-$$$$$$$$$$$$$$$$$$$$$$$$