I'm trying to use this dialpad plugin for Twilio Flex to make phone calls. I'm newbie on this so maybe I'm forgetting something to do in the process. I will detail the steps I made:
git clone https://github.com/lehel-twilio/plugin-dialpad.git
npm install
cp public/appConfig.example.js public/appConfig.js
appConfig.js file code:
// your account sid
var accountSid = 'ACXXxxxxXXXXxxxxxxXXXXXXxxxx35'; //my accountSid
// set to /plugins.json for local dev
// set to /plugins.local.build.json for testing your build
// set to "" for the default live plugin loader
var pluginServiceUrl = '/plugins.json';
var appConfig = {
pluginService: {
enabled: true,
url: pluginServiceUrl,
},
sso: {
accountSid: accountSid
},
ytica: false,
logLevel: 'debug',
showSupervisorDesktopView: true,
};
I deploy functions according to github docs: Hold Call (/hold-call), Create New Task (/create-new-task), Cleanup Rejected Task (/cleanup-rejected-task), Flex Dialpad Add Conference Participant (/add-conference-participant)
According to plugin-dialpad documentation, all these functions have the option Check for valid Twilio signature unchecked:
Configuring Functions :
Task channel 'custom1' is created:
I added my phone number as an attribute value to every Worker:
And finally, I added the filter:
At the beginning it displayed this error when I tried to make a phone call:
I could fix it applying CORS headers in Create New Task function which It's showing the error, I changed this line: "Access-Control-Allow-Origin":"https://flex.twilio.com":
But now it shows me an error in dialpad-plugin.js and I still can't make phone calls:
Flex version 1.11.1 (same happens with 1.10.0)
plugin-dialpad version 4.0
How can I fix it? I'd like your help.
Are you sure you created the function as details in the github repo? For example, the create-new-task function looks very different then what you posted.
https://github.com/lehel-twilio/plugin-dialpad/blob/master/src/functions/create-new-task.js
All the functions are located here:
https://github.com/lehel-twilio/plugin-dialpad/tree/master/src/functions
Ok, finally I could fix my problem.
First, I had to create Twilio functions according to github: https://github.com/lehel-twilio/plugin-dialpad/tree/master/src/functions
After that, when I make a phone call it's showing me an error message on Twilio Debugger: Got HTTP 500 response from https://*****.twil.io/call-outbound-join Error: 'From' phone number not verified.
My Twilio Phone Number is from another country, so I fixed adding this additional code on "Create New Task" function which allows so add "+" sign automatically:
const numbx = "+" + event.From; const wnumbx = numbx.replace(/\s/g,'');
console.log(wnumbx); const numbt = "+" + event.To; const wnumbt =
numbt.replace(/\s/g,''); console.log(wnumbt);
client.taskrouter.workspaces(workspace) .tasks .create( { attributes: JSON.stringify( { to: wnumbt, direction: 'outbound', name: 'MY COMPANY', from: wnumbx,...
This is not necessary on Twilio phone numbers of US.
Related
I'm looking to configure Twilio Flex only via code without using the UI. However, I'm stuck trying to find out how to enable the dial pad and caller ID details along with a few other settings.
Is everything able to be configured via an API/Terraform?
How can I find out the missing parts.
You can edit this information by Flex Configuration API.
Follow an example of a request that you can use:
Request method: POST
Request URL: https://flex-api.twilio.com/v1/Configuration?UiVersion=1.30.2 (The UiVersion will be the version of your environment, in this example, the version of the Flex is 1.30.2)
Authentication Type: Basic
Authentication credentials: accountSid:authToken (accountSid is the username and authToken is the password)
Request Body:
{
"account_sid": "ACXXXX",
"outbound_call_flows": {
"default": {
"workflow_sid": "WWXXXX",
"enabled": true,
"queue_sid": "WQXXXX",
"caller_id": "+551199998888",
"location": "BR"
}
}
account_sid -> The Account's account_sid (ACXXXX)
workflow_sid -> The Workflow that you want to configure for outbound calls, you can see existents workflows at Twilio Console following the path Taskrouter > Workspaces > Workflows (https://console.twilio.com/us1/develop/taskrouter/workspaces?frameUrl=/console/taskrouter/workspaces) (WWXXX)
queue_sid -> The Queue that you want to configure for outbound calls, you can see existents queues at Twilio Console following the path Taskrouter > Workspaces > Task Queues (https://console.twilio.com/us1/develop/taskrouter/workspaces?frameUrl=/console/taskrouter/workspaces) (WQXXX)
caller_id -> The Number that will be used for outbound calls, you can see the existents number at Twilio Console following the path Phone Numbers > Manage > Phone Numbers (https://console.twilio.com/us1/develop/phone-numbers/manage/incoming) (+...)
location -> The Location that will be used for outbound calls.
I hope that it can help you! :D
Unfortunately, this is not possible at the moment.
I have found a few examples of context.getTwilioClient(), but I have not been able to locate any online documentation. It's probably right under my nose, but it is eluding me. In particular, I'm trying to get information about workers in a Task Router queue (i.e., how many workers are in the different statuses and how many workers are available), but having the documentation will help with future projects.
I found some documentation saying that the context.getTwilioClient(), "enables you to invoke the getTwilioClient method on the context object for a fully-initialized Twilio REST API client." (https://support.twilio.com/hc/en-us/articles/115007737928-Getting-Started-with-Twilio-Functions)
It then shows this example, but there is no implementation of "messages" when I attempt to run this code:
var client = context.getTwilioClient();
client.messages.create({
to: '+12025551212',
from: '+12065551212',
body: "hello world!"})
Thanks.
The messages property should be on the client. getTwilioClient returns the Twilio helper library for Node.js.
I just created a Function with your code, and it worked as expected, meaning that I got the SMS, however, the function did time out because the callback was never invoked. To end the function invocation and respond to the caller, make sure you always invoke the callback function, like this:
exports.handler = function(context, event, callback) {
var client = context.getTwilioClient();
client.messages.create({
to: '+1xxxxxxxxxx',
from: '+1xxxxxxxxxxx',
body: "hello world!"})
.then((message) => {
console.log('SMS successfully sent');
console.log(message.sid);
// Make sure to only call `callback` once everything is finished, and to pass
// null as the first parameter to signal successful execution.
return callback(null, `Success! Message SID: ${message.sid}`);
})
.catch((error) => {
console.error(error);
return callback(error);
});
};
You can learn more about the callback function here.
If you still encounter this issue, can you tell use what Node Version you're using and which module dependencies and their versions?
You can find these details at Settings & More > Dependencies in your Twilio Functions Service.
My company uses Twilio Flex as our phone system and I was recently tasked with setting up a feature that will let us edit a TwiML voice message that plays before our normal voice message. This TwiML message will be changed through a Twilio bot that I've published in our Microsoft Teams.
The reason for this is so that our support desk can add a short message in the lines of "We're currently experiencing issues with X" before our normal "Welcome to [Company] support" message.
If TwiML's can be edited using HTTP POST/PUT or Twilio's API this should be a trivial matter, but so far I've not been able to figure out how.
I couldn't find any reference to this in the API doc, so I decided that HTTP POST would be the way to go. Using this as a start off point, I'm able to retrieve my TwiML using HTTP GET:
https://support.twilio.com/hc/en-us/articles/223132187--Not-Authorized-error-when-trying-to-view-TwiML-Bin-URL
const axios = require('axios');
const crypto = require('crypto');
const accountSidFlex = process.env.accountSidFlex;
const authTokenFlex = process.env.authTokenFlex;
var URL = 'https://handler.twilio.com/twiml/EHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + '?AccountSid=' + accountSidFlex
var twilioSig = crypto.createHmac('sha1', authTokenFlex).update(new Buffer(URL, 'utf-8')).digest('Base64')
var config = {
headers:{
'X-TWILIO-SIGNATURE': twilioSig
}
}
axios.get(
URL,config
).catch(error => console.log(error))
.then(response => {
console.log(response.data)
})
response.data shows the TwiML's current XML content.
My attempts at a POST only gives the same output as the GET, while PUT gives 405 Method Not Allowed.
var URL = 'https://handler.twilio.com/twiml/EHXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + '?AccountSid=' + accountSidFlex
var twilioSig = crypto.createHmac('sha1', authTokenFlex).update(new Buffer(URL, 'utf-8')).digest('Base64')
var config = {
headers:{
'X-TWILIO-SIGNATURE': twilioSig,
'Content-Type': 'text/xml'
}
}
var xml =
'<?xml version="1.0" encoding="UTF-8"?>\
<Response><Play digits="www"/>\
<Say voice="alice">"We are currently experiencing X related issues". </Say>\
</Response>';
axios.post(
URL,xml,config
)
.catch(error => console.log(error))
.then(response => {
console.log(response.data)
})
Ideally I'd like to be able to change a specific TwiML using either HTTP methods or the Twilio-API, so that we can use it in out Studio Flow. We'd just keep it silent until we need to add something to it and revert back to silent once the issues have passed.
Any help would be appreciated!
You cannot currently change the contents of TwiML Bins, Studio Flows, or Twilio Functions programatically. I believe the key functionality you are looking for is a way to dynamically update the messaging (Say/Play Widget) in a Studio flow based on some condition.
One way is to use a Function Widget to retrieve a Twilio Sync document for the message, returning the message as JSON and have the Say/Play widget play that message. You can find the Twilio Sync REST API examples for Add, Modify, and Retrieve in the associated document.
You can retrieve the parsed response using variable syntax detailed here, https://www.twilio.com/docs/studio/widget-library#run-function.
I see that Dialogflow has fulfiment and webhook installations to allow for further dynamic and logistic control over the bot responses. I'm trying to peg a database on top of the webhook, but the channel I'm using is Twilio Text Messaging, and I'm having a little trouble with connecting the two. When I do activate fulfillment, the twilio bot does not read it. Any way to solve this?
I already created a few webhooks using Flask, and integrated it through fulfillment briefly using ngrok, but the bot is responding via the text responses I set for it. Its for google assistance, and facebook messenger, but not with the Twilio integration.
I also tried using inlineJS to see if that held any difference to specifically define Twilio as the messaging outlet to use, however it did not peak success.
const functions = require('firebase-functions');
const {dialogflow} = require('actions-on-google');
const GOODLOCATION = 'location.good'
const NEARLOCATION = 'location.near'
const CHEAPLOCATION = 'location.cheap'
const WELCOME_INTENT = 'Default Welcome Intent'
const FALLBACK_INTENT = 'Default Fallback Intent'
const CRAVINGCULTUREINTENT = 'CravingCulture'
const CRAVINGITEM = 'CravingItem'
const app = dialogflow()
/*Supported Platforms*/
const PLATFORMS = {
UNSPECIFIED: 'PLATFORM_UNSPECIFIED',
FACEBOOK: 'FACEBOOK',
SLACK: 'SLACK',
TELEGRAM: 'TELEGRAM',
KIK: 'KIK',
SKYPE: 'SKYPE',
LINE: 'LINE',
VIBER: 'VIBER',
ACTIONS_ON_GOOGLE: 'ACTIONS_ON_GOOGLE',
TWILIO: 'TWILIO'
};
// Platforms that support Rich messaging
const SUPPORTED_RICH_MESSAGE_PLATFORMS = [
PLATFORMS.FACEBOOK,
PLATFORMS.SLACK,
PLATFORMS.TELEGRAM,
PLATFORMS.KIK,
PLATFORMS.SKYPE,
PLATFORMS.LINE,
PLATFORMS.VIBER,
PLATFORMS.ACTIONS_ON_GOOGLE,
PLATFROM.TWILIO
];
app.intent(WELCOME_INTENT, (conv)=> {
if(agent.requestSource === agent.TWILIO){
conv.ask('This is working, Congratulations!')
}
else{
conv.ask("Could not be served")
}
});
app.intent(FALLBACK_INTENT, (conv)=> {
conv.ask("I am unaware of that phrase, could you repeat that?")
});
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app)
I want the output to be any thing that the user insert through the twilio that this bot will respond accordingly to what is passed in.
A little late, perhaps - hopefully this issue isn't still blocking/plaguing you.
I'm thinking you were intending:
if(agent.requestSource === PLATFORMS.TWILIO){
not:
if(agent.requestSource === agent.TWILIO){
However, also the value of agent.requestSource is actually lowercase "twilio".
I'm following the tutorial here https://slackapi.github.io/node-slack-sdk/bots#posting-a-message and I'm flummoxed why I can't get this portion of the tutorial code to work. I copied and pasted the code from this section, which is below
var RtmClient = require('#slack/client').RtmClient;
var RTM_CLIENT_EVENTS = require('#slack/client').CLIENT_EVENTS.RTM;
var bot_token = process.env.SLACK_BOT_TOKEN || ''; //I know the problem is not here.
var rtm = new RtmClient(bot_token);
rtm.start();
var channel = "#general"; //could also be a channel, group, DM, or user ID (C1234), or a username (#don)
// you need to wait for the client to fully connect before you can send messages
rtm.on(RTM_CLIENT_EVENTS.RTM_CONNECTION_OPENED, function () {
rtm.sendMessage("Hello!", channel);
});
Since the first section of the tutorial code worked, the problem is definitely coming from the last 3 lines of code. Presumably its an issue with the event. My error message is
Unhandled rejection Error
at RTMClient.handleMessageAck [as _handleMessageAck] (/Users/mg/projects/slack_projects/games/s
lack_connect_four/node_modules/#slack/client/lib/clients/rtm/client.js:496:40)
at RTMClient._handleWsMessageViaEventHandler (/Users/mg/projects/slack_projects/games/slack_con
nect_four/node_modules/#slack/client/lib/clients/rtm/client.js:459:12)
at RTMClient.handleWsMessage (/Users/mg/projects/slack_projects/games/slack_connect_four/node_m
odules/#slack/client/lib/clients/rtm/client.js:419:10)
at WebSocket.wrapper (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/l
odash/lodash.js:4968:19)
at emitTwo (events.js:106:13)
at WebSocket.emit (events.js:191:7)
at Receiver.ontext (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/ws/
lib/WebSocket.js:841:10)
at /Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/ws/lib/Receiver.js:5
36:18
at Receiver.applyExtensions (/Users/mg/projects/slack_projects/games/slack_connect_four/node_mo
dules/ws/lib/Receiver.js:371:5)
at /Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/ws/lib/Receiver.js:5
08:14
at Receiver.flush (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/ws/l
ib/Receiver.js:347:3) at Receiver.finish (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/ws/
lib/Receiver.js:541:12)
at Receiver.expectHandler (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modu
les/ws/lib/Receiver.js:499:31)
at Receiver.add (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modules/ws/lib
/Receiver.js:103:24)
at TLSSocket.realHandler (/Users/mg/projects/slack_projects/games/slack_connect_four/node_modul
es/ws/lib/WebSocket.js:825:20)
at emitOne (events.js:96:13)
I would really appreciate any help.
Possibly your bot did not join the #general channel yet. Invite him to the channel first.
This post might be old but I'd like to share my experience with this error. I was testing this code too and I was using a private channel. Even if the bot is already a member of the channel it throws this error. Then I tried to use a public channel then it went through. I hope this helps.
You cannot use channel names, usernames, or user ids. Use channel/group/DM ids instead.
Change:
var channel = "#general";
To:
var channel = "C--------";
You can grab this channel ID from your channel's URL:
https://yourworkspace.slack.com/messages/C-------/details/
And your bot must be added to the target channel, as detailed here:
On your app's settings page, click the OAuth & Permissions settings item in the navigation menu.
In the Scopes section, add the chat:write permission scope, then click Save Changes.
Now that you've changed the scopes for your app, you'll need to install it again - you should see a yellow banner near the top of the screen telling you to click here to reinstall your app. Click it, and follow through the permissions authorization page.
You'll be redirected back to the OAuth & Permissions page, where you can see your workspace token listed at the top of the page - store this for use later on.
SLACK API REFERENCE
This code will work as expected:
var RtmClient = require('#slack/client').RtmClient;
var CLIENT_EVENTS = require('#slack/client').CLIENT_EVENTS;
var rtm = new RtmClient('.....'); // your token
rtm.start();
let channel = 'C--------' ; //your channel
rtm.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, function () {
rtm.sendMessage("Hello stack!", channel);
});