Get Handset Change Events
Handset Change events are triggered whenever a SIM card is moved from one handset to another. This happens triggered when the SIM card is inserted into a new handset and the handset is turned on.
Prerequisites
Required Scope
subscription.handset_details:read
Code Dependencies
<dependency>
<groupId>com.wgtwo.api.v1.grpc</groupId>
<artifactId>subscription</artifactId>
<version>1.10.1</version>
</dependency>
Code
If targeting production, you would need to add authentication to the sample code.
#!/usr/bin/env bash
grpcurl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '
{
"stream_configuration": {
"regular": {},
"disable_explicit_ack": {}
}
}
' \
sandbox.api.shamrock.wgtwo.com:443 \
wgtwo.subscription.v1.SubscriptionEventService/StreamHandsetChangeEvents
package com.example.handsetchange
import com.wgtwo.api.v1.subscription.SubscriptionEventServiceGrpc
import com.wgtwo.api.v1.subscription.SubscriptionEventsProto.AckHandsetChangeEventRequest
import com.wgtwo.api.v1.subscription.SubscriptionEventsProto.StreamHandsetChangeEventsRequest
import com.wgtwo.api.v1.subscription.SubscriptionEventsProto.StreamHandsetChangeEventsResponse
import io.grpc.ManagedChannelBuilder
import io.grpc.StatusRuntimeException
import java.util.concurrent.Executors
private const val MAX_IN_FLIGHT = 10
private val channel = ManagedChannelBuilder.forAddress("sandbox.api.shamrock.wgtwo.com", 443).build()
private val stub = SubscriptionEventServiceGrpc.newBlockingStub(channel)
private val executor = Executors.newFixedThreadPool(MAX_IN_FLIGHT)
fun main() {
while (!channel.isShutdown) {
try {
subscribe()
} catch (e: StatusRuntimeException) {
println("Got exception: ${e.status} - Reconnecting in 1 second")
Thread.sleep(1000)
}
}
}
private fun subscribe() {
println("Starting subscription")
val request = StreamHandsetChangeEventsRequest.newBuilder().apply {
streamConfigurationBuilder.maxInFlight = MAX_IN_FLIGHT
}.build()
stub.streamHandsetChangeEvents(request).forEach { response ->
// Using an executor to handle up to MAX_IN_FLIGHT messages in parallel
executor.submit {
handleResponse(response)
ack(response)
}
}
}
private fun handleResponse(response: StreamHandsetChangeEventsResponse) {
println("Got response:
$response")
}
private fun ack(response: StreamHandsetChangeEventsResponse) {
val ackInfo = response.metadata.ackInfo
val request = AckHandsetChangeEventRequest.newBuilder().setAckInfo(ackInfo).build()
stub.ackHandsetChangeEvent(request)
}
Example Result
{
"metadata": {
"timestamp": "2021-09-30T14:27:55.468Z",
"identifier": {
"subscriptionIdentifier": {
"value": "ce78..."
}
},
"ackInfo": {
"value": "Ch5..."
}
},
"handsetChangeEvent": {
"previous": {
"imeiSv": {
"imei": "867...",
"softwareVersion": "64"
}
},
"current": {
"imeiSv": {
"imei": "867...",
"softwareVersion": "65"
}
},
"number": {
"e164": "479..."
},
"imsi": {
"value": "Rn..."
}
}
}
metadata {
timestamp {
seconds: 1635326429
nanos: 93000000
}
identifier {
subscription_identifier {
value: "dummy:se:0"
}
}
}
handset_change_event {
previous {
imei_sv {
imei: "359237066557492"
software_version: "00"
}
}
current {
imei_sv {
imei: "353752084447134"
software_version: "00"
}
}
number {
e164: "479..."
}
imsi {
value: "33"
}
}
# Ack success
metadata {
timestamp {
seconds: 1635326429
nanos: 193000000
}
identifier {
subscription_identifier {
value: "dummy:se:0"
}
}
}
handset_change_event {
previous {
imei_sv {
imei: "353752084447134"
software_version: "00"
}
}
current {
imei_sv {
imei: "355330105977849"
software_version: "00"
}
}
number {
e164: "479..."
}
imsi {
value: "33"
}
}
# Ack success