General Workflow for bots - api

I've been tasked with setting up a bot to work with Yammer, as we are investigating using Yammer as an office communication tool.
Bots are essential to workflow, so they can notify users of important real-time events and can respond immediately to queries about system states even when not in the office without the need of complicated remote-desktop systems.
I've looked into Hubot, which has a Yammer adapter using a deprecated real-time API. However, this only reacts to posts made to public groups, and does not respond to private messages.
How would I start implementing something (which APIs to look at) to receive and send private messages in real-time? I feel this surely must be possible for a communication platform like Yammer (otherwise this defeats the point?), but I cannot find anything in the API documentation.
Thank you for your time.

Few changes in the hubot-yammer and yammer modules would make the adapters work with private groups as well.
Here is what I have done to make it work with private groups.
main.js:
I have modified the main.js of yammer module to pass the group id up front and modified it to call the messagesInGroup API of yammer to listen to private group messages.
RealTime.prototype.messages = function (g_id,cb) {
this.yam.messagesInGroup(g_id,function (e, body) {
Yammer.coffee:
Further modified Yammer.coffee script to call the yammer module with private group id.
class YammerRealtime extends EventEmitter under options
if options.access_token?
#g_id = options.g_id
## Yammer API call methods
listen: (callback) ->
#yammer.realtime.messages #g_id,(err, data) ->
With above changes hubot-yammer listens to private groups and responds back.

Related

Kotlin for Volley, how can I check the JSON request for newer data in the API?

I'm working on an app that gets a list of documents/source URL from an api. I'd like to periodically check for new or updated contents within that API so users can update saved items in the database. I'm at a loss on the correct wording to search, thus Google and Stack Overflow have both failed me. My fetching function is below:
The URL for the API is https://api.afiexplorer.com
private fun fetchPubs() {
_binding.contentMain.loading.visibility = View.VISIBLE
request = JsonArrayRequest(
Request.Method.GET,
Config.BASE_URL,
JSONArray(),{ response ->
val items: List<Pubs> =
Gson().fromJson(response.toString(), object : TypeToken<List<Pubs>>() {}.type)
val sortedItems = items.sortedWith(compareBy { it.Number })
pubsList?.clear()
pubsList?.addAll(sortedItems)
// Hardcoded pubs moved to Publications Gitlab Repo
// https://gitlab.com/afi-explorer/pubs
_binding.contentMain.recyclerView.recycledViewPool.clear()
adapter?.notifyDataSetChanged()
_binding.contentMain.loading.visibility = View.GONE
setupData()
Log.i("LENGTH OF DATA", "${items.size}")
},
{error ->
println(error.printStackTrace())
Toasty.error(applicationContext, getString(string.no_internet), Toast.LENGTH_SHORT, true).show()
}
)
MyApplication.instance.addToRequestQueue(request!!)
}
private fun setupData(){
adapter = MainAdapter(applicationContext, pubsList!!, this)
_binding.contentMain.recyclerView.adapter = adapter
}
I tried using ChatGPT to see if that would get me started and that failed miserably. Also searched Google, Reddit and Stack Overflow for similar projects, but mine is a unique scenario I guess. I'm just a hobbyist and intermediate dev I guess. First time working with Volley, everything works, but I would like to find a way to send a notification (preferably not Firebase) if there is updated info within the API listed above. I'm not sure if this is actually doable.
Are you asking if you can somehow find if the remote API has changed its content? If so, how would that service advise you? If the service provider provides a web hook or similar callback you could write a server-based program to send a push notification to your Android app.
Perhaps you intent to poll the API periodically, and then you want to know if there is a change?
If you use a tool such as Postman or curl to easily see the headers of the API https://api.afiexplorer.com you will see, unfortunately, there is no Last-Modified header or ETag header which would allow you to easily determine if there was a change.
Next looking at the content of the API, the author does not provide an obvious version/change date, so no luck there.
What you could do is receive the content as a String, and perform a checksum operation on it, and if it differs you know there has been a change
or if you are deserialising the received JSON in Kotlin data classes, then out of the box, Kotlin will enable you to perform an equality operation on a previous copy of the data to know if there was a change.
This looks like an android app; if so, why don't you create a background service that makes requests to the API and updates the data as needed? You can use an AlarmManager class to set the interval threshold for polling by using the setInexactRepeating() method.
Most apps are updated in this fashion; sometimes, a separate table is created to catalog changesets.
Let me know if this helps.

Slack API remove bot from channel

I'd like to remove a slack bot from a channel using slack's API.
I've tried channels.kick but ofcourse, a bot is not a user so it can't be deleted that way. I haven't found any solutions so far on the interwet or on Slacks API documentation.
You are not correct. You can remove a bot user from a public channel or private channel using API methods just fine. I just tested it on a private channel to confirm.
So there must be another reason why this does not work for you. Please check if any of these reasons below apply to your case. Also, please provide the error message you are getting from the API, as that would greatly help to identify the reason.
Here are some potential reasons why kicking a bot user might not work for you:
wrong method: channels.kick only works for public channel, use groups.kick for private channels.
wrong token: bot tokens can not use the kick methods. You need to use a user access token to invoke that API method. (you would get the user_is_bot error)
trying to remove oneself: a user can not kick himself. (you would get the cant_kick_self error)
not using channel IDs: the kick methods require you to provide a channel ID, the name will not work. (you would get the channel_not_found error)
Based on your question I would assume you are getting the user_is_bot error, which let you to assume (incorrectly) that you can't kick a bot. In that case the solution would be to use a user token (not a bot token) to execute the method.

How to auto-refresh a screen in Moqui?

Use case is a regularly updated display of vehicle tracking data retrieved through a REST call, onto a central office screen, with no user interaction.
There is no single answer for this, but some alternatives to consider:
add some JavaScript to your screen that uses the JS setTimeout() method or something similar to reload the page
for a smoother result but a lot more effort write the section of the screen that needs to auto-update as a Vue component and use the standard websocket interface to send data to the browser to update the data in the HTML; this is generally best done using the NotificationMessage interfaces and methods in the Moqui API where the JavaScript client registers on a topic and gets a notification along with any others registered (structure the topic ID as needed to differentiate different feeds) and have a scheduled service job feed the notification topic

Is it possible to add additional logic to the Parse Server?

I want to perform some actions on X value depending on input from received in Y value. Can I perform such actions writing server side code in parse server?
Any pointers will be helpful.
Thanks.
Custom server side code can be achieved via cloud code. Cloud code allows you to create custom functions that are written in NodeJS and those functions can do various operations like: query from database, integrate with other solutions like: social, sending emails and more. The big advantage in parse-server is that you can use any npm module that you like from within the cloud code function and because there are millions of modules out there you have unlimited options.
Another very cool features of cloud code is the server side hooks
server side hooks allows you to write a code that will be triggered by parse-server core when an object is being saved or deleted. such events can be:
beforeSave - do something before the object is being saved to the database
afterSave - do something after the object is being saved
beforeDelete - do something before deleting
and more and more..
in order to define new cloud code function you will need to use the following code:
Parse.Cloud.define("{YOUR_FUNCTION_NAME}", function (request, response) {
// write your code, require some npm module and more...
});
In order to create server side hook you can write the following code:
Parse.Cloud.beforeSave("{PARSE_OBJECT_NAME}", function (request, response) {
// write your code and handle before saving an object
});
Triggering cloud code functions can be done easily via parse-server REST API or via parse-server client SDK's (iOS,Android,JavaScript and more)
There is a great guide on cloud code in here:
http://parseplatform.github.io/docs/cloudcode/guide/
Good Luck :)

Backbone.sync – Collection using ajax as well as Socket.IO/WebSockets

I have a Backbone application, which has a collection called Links. Links maps to a REST API URI of /api/links.
The API will give the user the latest links. However, I have a system in place that will add a job to the message queue when the user hits this API, requesting that the links in the database are updated.
When this job is finished, I would to push the new links to the Backbone collection.
How should I do this? In my mind I have two options:
From the Backbone collection, long poll the API for new links
Setup WebSockets to send a "message" to the collection when the job is done, sending the new data with it
Scrap the REST API for my application and just use WebSockets for everything, as I am likely to have more realtime needs later down the line
WebSockets with the REST API
If I use WebSockets, I'm not sure of the best way to integrate this into my Backbone collection so that it works alongside the REST API.
At the moment my Backbone collection looks like this:
var Links = Backbone.Collection.extend({
url: '/api/links'
});
I'm not sure how to enable the Backbone collection to handle AJAX and WebSockets. Do I continue to use the default Backbone.sync for the CRUD Ajax operations, and then deal with the single WebSocket connection manually? In my mind:
var Links = Backbone.Collection.extend({
url: '/api/links',
initialize: function () {
var socket = io.connect('http://localhost');
socket.on('newLinks', addLinks)
},
addLinks: function (data) {
// Prepend `data` to the collection
};
})
Questions
How should I implement my realtime needs, from the options above or any other ideas you have? Please provide examples of code to give some context.
No worries! Backbone.WS got you covered.
You can init a WebSocket connection like:
var ws = new Bakcbone.WS('ws://exmaple.com/');
And bind a Model to it like:
var model = new Backbone.Model();
ws.bind(model);
Then this model will listen to messages events with the type ws:message and you can call model.send(data) to send data via that connection.
Of course the same goes for Collections.
Backbone.WS also gives some tools for mapping a custom REST-like API to your Models/Collections.
My company has a fully Socket.io based solution using backbone, primarily because we want our app to "update" the gui when changes are made on another users screen in real time.
In a nutshell, it's a can of worms. Socket.IO works well, but it also opens a lot of doors you may not be interested in seeing behind. Backbone events get quite out of whack because they are so tightly tied to the ajax transactions...you're effectively overriding that default behavior. One of our better hiccups has been deletes, because our socket response isn't the model that changed, but the entire collection, for example. Our solution does go a bit further than most, because transactions are via a DDL that is specifically setup to be universal across the many devices we need to be able to communicate with, now and in the future.
If you do go the ioBind path, beware that you'll be using different methods for change events compared to your non-socket traffic (if you mix and match) That's the big drawback of that method, standard things like "change" becomes "update" for example to avoid collisions. It can get really confusing in late-night debug or when you have a new developer join the team. For that reason, I prefer either going sockets, or not, not a combination. Sockets have been good so far, and scary fast.
We use a base function that does the heavy lifting, and have several others that extend this base to give us the transaction functionality we need.
This article gives a great starter for the method we used.