<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog posts by Krishna Santosh Nidri]]></title><description><![CDATA[Check out the articles and blog posts by Krishna Santosh Nidri on solutions to some common use cases. Articles from Medium and Hashnode.]]></description><link>https://blog.nidri.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 19 Apr 2026 07:48:08 GMT</lastBuildDate><atom:link href="https://blog.nidri.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Automate USCIS Case Tracking]]></title><description><![CDATA[In 2025, USCIS started using Cloudflares “Verify you are human” mechanism. Due to that, the following bot will not work because it cannot by pass Cloudflare’s verification.

To get the latest case status(H1B, H4 etc.), one has to visit USCIS and chec...]]></description><link>https://blog.nidri.dev/automate-uscis-case-tracking</link><guid isPermaLink="true">https://blog.nidri.dev/automate-uscis-case-tracking</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[puppeteer]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Fri, 29 Nov 2024 22:58:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732921020282/454ed150-c53d-4da4-9d4a-f7e4953bfcbe.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>In 2025, USCIS started using Cloudflares “Verify you are human” mechanism. Due to that, the following bot will not work because it cannot by pass Cloudflare’s verification.</p>
</blockquote>
<p>To get the latest case status(H1B, H4 etc.), one has to visit <a target="_blank" href="https://egov.uscis.gov/">USCIS</a> and check status by providing case ID. Straight and easy…</p>
<p>What if someone is so lazy(or so busy) to visit the site daily and check the status? Or what if there are more than one Case ID to check everyday?</p>
<p>Having a script that checks daily and notifies us would be so helpful 😀. USCIS does have API features but there is a process and policies on who can get access and use. Maybe it's not worth going through all that process if it's just for one case ID. As a workaround, a simple <strong>NodeJS</strong> script can be deployed to run daily and lookup the status on our behalf.</p>
<p><strong>Idea:</strong></p>
<ol>
<li><p>Take the case ID as input and get the status of the case.</p>
</li>
<li><p>Notify with the latest status</p>
</li>
<li><p>Repeat the process (until stopped)</p>
</li>
</ol>
<blockquote>
<h3 id="heading-have-nodejs-and-npm-installed-already">Have NodeJS and NPM installed already</h3>
</blockquote>
<p>#1 <strong>Script to run the process</strong></p>
<p>Puppeteer’s <a target="_blank" href="https://www.npmjs.com/package/puppeteer">NPM</a> package will be used to automate running a headless version of browser and get details from USCIS website.</p>
<pre><code class="lang-plaintext">npm i puppeteer

// Checkout the documentation to use other browser than the default.
// Also, optional parameters may require in actual code depending on
// OS and version
</code></pre>
<p>Next, the snippet to take the case ID and give the status back.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// index.js</span>
<span class="hljs-keyword">import</span> puppeteer <span class="hljs-keyword">from</span> <span class="hljs-string">'puppeteer'</span>;
<span class="hljs-comment">// Set the case ID</span>
<span class="hljs-keyword">const</span> id = <span class="hljs-string">'YourCaseID'</span>;
<span class="hljs-keyword">const</span> mainUrl = <span class="hljs-string">'https://egov.uscis.gov'</span>;

<span class="hljs-keyword">const</span> browser = <span class="hljs-keyword">await</span> puppeteer.launch({
    <span class="hljs-attr">headless</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">args</span>: [<span class="hljs-string">'--no-sandbox'</span>]
});
<span class="hljs-keyword">const</span> page = <span class="hljs-keyword">await</span> browser.newPage();
<span class="hljs-comment">// Setting user agent is required in headless mode</span>
<span class="hljs-keyword">await</span> page.setUserAgent(<span class="hljs-string">'Mozilla/5.0 (Windows NT 5.1; rv:5.0) Gecko/20100101 Firefox/133.0'</span>);

<span class="hljs-keyword">await</span> page.goto(mainUrl);

<span class="hljs-comment">// Type into search box</span>
<span class="hljs-keyword">await</span> page.locator(<span class="hljs-string">'#receipt_number'</span>).fill(id);

<span class="hljs-comment">// Wait and click on first result</span>

<span class="hljs-keyword">await</span> page.locator(<span class="hljs-string">'[name=initCaseSearch]'</span>).click();

<span class="hljs-keyword">const</span> reqUrl = <span class="hljs-string">`<span class="hljs-subst">${mainUrl}</span>/csol-api/case-statuses/<span class="hljs-subst">${id}</span>`</span>;

<span class="hljs-comment">// Wait for API request</span>
<span class="hljs-keyword">await</span> page.waitForResponse(reqUrl);

<span class="hljs-comment">// Capture the value from the element that shows the status</span>

<span class="hljs-keyword">const</span> textSelector = <span class="hljs-keyword">await</span> page
    .locator(<span class="hljs-string">'#landing-page-header'</span>)
    .waitHandle();
<span class="hljs-keyword">const</span> fullTitle = <span class="hljs-keyword">await</span> textSelector?.evaluate(<span class="hljs-function"><span class="hljs-params">el</span> =&gt;</span> el.textContent);

<span class="hljs-comment">// Print the full title.</span>
<span class="hljs-built_in">console</span>.log(id, fullTitle);

<span class="hljs-keyword">await</span> browser.close();
</code></pre>
<p>#2 <strong>Notifications:</strong></p>
<p>This is a personal preference on how and when to get notified. Personally I have set up a text message service to get notified via text everyday with the latest status.</p>
<p>But there are other ways to setup and get notified via email(<a target="_blank" href="https://www.npmjs.com/package/nodemailer">nodemailer</a>) or Webhooks or text messages.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732920229630/a6c396cb-66e6-4bad-bb53-43fb65609f11.png" alt class="image--center mx-auto" /></p>
<p>#3 <strong>Repeat the process</strong></p>
<p>I have used a Linux VM to run this script. And so, a CRON job has been set up and scheduled to run on a daily basis at a specific time. This job runs the node script and sends out a text message with the latest status of my Case.</p>
<p>This CRON job can also be set up on any local Raspberry PI computer or any old computer. ** On windows a task scheduler does the similar trick.</p>
<p>When this is all put together, it works seamlessly and makes it convenient to track the status automatically.</p>
<blockquote>
<p>Based on the operating system and version, puppeteer might run into issues while initializing a headless browser. Use the debug options available to get around the issue.</p>
<p>Note: USCIS uses cloudflare bot prevention mechanism. This may cause the script to fail as it does not by pass the cloudflare verification page.</p>
</blockquote>
<p>Cheers ✌</p>
]]></content:encoded></item><item><title><![CDATA[Integrate Pega with Azure Service Bus]]></title><description><![CDATA[This article details about how a message is posted to Azure Service Bus Queue from a Pega application using a HTTP protocol.
Primary focus of this article is on how the headers are constructed and message is sent using Connect-Rest method. The constr...]]></description><link>https://blog.nidri.dev/integrate-pega-with-azure-service-bus</link><guid isPermaLink="true">https://blog.nidri.dev/integrate-pega-with-azure-service-bus</guid><category><![CDATA[pega]]></category><category><![CDATA[azure service bus queues]]></category><category><![CDATA[Azure]]></category><category><![CDATA[Java]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Mon, 04 Mar 2024 05:21:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1732921241823/ad2765f5-7e9a-49aa-8a90-7803067d3f7c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article details about how a message is posted to Azure Service Bus Queue from a Pega application using a HTTP protocol.</p>
<p>Primary focus of this article is on how the headers are constructed and message is sent using Connect-Rest method. The construction of headers logic is same and can be used to other operations not only on Service Bus integration but also with other Azure services (with slight modifications)</p>
<p>Things needed for this integration:</p>
<ul>
<li><p>A Pega application (with outbound internet connection)</p>
</li>
<li><p>An Azure Service Bus with at least one queue</p>
</li>
<li><p>Necessary permissions and roles to post message to queue</p>
</li>
</ul>
<p>Steps involved:</p>
<ol>
<li><p>Gather and prepare required properties</p>
</li>
<li><p>Construct Authorization header</p>
</li>
<li><p>Call the rest connector to post message</p>
</li>
</ol>
<h3 id="heading-gather-and-prepare-required-properties">Gather and prepare required properties</h3>
<p>In this step, collect all the required properties of service bus queue after all the required permissions are granted.</p>
<p>A http queue url, SharedAccessKey are required to proceed further.</p>
<p>The http queue url can be grabbed from the Queue properties in the Azure portal. It will be in this format.</p>
<pre><code class="lang-plaintext">// Replace __SERVICEBUSNAMESPACE__ and __QUEUE__ with your values.
https://__SERVICEBUSNAMESPACE__.servicebus.windows.net/__QUEUE__
</code></pre>
<p>Collect the SharedAccessKey from the Azure portal Service Bus Queue properties. If required, coordinate with your Azure administrator to generate one.</p>
<h3 id="heading-construct-authorization-header">Construct Authorization header</h3>
<p>This is the crucial part of the implementation. Azure Rest API services require the authorization header to be constructed and passed in a certain format. This is something common across most of the Azure services.</p>
<p>Go through this <a target="_blank" href="https://learn.microsoft.com/en-us/rest/api/servicebus/send-message-to-queue#request-headers">documentation</a> on the requirement for constructing the authorization header for Azure services. We will be generating a <a target="_blank" href="https://learn.microsoft.com/en-us/rest/api/eventhub/generate-sas-token">SAS token</a> for this use case.</p>
<p>"Java step"</p>
<p>In order to generate a SAS token, we will be needing crypto and hashing functions. So to use them, we will need to write some java code.</p>
<pre><code class="lang-java"><span class="hljs-comment">// Replace __SERVICEBUSNAMESPACE__ and __QUEUE__ with your values.</span>
String strURL = <span class="hljs-string">"https://__SERVICEBUSNAMESPACE__.servicebus.windows.net/__QUEUE__"</span>;
String keyName = <span class="hljs-string">"Send"</span>; <span class="hljs-comment">// Shared key name. This is a constant required to post a message.</span>
<span class="hljs-comment">// Replace __SHAREDACCESSKEY__ with your value.</span>
String key = <span class="hljs-string">"__SHAREDACCESSKEY__"</span>; <span class="hljs-comment">// Shared Access Key from Azure portal</span>
<span class="hljs-keyword">long</span> epoch = System.currentTimeMillis()/<span class="hljs-number">1000L</span>;
<span class="hljs-keyword">int</span> week = <span class="hljs-number">60</span>*<span class="hljs-number">60</span>*<span class="hljs-number">24</span>*<span class="hljs-number">7</span>;
String ttl = Long.toString(epoch + week);
<span class="hljs-keyword">byte</span>[] keyBytes = key.getBytes();
<span class="hljs-keyword">try</span> {
  String encodedURL = java.net.URLEncoder.encode(strURL, <span class="hljs-string">"UTF-8"</span>);
  String strToSign = encodedURL + <span class="hljs-string">"\n"</span> + ttl;
  javax.crypto.Mac sha256_HMAC = javax.crypto.Mac.getInstance(<span class="hljs-string">"HmacSHA256"</span>);
  javax.crypto.spec.SecretKeySpec secret_key = <span class="hljs-keyword">new</span> javax.crypto.spec.SecretKeySpec(keyBytes, <span class="hljs-string">"HmacSHA256"</span>);
  sha256_HMAC.init(secret_key);
  <span class="hljs-keyword">byte</span>[] rawHmac = sha256_HMAC.doFinal(strToSign.getBytes(<span class="hljs-string">"UTF-8"</span>));
  String hash = org.apache.commons.codec.binary.Base64.encodeBase64String(rawHmac);
  String encodedHash = java.net.URLEncoder.encode(hash, <span class="hljs-string">"UTF-8"</span>);
  String sasToken = <span class="hljs-string">"SharedAccessSignature sr="</span> + encodedURL + <span class="hljs-string">"&amp;sig="</span> + encodedHash + <span class="hljs-string">"&amp;se="</span> + ttl + <span class="hljs-string">"&amp;skn="</span> + keyName;
  tools.putParamValue(<span class="hljs-string">"sasToken"</span>, sasToken); <span class="hljs-comment">// Put the generated token onto a parameter</span>
}
<span class="hljs-keyword">catch</span> (java.security.NoSuchAlgorithmException e) {
  e.printStackTrace();
}
<span class="hljs-keyword">catch</span> (Exception e){
  System.out.println(<span class="hljs-string">"Error - "</span> + e.getMessage());
}
</code></pre>
<p>The above code will generate a token and put onto "sasToken" parameter. This parameter will be later used in the REST connector to set it to Authorization header.</p>
<blockquote>
<p>It is recommended to use Rule Utility Function instead of Java step in the Activity rule.</p>
</blockquote>
<h3 id="heading-call-the-rest-connector-to-post-message">Call the rest connector to post message</h3>
<p>Now, the final part is to call the REST service to post the message to queue. The documentation for the same can be found in this <a target="_blank" href="https://learn.microsoft.com/en-us/rest/api/servicebus/send-message-to-queue">link</a>.</p>
<p>"Connect-Rest rule"</p>
<p>Create a Connect-REST rule and provide the base url and resource path.</p>
<pre><code class="lang-plaintext">// Base url. Replace __SERVICEBUSNAMESPACE__ with your value.
http{s}://__SERVICEBUSNAMESPACE__.servicebus.windows.net

// Resource path. Replace __QUEUE__ with your values.
/__QUEUE__/messages
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709527650556/063acd8e-2997-4493-bc79-b537af651994.png" alt="Connect-REST rule with base url and resource path" class="image--center mx-auto" /></p>
<p>Next, supply the details in POST method. Authorization, BrokerProperties and Content-Type are minimum required headers. Check the documentation for more options. May have variations depending on setup and requirements.</p>
<p>BrokerProperties contain identifiers and some necessary values. Refer to this <a target="_blank" href="https://learn.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.brokeredmessage?view=azure-dotnet-legacy">link</a> for more details.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709528224961/033854cd-0acf-4035-b7ac-6ae5f797ee80.png" alt="Headers to be supplied in Connect-REST rule POST method" class="image--center mx-auto" /></p>
<p>Finally, set the request body.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709528323850/098c7ea4-bc48-4c1f-bfa2-5346f35fb49f.png" alt="Setting request body through a parameter reference" class="image--center mx-auto" /></p>
<p>In the above screenshot, the BrokerProperties in the header(Param.BrokerProperties) and the Request message in the Message data(Param.RequestMessage) were referenced through parameters. The values for these parameters were set in the Activity prior to calling this Connect-REST rule.</p>
<p>Both the parameters were set with JSON strings.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1709528671901/307e1a77-5ac6-407d-9f18-e338f6c44c25.png" alt="Activity to set required Parameters and call Connector rule." class="image--center mx-auto" /></p>
<p>The above screenshot is the activity that constructs required Parameters and call the Connect-REST rule.</p>
<p>First step sets the values to parameters in JSON strings format.</p>
<p>Second step is to construct the Authorization header value (Java snippet in the above section)</p>
<p>Third step is to call the Connect-REST rule with POST method.</p>
<p>If everything is setup correctly and the activity is run, the service will return 201 http status code which is a success.</p>
<p>Similarly, other operations on the Service Bus queues/topics can be performed with slight modifications.</p>
<p>Hope this helps!! Give it a try and feel free to reach out with any questions.</p>
<p>Cheers!!</p>
]]></content:encoded></item><item><title><![CDATA[How to create an Azure virtual desktop (Windows 11)]]></title><description><![CDATA[Microsoft Azure has a virtual desktop feature that comes with Windows 11 or other server platforms and with an optional suite of Microsoft apps.
Windows 11 virtual desktops are very useful for accessing from anywhere in the world. They can be connect...]]></description><link>https://blog.nidri.dev/how-to-create-an-azure-virtual-desktop-windows-11</link><guid isPermaLink="true">https://blog.nidri.dev/how-to-create-an-azure-virtual-desktop-windows-11</guid><category><![CDATA[Azure]]></category><category><![CDATA[virtual machine]]></category><category><![CDATA[desktop]]></category><category><![CDATA[Windows]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Fri, 09 Jun 2023 10:49:35 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1685235854288/89ddd0a4-a643-43bb-a0c4-c9f7b75f1044.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Microsoft Azure has a virtual desktop feature that comes with Windows 11 or other server platforms and with an optional suite of Microsoft apps.</p>
<p>Windows 11 virtual desktops are very useful for accessing from anywhere in the world. They can be connected through the browser, remote desktop app and even on mobile devices too.</p>
<p>Different entities created as part of virtual desktop creation are:</p>
<ol>
<li><p>Azure subscription</p>
</li>
<li><p>Resource group</p>
</li>
<li><p>Workspace</p>
</li>
<li><p>Host pool</p>
</li>
<li><p>Application Group</p>
</li>
<li><p>Virtual desktop</p>
</li>
</ol>
<p>To start with, an Azure account is required. If not done already, a new account needs to be registered at <a target="_blank" href="https://portal.azure.com">Azure Portal</a>. Complete the registration process (registration information, payment process etc.)</p>
<p>A default subscription may be created during the initial registration, either it can be used or a new subscription can be created for the virtual desktop. Call it 'AVD-SUB' for this example.</p>
<blockquote>
<p>An active subscription is required to create any resource in Azure</p>
</blockquote>
<p>Next, create a resource group under the subscription selected/created in the above step. Call it 'AVD-SUB-RG' for this example. After that, create a new Azure virtual network(search for "virtual network" in the Azure portal) and call it 'AVD-VIRTUAL-NETWORK'.</p>
<p>Make sure to select the right subscription (AVD-SUB) and resource group (AVD-SUB-RG) for this new virtual network. Select the region closest or appropriate to your usage.</p>
<p>Next, search for Azure Virtual Desktop and open the section. Start with creating a host pool. Select the subscription, and resource group and give it the name 'AVD-HP' for this example.</p>
<p>Select the host pool type as 'Personal', this will create one machine per login. Select the region same as the virtual network created in the above step. In the next steps, skip creating the Virtual machine and Workspace by selecting the option 'No' and complete the Host pool creation.</p>
<h3 id="heading-session-hosts">Session Hosts</h3>
<p>To create a session host(virtual desktop), go to the host pool and select 'Session hosts' and create one.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686303341501/6bb2eb03-1561-4e6d-866a-158e46089dba.png" alt="Session hosts page under host pool" class="image--center mx-auto" /></p>
<ul>
<li><p>Select the same subscription, resource group and location as before.</p>
</li>
<li><p>Select the Image as 'Windows 11' (or of your choice) and the machine size according to your need.</p>
</li>
<li><p>Give the number of VMs as 1.</p>
</li>
<li><p>Select the virtual network created in the above steps.</p>
</li>
<li><p>Under Domain to join, select 'Azure Active Directory' and provide details for the Administrator account.</p>
</li>
</ul>
<p>Leave all other settings as they are and create the virtual machine.</p>
<p>Now, under the host pool, select Application Groups and select the one that is created by the system. Then, go to Assignments from the menu and add a new assignment. Select the user(s) and submit.</p>
<p>The next step is to assign a role for these user(s) to access the virtual desktop. For that, go to the resource group (AVD-SUB-RG) and select Access Control (IWM) from the menu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686304763509/18df07d6-3f0b-48e8-9473-75d4ebea39a7.png" alt class="image--center mx-auto" /></p>
<p>Go to Role assignments and add a new role assignment. Select 'Virtual Machine User Login' and add the user(s) under members. Review and complete the assignment process. Repeat the role assignment for 'Virtual Machine Administrator Login' to assign admin user(s).</p>
<h3 id="heading-workspaces">Workspaces</h3>
<p>Workspace is a section to host the remote desktop and any other apps. These will be accessed from the web session or through an app. To enable remote desktop for the virtual desktop created, it needs to be listed in the workspace.</p>
<p>Go to Azure Virtual Desktop and navigate to Workspaces from the menu.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686305645628/5e95232f-dc3a-443e-b1a6-3e2c6ce56ed1.png" alt class="image--center mx-auto" /></p>
<p>Add a new workspace, select the right subscription, resource group and region and finish the creation process leaving other settings as is.</p>
<p>Now, go to the newly created workspace and navigate to Application Groups from the menu. Add a new Application group and select the one created by the system as part of Session host creation and finish the process.</p>
<h3 id="heading-rdp-properties">RDP Properties</h3>
<p>Go to the host pool and select RDP Properties from the menu. Here you can alter the settings for how the virtual desktop should work and perform. One important step is to make sure a specific setting is there in the Advanced section.</p>
<p>Check for the setting <code>targetisaadjoined:i:1;</code> under RDP properties under the Advanced section. If not already present add this to the beginning of the text present in the box.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1686306280998/07920470-c700-4869-9d9f-1a0cfad0e202.png" alt class="image--center mx-auto" /></p>
<p>Now all the steps are completed. Make sure the virtual desktop is created and running (host pool dashboard page)</p>
<h3 id="heading-launch-the-virtual-desktop">Launch the virtual desktop</h3>
<ul>
<li><p>Go to <a target="_blank" href="https://aka.ms/avdweb">https://aka.ms/avdweb</a></p>
</li>
<li><p>Login with virtual desktop credentials provided.</p>
</li>
<li><p>The desktop will be displayed under Workspace.</p>
</li>
<li><p>Click and it will start a remote session to the virtual desktop.</p>
</li>
<li><p>If needed login with the user credentials created during setup.</p>
</li>
</ul>
<p>Hope you got the setup right and can launch the desktop successfully. There are also some youtube tutorials on setting up the Azure Virtual Desktop. Check them too.</p>
<p><a target="_blank" href="https://youtu.be/aPEibGMvxZw">https://youtu.be/aPEibGMvxZw</a></p>
<p><a target="_blank" href="https://www.youtube.com/watch?v=jMAanEp-ugI&amp;t=60s">https://www.youtube.com/watch?v=jMAanEp-ugI&amp;t=60s</a></p>
<p>If you are Enterprise level systems administrator, you may want to check this book on how to manage Azure Virtual Desktop Environments. <a target="_blank" href="https://amzn.to/41VU7ZT">Link to Book</a></p>
<p>Feel free to leave a suggestion or comment. Thank you until next time.</p>
]]></content:encoded></item><item><title><![CDATA[Starting career as a fresher?]]></title><description><![CDATA[Primary objective
When you start in the software industry or any industry for that matter, your primary focus should only be on learning. Learn as much as you can, gain knowledge and give your best at work.

Use all the resources available, talk to y...]]></description><link>https://blog.nidri.dev/starting-career-as-a-fresher</link><guid isPermaLink="true">https://blog.nidri.dev/starting-career-as-a-fresher</guid><category><![CDATA[Career]]></category><category><![CDATA[job]]></category><category><![CDATA[#DevRetro2022]]></category><category><![CDATA[career advice]]></category><category><![CDATA[General Advice]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Thu, 29 Dec 2022 17:11:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1672333142451/88e8b157-10b3-453d-8ccf-9e5fca9f3d83.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-primary-objective">Primary objective</h2>
<p>When you start in the software industry or any industry for that matter, your primary focus should only be on learning. Learn as much as you can, gain knowledge and give your best at work.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672332080621/52ca42b4-dce0-4c01-b5bf-24d42c42bcb7.jpeg" alt class="image--center mx-auto" /></p>
<p>Use all the resources available, talk to your mentors, peers or anyone and know a new thing every day. It is also important to share what you learned with others. Don’t keep it to yourself.</p>
<p>There are plenty of resources related to your field of work in form of books, videos, courses etc. Check out them, learn and gain proficiency in your area of interest.</p>
<h2 id="heading-money-is-not-a-priority">Money is not a priority</h2>
<p>When you start earning, you start to think about financial goals, commitments and spending on fantasies. This sometimes leads to a mindset where you feel like what you are earning is not enough.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672332505422/e5be512a-529b-4d43-bbea-ccc84c7e71df.png" alt class="image--center mx-auto" /></p>
<p>Clear your mind about money and focus on your journey. Give your best in the initial years of your career and things will eventually turn out for you.</p>
<p>Once you flow through your career, several opportunities will come to you and slowly those convert into investments. Being diligent is the key.</p>
<p>As the time passes by and you accumulate some money, learn new things about investing and start with the money you earned so far.</p>
<p>Some of the recommended books on investing in stocks can be found <a target="_blank" href="https://amzn.to/3X6kWc3">in this link</a>, check them out.</p>
<h2 id="heading-do-not-compare-with-others">Do not compare with others</h2>
<p>Never compare yourself to anyone in any aspect. Your only objective should be learning and giving your best. Gain as much knowledge as you can and share the same with others. This will help you grow and makes you a better engineer.</p>
<h2 id="heading-get-the-right-tools">Get the right tools</h2>
<p>Having the right tools for your job and learning purpose is very important and makes a lot of difference. It also motivates to push further. If you are in software industry, get you self a nice laptop, <a target="_blank" href="https://amzn.to/41274kf">monitor</a>, <a target="_blank" href="https://amzn.to/414IXBh">back pack</a>. No need to go crazy and spend lot of money., just decent enough stuff should do the work.</p>
<p>And of course a <a target="_blank" href="https://amzn.to/3X7O1UB">nice water bottle</a> to stay hydrated.</p>
<h2 id="heading-do-not-change-jobs">Do not change jobs</h2>
<p>After a year or two, you may start feeling like you have done enough at your current workplace and it is time to change jobs. Unless you have a strong reason to change, do not think about a job change for at least 4-5 years. Because it is going to be an almost fresh start again at the new workplace.</p>
<p>Gain the knowledge and experience and when the time comes(have a good reason), make a move.</p>
<h2 id="heading-go-all-in-at-work">Go all in at work</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672332877313/9e754058-14e0-4ccc-80cd-191d240e0972.png" alt class="image--center mx-auto" /></p>
<p>When you start as a fresher, your primary objective should be learning and giving your best at work. It is not just an 8-hour job, stretch for long hours, spend more time at work and try to finish it with quality. Do not have a mindset like you have to work only regular hours.</p>
<h2 id="heading-it-all-pays-off-in-future">It all pays off in future</h2>
<p>All the hard work you did initially in your career is going to pay off in the future. The more knowledge and experience, the better future you will have.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1672332970272/606f0333-9b61-4d2e-90ec-79ff65118154.png" alt class="image--center mx-auto" /></p>
<p>Share your thoughts and tips with other new comers. Take care!!</p>
]]></content:encoded></item><item><title><![CDATA[Refer datapage with parameters in HTML rule in Pega]]></title><description><![CDATA[We might have come across or probably used pega: reference jsp tag to refer properties in HTML rules like Fragment, Correspondence, Paragraph etc.
There could be a scenario where we have to refer a parameterized Datapage in a HTML rule. But the synta...]]></description><link>https://blog.nidri.dev/refer-datapage-with-parameters-in-html-rule-in-pega</link><guid isPermaLink="true">https://blog.nidri.dev/refer-datapage-with-parameters-in-html-rule-in-pega</guid><category><![CDATA[pega]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[HTML]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Thu, 20 Oct 2022 05:28:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1666240557707/XEAZTpajS.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>We might have come across or probably used <code>pega: reference</code> jsp tag to refer properties in HTML rules like Fragment, Correspondence, Paragraph etc.</p>
<p>There could be a scenario where we have to refer a parameterized Datapage in a HTML rule. But the syntax to access or refer a Datapage with parameters doesn't work.</p>
<pre><code class="lang-plaintext">D_PageName[param1: value1, param2: value2].PropertyName
</code></pre>
<p>However, there is a workaround to refer properties from parameterized Datapages.</p>
<blockquote>
<p>Note: It is not recommended to use this method. Better way is to construct a new Datapage or a normal page with all values and use as reference in HTML rule.</p>
</blockquote>
<p>By setting the required parameters using java scriplet prior to using a reference tag, system will load the Datapage and the properties will be constructed in HTML rule.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667068632496/BXeK9UzjR.png" alt="Screenshot of code snippet in HTML" /></p>
<pre><code class="lang-plaintext">&lt;!-- Sample snippet to refer parameterized Datapages --&gt;

&lt;%
   // Set all parameters required for datapage
  tools.putParamValue("OperatorId", "administrator@pega.com");
 // Set all other params required for datapage
%&gt;
    &lt;div&gt;
        &lt;h1&gt;Referencing Parameterized Data Page in HTML Rule&lt;/h1&gt;
        &lt;div&gt;
            Name: &lt;pega:reference name="D_pxOperatorDetails.pyUserName" /&gt;
        &lt;/div&gt;
      &lt;div&gt;
            Email: &lt;pega:reference name="D_pxOperatorDetails.pyAddresses(Email).pyEmailAddress" /&gt;
        &lt;/div&gt;
      &lt;div&gt;
            TimeZone: &lt;pega:reference name="D_pxOperatorDetails.pyDefaultTimeZone" /&gt;
        &lt;/div&gt;
    &lt;/div&gt;
</code></pre>
<h4 id="heading-and-the-result-looks-like-this">And the result looks like this</h4>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667068557945/Y50szZ_t3.png" alt="End result of Datapage with params in HTML" /></p>
<p>Hope this helps and be very careful to refer properties from parameterized Datapage using this method. This is not supported and there is no official documentation.</p>
<p>If there any questions, feel free to reach me.</p>
<p>Cheers!</p>
]]></content:encoded></item><item><title><![CDATA[Speech to text in Pega]]></title><description><![CDATA[Pega applications have evolved and are being used on all kinds of devices - desktop, tablets, mobile etc. It is important to incorporate the latest technologies into the application to make the user experience better. 
With speech recognition API, us...]]></description><link>https://blog.nidri.dev/speech-to-text-in-pega</link><guid isPermaLink="true">https://blog.nidri.dev/speech-to-text-in-pega</guid><category><![CDATA[pega]]></category><category><![CDATA[prpc]]></category><category><![CDATA[Web API]]></category><category><![CDATA[speech to text]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Fri, 19 Aug 2022 10:23:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1658271916519/T7uZsSotg.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Pega applications have evolved and are being used on all kinds of devices - desktop, tablets, mobile etc. It is important to incorporate the latest technologies into the application to make the user experience better. 
With speech recognition API, use cases like taking a note, drafting an email etc. can be achieved.</p>
<h2 id="heading-let-us-see-how-we-can-implement-this-speech-recognition-api">Let us see how we can implement this speech recognition API</h2>
<p>We shall modify Pega pulse in such a way that it takes notes by listening to user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660806930564/tmsv-tTIP.png" alt="Screenshot 2022-08-18 12.37.14.png" /></p>
<p>We will be using <code>Web speech API</code> for this use case. To learn more about this API, please check this <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API">MDN Documentation</a></p>
<p>For this use case we need a javascript file. This file will contain functions and logic to invoke speech recognition API. These functions will convert speech into text and assign the text to textarea in Pulse section.</p>
<h3 id="heading-steps-to-configure-speech-recognition-api">Steps to configure speech recognition API</h3>
<ol>
<li><p>Modify Pega pulse section and include two buttons 'Start' and 'Stop'. These buttons will activate and  deactivate speech  recognition. Add two empty labels in the same section.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660900970698/gupcCLF_X.png" alt="Screenshot 2022-08-19 14.52.28.png" /></p>
</li>
<li><p>Give Tour ID's to these two buttons and labels.</p>
<ul>
<li>Start button - startSpeech</li>
<li>Stop button - stopSpeech</li>
<li>Label1 - speechInterim</li>
<li>Label2 - speechStatus
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660901177501/QepstiHn2.png" alt="Screenshot 2022-08-19 14.53.38.png" />
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660902312017/INrvMsSok.png" alt="Screenshot 2022-08-19 15.14.48.png" /></li>
</ul>
</li>
<li><p>Provide a tour id of value 'pulseNote' to textarea field in Pega pulse section.</p>
</li>
<li><p>Create a javascript binary file in Pega and include this .js file in scripts and styles tab of container harness rule.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660901345318/aBRtVf6G5.png" alt="Screenshot 2022-08-19 14.58.48.png" /></p>
</li>
<li><p>Get the code from this <a target="_blank" href="https://gist.github.com/nidri/9cc39b0d4b1d99e7ef9261afdfd5aadb">Gist</a> and paste in the javascript file and save the rule.</p>
</li>
<li><p>Save all the rules and test the functionality. When the start button is clicked for the first time, browser will ask permission for microphone. Make sure this permission is granted. </p>
</li>
</ol>
<p>At this point, browser will capture your speech and convert it to text and assign this text to textarea in Pega pulse section. To stop the speech recognition, just click on Stop button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1660903530452/3XZHu8Ek4.gif" alt="pega-speechrecognition.gif" /></p>
<p>It is just a sample to get started with, this speech recognition can be applied to wide range of use cases in Pega workflows and in non pega applications as well.</p>
<p>I hope this gave a good idea to explore browser API's in Pega applications and would like to hear other interesting use cases you applied this API in.</p>
<p>Reach out to me if you encounter any issues or have any questions.</p>
<p>Thank you.</p>
]]></content:encoded></item><item><title><![CDATA[How to set custom cookie in Pega PRPC]]></title><description><![CDATA[Sometimes there will be a requirement to capture certain user action. One of the use case of this kind would be where a user is displayed with a pop up with some information (like new features or updates). User can then read it and close the pop up a...]]></description><link>https://blog.nidri.dev/how-to-set-custom-cookie-in-pega-prpc</link><guid isPermaLink="true">https://blog.nidri.dev/how-to-set-custom-cookie-in-pega-prpc</guid><category><![CDATA[pega]]></category><category><![CDATA[prpc]]></category><category><![CDATA[cookies]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Tue, 08 Feb 2022 04:51:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1654149156779/aZ0St5wHs.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Sometimes there will be a requirement to capture certain user action. One of the use case of this kind would be where a user is displayed with a pop up with some information (like new features or updates). User can then read it and close the pop up and then it will not be displayed until next time (new update or release). </p>
<p>In the above use case, the information about user closing the pop up needs to be captured and stored. This is where the concept of cookies play well and is apt for this requirement.</p>
<blockquote>
<p>Be cautious with cookies as they can have adverse effects  </p>
</blockquote>
<p>A custom cookie in a <code>Pega</code> application can be set in one line</p>
<pre><code>tools.getRequestor().getRequestorPage().getPage(<span class="hljs-string">"pyHTTPResponseHeaders"</span>)
.putString(<span class="hljs-string">"set_cookie"</span>, <span class="hljs-string">"customCookie=someValue; Path=/prweb; Secure;"</span>);
</code></pre><hr />
<p>Cookie has to be set on <em>pyHttpResponseHeaders</em> page property on <em>pxRequestor</em> page. Use <em>set_cookie</em> property to set cookie value. </p>
<hr />
<p>But where does this line go? </p>
<p>This has to be placed in a <code>Java</code> step in an activity that is called from UI. It can be on click of a button or from <code>XHR</code> or <code>fetch</code> request.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644293923634/P1EPpu624.png" alt="activity_image.png" /></p>
<p><a target="_blank" href="https://gist.github.com/nidri/4db50f71cbf36037c8b6eeca1c8703df">Link to code</a></p>
<p>When this activity is invoked, the cookie will be sent in response. It can be verified in browser developer tools.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1644294134161/2ZBYKVX-t.png" alt="cookies_image.png" /></p>
<p>There should also be a logic in application to set or reset value of this cookie whenever user takes action. For example, in the above use case, when user closes the pop up, the value of cookie should be updated to indicate that pop up has been closed. </p>
<p>This way when the same user logs in to application again, pop up will not be displayed. The logic to check the cookie value and decide whether to show pop up or not should be implemented manually, most likely this code goes into <code>Javascript</code> file in portal harness. But it may differ based on application needs and design.</p>
<p>Lastly, there should be application logic to reset this cookie value, so that user will get the pop up again (Ex: when a new feature is introduced in next release). </p>
<blockquote>
<p>Use custom cookies diligently and only when required. Pega doesn't recommend to use custom cookies as they may impact overall application</p>
</blockquote>
<p>Feel free to leave a suggestion or comment. Thank you until next time.</p>
]]></content:encoded></item><item><title><![CDATA[Connect to Azure Cache For Redis with NodeJS]]></title><description><![CDATA[This article only highlights the way to connect to Azure Redis server from NodeJS. For full list of commands and usage please refer to  Redis and  Microsoft documentation
At the time of this article is published, the version of Redis is 4.0.1

To con...]]></description><link>https://blog.nidri.dev/connect-to-azure-cache-for-redis-with-nodejs</link><guid isPermaLink="true">https://blog.nidri.dev/connect-to-azure-cache-for-redis-with-nodejs</guid><category><![CDATA[Redis]]></category><category><![CDATA[Azure]]></category><category><![CDATA[cache]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Krishna Santosh Nidri]]></dc:creator><pubDate>Sat, 25 Dec 2021 15:31:14 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1660935469897/JABFT0K3x.jpg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<blockquote>
<p>This article only highlights the way to connect to Azure Redis server from NodeJS. For full list of commands and usage please refer to  <a target="_blank" href="https://www.npmjs.com/package/redis">Redis</a> and  <a target="_blank" href="https://docs.microsoft.com/en-us/javascript/api/overview/azure/redis-cache?view=azure-node-latest">Microsoft</a> documentation</p>
<p>At the time of this article is published, the version of Redis is <a target="_blank" href="https://www.npmjs.com/package/redis/v/4.0.1">4.0.1</a></p>
</blockquote>
<p>To connect to Azure Redis server using host name and primary key, Microsoft clearly described how to create a Redis client in their Javascript  <a target="_blank" href="https://docs.microsoft.com/en-us/azure/azure-cache-for-redis/cache-nodejs-get-started">sample</a> .</p>
<pre><code><span class="hljs-string">const</span> <span class="hljs-string">client</span> <span class="hljs-string">=</span> <span class="hljs-string">redis.createClient(6380,</span> <span class="hljs-string">hostName,</span> 
{<span class="hljs-attr">auth_pass:</span> <span class="hljs-string">azureKey</span>, <span class="hljs-attr">tls:</span> {<span class="hljs-attr">servername:</span> <span class="hljs-string">hostName</span>}}<span class="hljs-string">);</span>
</code></pre><p>However, this works only until Redis version 3.0.0. In the later versions of Redis, the mechanism of passing parameters to createClient has changed. The parameters are now required to be passed in below format.</p>
<pre><code><span class="hljs-string">const</span> <span class="hljs-string">client</span> <span class="hljs-string">=</span> <span class="hljs-string">redis.createClient({</span>
    <span class="hljs-attr">socket:</span> {
        <span class="hljs-attr">host:</span> <span class="hljs-string">hostName</span>,
        <span class="hljs-attr">port:</span> <span class="hljs-number">6380</span>,
        <span class="hljs-attr">tls:</span> <span class="hljs-literal">true</span>
    }<span class="hljs-string">,</span>
    <span class="hljs-attr">password:</span> <span class="hljs-string">azureKey,</span>
<span class="hljs-string">});</span>
</code></pre><blockquote>
<p><strong>It is also required to call connect method on the client object. Otherwise the connection will not be established</strong></p>
</blockquote>
<pre><code>client.connect();
</code></pre>]]></content:encoded></item></channel></rss>