Wednesday, 22 April 2020

Authenticating an Internal Service inside Slack

So, let's say I have the following use case - I have service A and I want to perform a certain action associated with service A in slack. But for that, I must first log in to service A and bound the accounts of slack and of service A.
Following is the basic documentation I found out about it.
https://api.slack.com/best-practices/blueprints/account-binding


We will have the following components -

  1. User
  2. Intermediate service - X
  3. Slack 
  4. Service A
So, the following steps should be followed when this is done.
  1. The user invokes an action related to service A.
  2. If logged in and authenticated already, alright.
  3. If not, It will need to do so again. For that, it goes to intermediate service, check if binding exists. If yes, good to go. 
  4. If not, it will create a token, send it to service A along with a request to authenticate.
  5. User logs in to service A and return user id for service A user along with the token. 
  6. Then this token will be looked up and then user id for service A will be stored against slack user id.
  7. Binding is successful.
Now, some points to consider, This makes the assumption that it is okay to just authenticate once and to invoke any action service A, we will not need to authenticate again and again.

Now, let's consider scenario 2.
We have service A and Service B and slack admin can choose which service should be used to do so. and once chosen it is fixed and all users from that workspace will automatically use that service to authenticate. Except for the addition to the previous scenario is, we always need to have a session to invoke action to service B.


At first, let's see how to fix which service will be authenticated for which workspace.
Let's say in service A and service B we can provide a way to give the option to install the app.
Since the request will be coming from each individual service, We can add a parameter state with values 'A' or 'B' with it. And this can be returned to the oauth2 URL. There, along with team id and workspace, you can read value State as well.

So, in summary,
1. State (optional) parameter while making this call.
2. use 'A' or 'B' as value there.


We will have the following components - 

  1. User
  2. Intermediate service - X
  3. Slack 
  4. Service A
  5. Service B
Now, this should follow the same flow. Except we need to do either of the following steps for service B.
  1. We add an extra way to make a session persisted in service B and use that way.
  2. We store user password in service X upon authentication
  3. Since, 2 will need extra space, instead of checking if the slack user has community id, it should authenticate and check-in service B if we have a slack user ID. Assuming you can store that info there. But this will still anyways need a way to log in, have user id and password stored already and check for that particular user, right? So, to really avoid doing so, we can use the admin user or create one role on the community side and use it so we can lookup user id and then associated slack user with it.
  4. So, we need to store only admin credentials in service X and then make calls using that. No need to store all user id and slack id in service X. just store service X in community side.

So, finally proposed solution -
1. Use the 'state' parameter while installing to know which service is used.
2. Store admin credentials of service A and service B to know about whether the user has logged in at least once when a request comes from slack.
3. When you want to post things from community, you can just check if community user has associated slack id. If yes, then make an associated calls and post the notification.


Wednesday, 8 April 2020

Create, Install and Manage a slack app - OAUTH2 Flow

Hey,
So, here we will go into details about creating, installing and distributing a slack app.

This is where you start.

I created an App to send random cat emojis. I used AWS to host a service used for this app. So yeah, building a slack app is free but will cost you something eventually if you want to distribute it too.

First, create one app. 
Create a bot user. You can assign permission to it. So, unless you give the bot permission for doing something, it can't do it. You always have to give permission and scope and reinstall if your permission is changed.

Normally by default, each slack app is installed just in its own developing workspace.
To install it to another workspace, you need to build an oauth2 flow. 
Oauth2 is basically a service that will exchange temporary token and after installing, return a bot user oauth token for that particular workspace. Now, you can save that token for that particular workspace and use it to post a message as bot token.

Read more about oauth2 here - https://api.slack.com/legacy/oauth

So, nonetheless, I created a free AWS account. It is free for one year. Yay!!
I used the serverless framework to deploy the service and see logs. Google up about this to find how to set it up. https://serverless.com/framework/docs/providers/aws/guide/credentials/
sls deploy --------> to deploy the service
sls -f <function name> -t    -------> to see logs

So, now coming more to oauth2 flow,

This is what will happen.
  1.  There is a button where the user can click. It will ask the user to sign into to workspace in which they want to install. 'Add to Slack' button. Instead of a button, there can be a link as well to click on. Following is the link of my helloKitty app - https://slack.com/oauth/v2/authorize?client_id=1043883525779.1063323392868&scope=commands,incoming-webhook
  2. If already signed into multiple orgs, you can choose which one to install to.
  3. After reviewing the scope, the user hits the allow button. Then it is redirected to the URL provided when creating an app. -  Redirect URL. 
  4. On this URL, you will receive the temporary token.
  5. You are supposed to return it.
  6. In response, you will receive a bot token. These tokens don't change unless this revoked.
  7. You can use this bot token for posting a message.

Important points to keep in mind - 
  • Since this redirect URL is one for all, we indeed need to have one unchanging endpoint. This creates a need to have extra service. 
  • You will also need to store the token against workspace name/id to post a message there.
  • Client ID and Client Secret will be known to you once you create the app.

Following is the snippet of code written for oauth2.




To debug - if your logs say, not able to find a particular module. Add it to your package.json and do npm install.

With this, we are done with oauth2 flow.

Anyone should be able to install your app now.

I created one slash command too just to explore the whole stuff. 
It also takes one constant URL. Each time that command is called, it gets triggered by the URL provided while creating one. So, for each slash command, we need one constant URL as well.
If you install this app, do /helloKitty
It will pop up one random cat image for you.

I have obviously followed a lot of bits and pieces from the internet. and some by asking slack experts.
I had the following detailed chat with another user but implementing it definitely cleared all the doubts. Adding it here, just in case if someone has similar doubts. Although, I have tried to clarify as much as possible in this blog.



Monday, 6 April 2020

Peace, Slumber and Dreams

Hey,
I have been having difficulty sleeping for the last two weeks. And let me remind you, usually I sleep like Kumbha karna. Night especially. Never been a fan of all-nighters. Slept on time and woke up on time. But then lockdown happened and Now, I am home. And I could barely sleep from the past two weeks. My brain started throbbing inside for not allowing it to rest. Whenever I slept even for a short time, I had vivid dreams. I have been highly focused on my work and even that has not helped me to get to sleep. So, I put Whatsapp status asking for tips.
As we all know, these are difficult times. A lot of us are agitated over something, let it be job, lockdown, COVID'19, loved ones at the front line, college, money, food, WFH, increasing communal riots, etc. So, whatever your reason for being uncomfortable and being stressed is, one needs peaceful sleep to deal with life.
So, here is a compiled version of the suggestions I got. I hope one of them will suit you. Honestly, I have not tried all of them. The ones I think are important or have tried, I have made them bold.

  1. HeadSpace
  2. Wash hands, face and feet before going to bed.
  3. Have a bath before going to bed. (If 2nd point doesn't help)
  4. Have a workout routine in the evening. If it pains or is intense, better.
  5. If you are religious, try listening to something you like in low volume.
  6. Try white noise.
  7. Try ocean, tree leaves noise. If you are hyper-aware, sometimes this can backfire. XD.
  8. Try sniffing Lavender essential oil. Eat 1 tablespoon of khus khus before going to sleep. (Did not try this but one friend did).
  9.  Try reading a book. Now, I would not suggest grabbing Sherlock or something. You want to sleep, not stay awake in suspense. If you are a student, try reading your textbook. Nothing is better to induce sleep sometimes. Don't read it on a phone or tablet. Use a hard copy.
  10. Stay away from the screen. Put your phone away. Put the laptop away too. Don't text or watch random videos.
  11. Try meditating to relax. Try to focus on your breath. If that doesn't work for you, try counting in a rhythm. 
  12. Don't think much. Keep your head as empty as possible. If you can't put issues to the side, then just deal with them already instead of wasting your time being anxious about them. And if things like worrying about your grades or kids or India's economy are making you anxious,  I would suggest being anxious the next day when you can do something about it. Put it on hold. Like okay, here is a thought and I will come back to it tomorrow. It is like a reprioritizing list in your head.
  13. Put a pillow to support your legs. 
  14. Keep your room temperature according to your liking. I like cold rooms with warm blankets sometimes, Sometimes avg temp.
  15. Stay hydrated throughout the day. If you forgot, drink water before going to sleep.
  16. Try going to sleep on scheduled time each day.
  17. Hot milk before sleep.
  18. Have a head massage with some oil. You can use slightly warm oil too. Ask someone else to do it for you. After that, maybe massaging shoulders will help a lot. Especially if you have neck and shoulder pains. 


The intention is to sleep. You guys must know the importance of sleep. Life is short and staying awake unnecessarily is not the way to live it efficiently. Have a nice sleep. Night night.
PS - Stay hydrated.
PPS - Add comments if you have more ideas. XD 

Thursday, 26 March 2020

Salesforce API SOAP endpoint - SoapUi

Hey all,
so I got to recently try out salesforce API and how to hit them up.
This is a summary of how to do it.
So, the first thing we need to make any call is authentication. I am pretty sure all of you know what is authentication but nonetheless, authentication is basically verification of your identity.
Once we authenticate, we get a session token. This session token can be used to make all other calls.

For authentication, you need username, password and security token.

Step 1: Download WSDL for your organization. Now, this is the file containing the relevant info of your org. There are two different types of WSDL available in salesforce.  It is more specific to your org than Partner WSDL which is a bit more generic.

To generate WSDL -
1. Log in to Salesforce as 'System Administrator' or as a user who has the 'Modify All Data Permission'.
2. Setup > Search for 'API' in the quick find box.
3. Select API.
4. Click Generate Enterprise WSDL.
5. Save the XML WSDL file to your computer.
https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_quickstart_get_WSDLs.htm

To make soap calls, you need a soap UI. You can make post calls using postman as well but I have used soap UI. you can download it from here.
https://www.soapui.org/downloads/latest-release.html


Step 2: Once that is done, create a new project and import your WSDL.
Since WSDL is like a MAP to your org, if you changed your org or updated it, for example, created a new custom endpoint in your org, then you need to update this WSDL by downloading and importing it again. So, if you installed a package, then you need to update this as well.





Step 3:  Explore your new project. You will see a lot of new methods in your project. All of them have a sample request call. Update the required info according to each call.

Step 4: Authenticate and use the token to make new calls.
use the login call to authenticate.
Use a password appended with your security token for login.


Step 5: DescibeSobject. This method describes all fields associated with a particular 'SObject'. Use the token obtained in step 4.


Step 6: Query Method. Use the token obtained in step 4.


Step 7: Similarly, you can use the 'create' method to create new SObjects like a case, account in salesforce. Use the token obtained in step 4. I have a custom SObject in my org. Trying to create it.

So, This is brief about testing Salesforce API using SOAP calls.

PS - Stay hydrated. In this season of coronavirus. Maintain social distance but please feel free to reach out to me over the mail in case of doubts.




Friday, 20 March 2020

Salesforce API Rest Endpoints

Salesforce has exposed a soap library as well as Rest Endpoints. In the following doc, we will talk about Rest endpoints.
I hope all of you know what is Rest and why it is favored over soap lots of times.
To know more about it, check out the following link.  https://restfulapi.net/
Read Soap vs Rest if you have time as well. https://restfulapi.net/soap-vs-rest-apis/
Following is the standard salesforce Rest API documentaion - https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/quickstart_prereq.htm


Firstly you need a tool through which you can hit the API. You can hit GET API using a browser and POST using a terminal using a curl command.  I have used the Postman app. It is wildly popular for API testing. It makes the job easier. You can find it here - https://www.postman.com/downloads/

So, to start with salesforce API, you will first need to know what are the endpoints to hit. If you have custom code in your org and you have exposed some new rest endpoints then you can hit them up as well. The important condition being you know what path to hit.

At first, we will talk about the default REST endpoints. Salesforce has detailed documentation on which API to hit but it could take time to figure it out. So, I am here to help you with it.

So, Salesforce has a tool called Workbench where you can execute REST queries and get to know its path. That's how I got this as well. I have found an excellent Salesforce doc for this. https://trailhead.salesforce.com/en/content/learn/modules/api_basics/api_basics_rest
Play around with it figure it out.

Once you are done with it, if you want to still make API calls using POSTMAN, you need to Authenticate yourself first.
For that, you need to create a connected app in your salesforce org with API access enabled. It is a POST call. here is a great link which shows how to do it in detail -(https://docs.datawatch.com/swarm/desktop/Generating_a_Client_ID_and_ClientSecret_Key_for_Salesforce_Connections.htm)

Following is the standard document from salesforce to gain more knowledge about authentication flows. Use password appended with the security token.
https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_oauth_and_connected_apps.htm

This returns a token, which you can use for making other calls.
For example, 

This is just for a token, you still need to input parameters that you are using for the API under the params tab for the GET call. Like,

However, for POST call you need to provide data that you want to send over under the tab named 'Body' in raw format. and give the content type under the 'Headers' tab as 'JSON'.
At least that's what I did.
I am trying to create the Community user object from the managed package I have installed using POST API.



Add token, add headers, add body and you are good to go. Hit the API and see the response. 
The response depends on what is the call made. If it was for creating an SObject like community user, it will return the id of the object created.
If you hit a GET call asking for a bunch of contacts, then the response will contain that. You can see the format of response while playing around with Workbench anyways. (https://workbench.developerforce.com/login.php)
Use it effectively. It is a great tool.

You can as well create your own rest endpoints in salesforce.
You will see how it hit such customized endpoints as well. 
Although to know correct path for hitting such endpoints declared inside installed managed package, follow the link - https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_rest_methods.htm

Para from the above link - 
Apex REST methods can be used in managed and unmanaged packages. When calling Apex REST methods that are contained in a managed package, you need to include the managed package namespace in the REST call URL. For example, if the class is contained in a managed package namespace called packageNamespace and the Apex REST methods use a URL mapping of /MyMethod/*, the URL used via REST to call these methods would be of the form https://instance.salesforce.com/services/apexrest/packageNamespace/MyMethod/. For more information about managed packages, see What is a Package?



So, I think this is it, guys. You can do REST API salesforce testing on your own then. Take care. Stay Hydrated. 
PS - I always forget to drink water.