We are trying to implement a chatbot on our website.
My code successfully triggers the Flow. The Conversations log on Twilio shows that my code sent a message of "Hi" and the Flow triggered and sent the expected greeting.
The problem is that I'm not seeing anyplace where the Flow output is being sent to my website callback and so I'm not able to output the Flow messages to my website user.
When the Flow sends a message, where is the configuration that makes a callback to my website so I can output the message to the user?
onMessageAdded DOES get called on my website callback, but only for messages sent by the website code - not the Flow.
At this point I think the problem is a Twilio configuration for Conversations, Messages or the Flow, but it could be a configuration problem in my code.
Here is my rough initial code:
TwilioClient.Init(_twilioAccountSid, _twilioAuthToken);
//
// Create Conversation
var conversation = ConversationResource.Create(
friendlyName: "Test conversation",
messagingServiceSid: _twilioMessagingServiceSid,
attributes: null,
xTwilioWebhookEnabled: ConversationResource.WebhookEnabledTypeEnum.True
);
_log.Info("Conversation.Create: " + conversation.Sid);
//
// Attach Flow to Conversation
var webhook = WebhookResource.Create(
configurationMethod: WebhookResource.MethodEnum.Post,
configurationFlowSid: _twilioStudioFlowSid,
target: WebhookResource.TargetEnum.Studio,
configurationFilters: new List<string> {
"onMessageAdded",
"onMessageUpdated",
"onMessageRemoved",
"onConversationUpdated",
"onConversationRemoved",
"onParticipantAdded",
"onParticipantUpdated",
"onParticipantRemoved"
},
pathConversationSid: conversation.Sid
);
_log.Info("WebhookResource.Create: " + webhook.Sid);
//
// Create a Participant
var participant = ParticipantResource.Create(
identity: _identity,
pathConversationSid: conversation.Sid
);
_log.Info("Participant.Create: " + participant.Sid);
//
// Send Message
var message = MessageResource.Create(
author: _identity,
body: "Hi!",
xTwilioWebhookEnabled: MessageResource.WebhookEnabledTypeEnum.True,
pathConversationSid: conversation.Sid
);
_log.Info("Message.Create: " + message.Sid);
Is there a reason you decided to not use the Twilio Conversations SDK for JavaScript?
The architecture you are using may require this additional configuration.
Triggering Webhooks for REST API Events
Upon configuration, only actions from SDK-driven clients (like mobile phones or browsers) or SMS-based Participants will cause webhooks without further action on your part. This includes both Service-level webhooks and Conversation-Scoped Webhooks. This is a default behavior to help avoid infinite feedback loops.
Your Post-Event Webhook target, however, may be an important tool for archiving. In this case, you may also want to enable webhook "echoes" from actions you take on the REST API. To do so, you can add a header X-Twilio-Webhook-Enabled=true to any such request. Requests bearing this header will yield webhooks to the configured Post-Event webhook target.
Troubleshooting Webhook Delivery for Conversations or Chat
I don’t think there is a way to set this header when using Twilio Studio widgets.
Related
I would like to integrate WhatsApp business to MS Teams. When I send a message via WhatsApp it is received in Twilio. I set webhook in Teams and in Twilio also, but Twilio can't forward the message to the Teams.
The Twilio give me a
11200 ERROR There was a failure attempting to retrieve the contents of this URL.
I checked the response of Teams and I found this in the body:
"Bad payload received by generic incoming webhook."
I tested the webhook via curl and I received the text in channel of Teams.
Twilio developer evangelist here.
From the MS Teams documentation (emphasis mine):
If Incoming Webhooks are enabled for a team in any channel, it exposes the HTTPS endpoint, which accepts correctly formatted JSON and inserts the messages into that channel.
Twilio webhooks are sent in the format application/x-www-form-urlencoded, so you will need something in the middle to reformat the Twilio webhook into a format that MS Teams can ingest.
From a quick search, it's a bit difficult to find a reference for what JSON that MS Teams actually expects. This page has some examples.
To do the reformatting, you could use a Twilio Function. Code like this might well work for a basic text message into Teams:
const got = require("got");
exports.handler = async function (context, event, callback) {
const teamsWebhookUrl = context.TEAMS_WEBHOOK_URL;
const teamsPayload = {
text: event.Body
};
try {
await got(teamsWebhookUrl, {
method: "POST",
body: JSON.stringify(teamsPayload),
headers: {
"Content-Type": "application/json"
}
);
const response = new Twilio.twiml.MessagingResponse();
callback(null, response);
} catch(error) {
callback(error);
}
}
This is untested, but the idea is that it builds a simple text message using the JSON from this curl example and send it to the Teams webhook URL using got. If there is a successful response from Teams then an empty response is sent back to the original Twilio webhook. If there is an error, then that error is logged in the Twilio debugger.
To use this code you will need to install got in the dependencies and add the Teams webhook URL in the environment variables.
I am trying to us the Lifecycle events within the Graph Beta API using code like this:
var subscription = new Subscription
{
Resource = $"users/{userObjectId}/mailFolders('{resource}')/messages",
ChangeType = "created,updated",
NotificationUrl = notificationWebHookUrl,
LifecycleNotificationUrl = lifecycleNotificationWebHookUrl,
ClientState = clientState,
ExpirationDateTime = DateTime.UtcNow + new TimeSpan(0, 0, 4200, 0),
};
However, even though I have supplied a different LifecycleNotificationUrl to the NotificationUrl, the initial requests to perform the validate request only go to the NotificationUrl endpoint not the LifecycleNotificationUrl endpoint. I have checked and I am definitely supplying different endpoint urls.
I am using 2 separate Azure Functions with Http triggers as the endpoints.
Also to note is that I am using ngrok for exposing my localhost Azure functions.
I understand that if you do not supply a LifecycleNotificationUrl that this is the behaviour that you should expect, but I am.
We currently have an open issue where the validation code is sending two validation requests to the notificationUrl and none to the lifecycleNotificationUrl. This is something we're trying to address, hopefully shortly. I suggest you follow this issue to get notified of any update on the matter.
Besides that, once the validation is passed, lifecycle notifications will get delivered to your lifecycleNotificationUrl and not your notificationUrl.
I would like to make my client to check whether end client is received text or not and what reply he/she has sent? I always going through twilio to see whether client received sms or not? Is there any way to check it from twilio?
Twilio developer evangelist here.
You can get both incoming messages to your Twilio numbers and reports on the status of messages after you send them from Twilio using webhooks.
When you send a message you can include a StatusCallback parameter. The parameter should be a URL in your application.
$client->messages
->create(
$to,
array(
"from" => $from,
"body" => "Let's grab lunch at Milliways tomorrow!",
"statusCallback" => "https://example.com/messageStatus"
)
);
Twilio will send a POST request to the statusCallback URL each time your message status changes to one of the following: queued, failed, sent, delivered, or undelivered. It will include the original message's SID, so you can tie these webhooks back to the message you sent.
Similarly, you can get these webhook notifications for incoming messages to your Twilio numbers. For this you need to set up the incoming webhook URL to the number in your Twilio console. Set it to a URL in your application and you will receive a webhook when someone sends a message to your Twilio number. Check out this quickstart guide on receiving messages to your Twilio number with PHP.
Let me know if that helps at all.
[edit]
Thanks for the comment where you made it clear that this is after the fact, not at the time of sending.
In this case, you can absolutely list the messages by the phone number that sent them. A message resource includes a Status attribute that lists the current message state in the Twilio system, anything from "accepted" and "queued" to "sending", "sent", "delivered", "undelivered" and "failed". You can see more about these statuses in the documentation.
To get the list of messages sent from a number you can use the following code:
use Twilio\Rest\Client;
// Your Account Sid and Auth Token from twilio.com/user/account
$sid = "ACXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
$token = "your_auth_token";
$client = new Client($sid, $token);
// Loop over the list of messages and echo a property for each one
foreach ($client->messages->read(array("from" => $FROM_NUMBER) as $message) {
echo $message->status . " - " . $message->to . " = " . $message->body;
}
You can pull data for specific messages https://www.twilio.com/docs/api/messaging/message#delivery-related-errors
or you can simply pull all the logs
I am sending messages in using Twilio using this code:
string channelId = <channelId>;
string serviceSid = <servicesid>;
IpMessagingClient ipMessagingClient = new IpMessagingClient(<accountid>, <token>);
var msgResult = ipMessagingClient.CreateMessage(serviceSid, channelId, "sender", "message");
msg.Body = "body"
msg.DateSent = DateTime.Now;
msg.Sender = "sender"
return Json(new
{
Success = msgResult.Sid != null,
NewMessage = msg
});
Message is sent just fine and I can retrieve the messages of the channel. What I am trying to achieve now is other open browser and in the channel gets notified of new messages sent so I can update the UI to display the new messages without manual refreshing the browser.
Twilio developer evangelist here.
It looks like you are using the REST API to send messages to the Programmable Chat API.
To get using the client versions, the JS client in particular, I would take a read through the Programmable Chat documentation, go download the JS SDK and take a look at the code for the reference chat demo. All of those bits should give you a good grounding in building chat for the client side.
Let me know if that helps at all.
I am currently integrating into the twilio rest api and need to perform a check on a users phone number to determine if that user has blacklisted themselves or not. I have little experience with this api and scouring through the documentation and google has turned up nothing.
In our application we are going to have a notification center and if the user has blacklisted themselves I do not want to give them the ability to turn on their SMS notifications. Potentially a user could have SMS notifications on but twilio would block any messages. I know there is the ability to get a status code back from twilio when an SMS is queued that shows the user is blacklisted (https://www.twilio.com/docs/api/rest/message). However, I will not be sending messages on the notifications screen and need a direct way (if at all possible) to check twilio to determine if a number is blacklisted. Any help is much appreciated. Let me know if anymore information will be of help.
Megan from Twilio.
I'd be curious to see if you ever tried your own workaround. But I wanted to note for others in a similar situation how you could grab the blacklist error and then do whatever you may want with it.
In Ruby it would look something like this:
require 'rubygems'
require 'twilio-ruby'
account_sid = 'YOUR_ACCOUNT_SID'
auth_token = 'YOUR_AUTH_TOKEN'
#client = Twilio::REST::Client.new account_sid, auth_token
begin
#message = #client.messages.create(
from: 'TWILIO_NUMBER',
to: 'USER_NUMBER',
body: 'Howdy!'
)
rescue Twilio::REST::RestError => e
if e.code == 21610
# User is blacklisted
# Store info however you choose
puts e.message
end
end
We check for blacklisting specifically using the code '21610'. For more information about errors you can visit the reference page.
Hope this helps!
Twilio recommends developers to store the opt-out/in statuses in their side. I have stored it in DB. There are 2 ways to collect the unsubscribed users list.
1) Use SMS webhooks. You can find how to configure your Twilio number to receive webhook events here
#PostMapping(value = "/twilio", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
produces = MediaType.APPLICATION_ATOM_XML_VALUE)
public String twilioConsumer(TwilioEventDTO twilioEventDTO) {
// twilioEventDTO.getBody() => returns the body of the SMS user replied.
twilioService.consume(twilioEventDTO);
return new MessagingResponse.Builder().build().toXml();
}
2) Since I implemented webhooks later, I had to collect already unsubscribed users. When you send sms to the number that has been opted-out, Twilio API throws an exception with the status number of 21610. You can catch it and store the number in DB.
try {
Message result = Message.creator(
new PhoneNumber(toPhoneNumber),
new PhoneNumber(fromPhoneNumber),
messageBody)
.create();
response = result.getStatus().name();
} catch (ApiException e) {
if (e.getCode().equals(21610))
updateSubscription(toPhoneNumber, false);
logger.warn("Error on sending SMS: {}", e.getMessage());
}
P.S.: examples written in Java - Spring Boot framework.