slack api rtm direct message - websocket

I'm using a node package: slack-client to interact with the api at slack. Now with or without using slack-client how do I send a direct message from my bot to a user I want to specify? Here's what have so far with a plain socket connection:
var WebSocket = require('ws')
,ws2 = new WebSocket(myURL); //from rtm start
ws2.on('open', function() {
ws2.send({
"id": 333,
"type": "message",
"channel": "#user1", //User I want to send to
"text": "HEY!!!!"
});
});
ws2.on('message', function(message) {
console.log('received: %s', message);
});
I was hoping that message would go directly to me from the bot but nothing. I get a reply of type hello though? The send details above I got on another post about this but it doesn't work for me. The message Id was one I created.

Ok so when calling the rtm.start via the web api, you would get a list of DM's that would be open for various users otherwise you can easily just open an im with im.open. I'm using the node package slack-client as mentioned in my question so you can do this:
//name of user your bot wants to send a msg to.
var userTest = slack.getUserByName('user1');
slack.openDM(userTest.id, function(res)
{
TestMsg(res.channel.id, 'some other msg');//test function I'm using
});
Next is the TestMsg function:
function TestMsg(userChannelId, msg)
{
request.post({url: 'https://slack.com/api/chat.postMessage',
form: { token: "xxxx-yourbot-token",channel: userChannelId,text: msg ,username: "yourBotNamehere", as_user: false}
}, function(error, response, body){
console.log(response.body);
});
}
I couldn't get it to work yet using the websockets send method but I suppose the api of postMessage will do for now as you can post richly formatted messages with postMessage. Hope this helps someone

Related

Where do I get `thread_ts` to start a Slack thread with an incoming webhook?

On Slack's incoming webhook documentation, they mention including the thread_ts in the request body to start a thread.
{
"text": "Hello, world.",
"thread_ts": "12345.6789"
}
When I make the POST request to my incoming webhook url, the response body does not include the thread_ts. I was expecting the thread_ts to be in the response body, but the response body just says ok and does not include any json.
Is it possible to get the thread_ts without another app or authentication token? Do I have to use another Slack API? I only have the incoming webhook configured right now.
As a side note, if this is easier to do with Slack's new Block Kit API, that would work as well.
To take full control of all messaging features of Slack including threads you want to use the API.
When posting messages with chat.postMessage you get the thread_ts value and can start creating threads.
Also check out this official documentation on threads. It clears up a lot.
I am not an export on the new blocks yet, but as far as I understand it replaced the attachments and provides a more flexible way for message layouts. It does however not change the way threading works.
from slack_sdk import WebClient
slack_client = WebClient(token='token_value')
response = slack_client.chat_postMessage(channel=receiver, text=message)
print(response.data)
thread_ts = response.data['ts']
In case of Bolt api (js) you can check ts value from callback arguments.
app.message(
"link please",
async ({ message, say }) => { // You can also get ts from `payload`
console.log(message);
await say({
text: "you can check this link",
thread_ts: message.ts, // you can get ts from message
});
});
message content:
{
client_msg_id: 'xxxxx',
type: 'message',
text: 'xxxx',
user: 'UxxR',
ts: '1650249299.335499',
team: 'xxxx',
blocks: [ { type: 'rich_text', block_id: 'adOR', elements: [Array] } ],
thread_ts: '1650249116.347219',
parent_user_id: 'UxxxxxR',
channel: 'C01TNEN8SSK',
event_ts: '1650249299.335499',
channel_type: 'group'
}

Twilio awaits response, I don't want server to respond

I am using a Slack webhook to process incoming SMS messages from Twilio. However, the way I have it set up, It seems that Twilio is expecting the web server (slack) to respond to it. This causes errors to be generated in Twilio, and I obviously don't want errors because I'll be getting emails.
I am using the twilio-ruby gem in Ruby to send out the SMS messages, and using the slack-ruby-client to monitor incoming messages from Slack.
How do I stop Twilio from trying to expect a response from the web server when it POSTS to the Slack webhook? Is that even possible or do I have this all configured incorrectly?
EDIT
Here's the function that I have which sends the forwarded SMS to Slack:
const https = require("https");
// Make sure to declare SLACK_WEBHOOK_PATH in your Environment
// variables at
// https://www.twilio.com/console/runtime/functions/configure
exports.handler = (context, event, callback) => {
// Extract the bits of the message we want
const { To, From, Body } = event;
// Construct a payload for slack's incoming webhooks
const slackBody = JSON.stringify({
text: `!asi SMS\nFrom: ${From}\nMessage: ${Body}`
});
// Form our request specification
const options = {
host: "hooks.slack.com",
port: 443,
path: context.SLACK_WEBHOOK_PATH,
method: "POST",
headers: {
"Content-Type": "application/json",
"Content-Length": slackBody.length
}
};
// send the request
const post = https.request(options, res => {
// only respond once we're done, or Twilio's functions
// may kill our execution before we finish.
res.on("end", () => {
// respond with an empty message
callback(null, new Twilio.twiml.MessagingResponse());
});
});
post.write(slackBody);
post.end();
};
Twilio developer evangelist here.
Twilio is always going to expect at least a 200 response or will timeout at 15 seconds for incoming message webhooks.
You could avoid the error messages by using something in between Twilio and Slack, like Zapier (example in this blog post) or using a Twilio Function (as described here) or with Twilio Studio (from the documentation here).
Hope one of those ideas helps!
Update
Further to my earlier answer, and given the code you used to make the call, I have an update.
When making a request using Node's built in https module you will not get the end event until you have read the data. This is what is causing the timeout between Twilio and the Twilio Function, you are never responding to it because you don't consume the data from the request.
In a quick test I found that just listening for the data event meant that the end event did fire. So update your function to:
const post = https.request(options, res => {
// only respond once we're done, or Twilio's functions
// may kill our execution before we finish.
res.on("data", () => {});
res.on("end", () => {
// respond with an empty message
callback(null, new Twilio.twiml.MessagingResponse());
});
});
And it should work.

bot framework not receiving Slack dialog.open form response

I am building bot with Bot Builder SDK for Node.js
The bot is for slack
I have configured the slack and botframework correctly, as per the doc Connect a bot to Slack
All communication between botframework, slack and node service is through HTTPS.
The framework is communicating with slack properly.
In Next step, I am working on slack dialog.open
First of all, I could not find any method in Bot Builder SDK, to open the slack dialog, I even tried to Implement channel-specific functionality
Finally I was able to open dialog with direct post to: https://slack.com/api/dialog.open
But when I submit the form, I am getting error:
We had some trouble connecting. Try again?
Please see the screenshot:
The console displays the following error:
Request URL: https://xxxxx.slack.com/api/dialog.submit
Response: {"ok":false,"error":"curl_error"}
Slack send payload with "type":"dialog_submission".
I have tested that by changing the "Interactive Components -> Request URL", to my bot service.
To make slack communicate directly to my bot service.
Reference: section "Add and Configure Interactive Messages (optional)" in Connect a bot to Slack
So, I am sure message is being sent from the dialog box, when I click on submit button.
The message is lost between slack and my bot service. when Request URL is set to: https://slack.botframework.com/api/Actions
I never receives any indication that service is receiving a message.
Please help me to resolve this problem.
Following is the code that I used to open the dialog:
let RESTClient = require('node-rest-client').Client;
let FrameworkClient = new RESTClient();
let Promise = require('bluebird');
openDialogBox: function(token, trigger_id, callback_id) {
return new Promise(function(resolve, reject) {
var dialog = {
"title": "Issue Details",
"submit_label": "Submit",
"callback_id": callback_id,
"elements": [
{
"type": "text",
"label": "Pickup Location",
"name": "loc_origin"
},
{
"type": "text",
"label": "Dropoff Location",
"name": "loc_destination"
}
]
};
var args = {};
args.headers = {Authorization: 'Bearer ' + token, 'Content-type': 'application/json; charset=utf-8'};
args.data = {"trigger_id": trigger_id, "dialog": dialog};
FrameworkClient.post("https://slack.com/api/dialog.open", args , function(data, response) {
if (data && data.ok) {
resolve(data);
} else {
reject();
}
});
});
}
Thanks
As per #JasonSowers (Engineer - Microsoft Bot Framework)
Microsoft Bot Framework do not support this right now.
They may support this in future.

How capture audio message receive or image receive in BotKit Facebook

I have been using Botkit Facebook Messenger and I can receive text messages from Facebook perfectly, however I can not capture audio messages, images or attachments.
Has anyone been able to capture these types of messages?
var Botkit = require('botkit');
var controller = Botkit.facebookbot({
access_token: process.env.access_token,
verify_token: process.env.verify_token,
})
var bot = controller.spawn({
});
// if you are already using Express, you can use your own server instance...
// see "Use BotKit with an Express web server"
controller.setupWebserver(process.env.port,function(err,webserver) {
controller.createWebhookEndpoints(controller.webserver, bot, function() {
console.log('This bot is online!!!');
});
});
// this is triggered when a user clicks the send-to-messenger plugin
controller.on('facebook_optin', function(bot, message) {
bot.reply(message, 'Welcome to my app!');
});
// user said hello
controller.hears(['hello'], 'message_received', function(bot, message) {
bot.reply(message, 'Hey there.');
});
controller.hears(['cookies'], 'message_received', function(bot, message) {
bot.startConversation(message, function(err, convo) {
convo.say('Did someone say cookies!?!!');
convo.ask('What is your favorite type of cookie?', function(response, convo) {
convo.say('Golly, I love ' + response.text + ' too!!!');
convo.next();
});
});
});
there is an example for stickers, images, and audio replies in the facebook starter project: https://github.com/howdyai/botkit-starter-facebook/blob/master/skills/sample_events.js
If you have trouble using them, feel free to create an issues on the github!

Socket.IO subscribe to multiple channels

I want to build a simple chat room system on top of Socket.IO where user can create a new chat room and then people can start chatting.
This sound simple but as the Socket.IO 0.9.4 I'm running now, after reading a few SO posts together with the document on socket.io, i'm getting more and more confused. So, I hope that someone can provide me with instruction that WORK with 0.9.4:
I need a way to subscribe to a room. The room name is chosen by user. When a message is posted in a room, the user should receive it. How should I write the server code, how should I write the client code?
A user can join multiple rooms simultaneously.
I want another system to send a message to all user in a certain room. This 'another system' send the message through a request handled by express. How would I write that request handler?
This is all pretty straightforward with the socket.io rooms feature. Take a look at the documentation on LearnBoost wiki.
https://github.com/LearnBoost/socket.io/wiki/Rooms
It allows for being connected to multiple rooms over a single socket. I put together a quick test with the following code.
Server
io.sockets.on('connection', function(client){
client.on('subscribe', function(room) {
console.log('joining room', room);
client.join(room);
})
client.on('unsubscribe', function(room) {
console.log('leaving room', room);
client.leave(room);
})
client.on('send', function(data) {
console.log('sending message');
io.sockets.in(data.room).emit('message', data);
});
});
Client
var socket = io.connect();
socket.on('message', function (data) {
console.log(data);
});
socket.emit('subscribe', 'roomOne');
socket.emit('subscribe', 'roomTwo');
$('#send').click(function() {
var room = $('#room').val(),
message = $('#message').val();
socket.emit('send', { room: room, message: message });
});
Sending a message from an Express route is pretty simple as well.
app.post('/send/:room/', function(req, res) {
var room = req.params.room
message = req.body;
io.sockets.in(room).emit('message', { room: room, message: message });
res.end('message sent');
});

Resources