Get first attachment events
The first attachment event will be triggered for each SIM card the first time it connects (attaches) to a mobile network. This happens as soon as the phone is connected to a mobile network.
Note that only operators and third party products enabled by default, that have rights regarding the subscriber before they initially attach, can get this event, as the event is created before the subscriber can authenticate in the products portal.
NOTE that this API responds with the IMSI for the SIM card in the user's handset. This is considered PII information and needs to be handled with care.
Prerequisites
Required scope
subscription.first_attachment:read
Code
TIP
You can test our APIs without authorization by targetting sandbox.api.wgtwo.com
instead of api.wgtwo.com
and removing any authorization from the request/code sample.
Download proto definitions
curl -sL 'https://github.com/working-group-two/wgtwoapis/blob/master/image.bin?raw=true' -o wgtwo.bin
export ACCESS_TOKEN="my_client_access_token"
grpcurl -protoset wgtwo.bin \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '
{
"stream_configuration": {
"regular": {},
"disable_explicit_ack": {}
}
}
' \
api.wgtwo.com:443 \
wgtwo.subscription.v1.SubscriptionEventService/StreamFirstAttachmentEvents
2
3
4
5
6
7
8
9
10
11
12
13
About stream_configuration
For testing purposes, we include the config:
"stream_configuration": {
"regular": {}, Reading position will not be stored in the server and load is not spread between your clients
"disable_explicit_ack": {} Let events be automatically acked
}
2
3
4
By default, load will automatically be spread between all connections using the same OAuth 2.0 client and you will need to reply with a ack once your service has handled the message. This is also what we would recommend for real production usage.
See configuring event streaming for details.
Example result
{
"firstAttachmentEvent": {
"number": {
"e164": "+47xxxxxxxx",
},
"imsi": {
"value": "24206000010001"
}
}
}
{
"firstAttachmentEvent": {
"number": {
"e164": "+47xxxxxxxx",
},
"imsi": {
"value": "24206000020001"
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Install dependencies
Maven
<dependency>
<groupId>com.wgtwo.api.v1.grpc</groupId>
<artifactId>subscription</artifactId>
<version>1.8.0</version>
</dependency>
search.maven.org/search?q=g:com.wgtwo.api.v1.grpcopen in new window
package com.example.firstattachment
import com.wgtwo.api.v1.subscription.SubscriptionEventServiceGrpc
import com.wgtwo.api.v1.subscription.SubscriptionEventsProto.AckFirstAttachmentEventRequest
import com.wgtwo.api.v1.subscription.SubscriptionEventsProto.StreamFirstAttachmentEventsRequest
import com.wgtwo.api.v1.subscription.SubscriptionEventsProto.StreamFirstAttachmentEventsResponse
import com.wgtwo.auth.BearerTokenCallCredentials
import io.grpc.ManagedChannelBuilder
import io.grpc.StatusRuntimeException
import java.util.concurrent.Executors
private const val MAX_IN_FLIGHT = 10
private val environment = Environment.SANDBOX
private val endpoint = when (environment) {
Environment.SANDBOX -> "sandbox.api.wgtwo.com"
Environment.PRODUCTION -> "api.wgtwo.com"
}
private val channel = ManagedChannelBuilder.forAddress(endpoint, 443).build()
private val stub = SubscriptionEventServiceGrpc.newBlockingStub(channel).apply {
/**
* If you are not using the sandbox, you need to add credentials.
* The BearerTokenCallCredentials class can be found in our auth library.
*/
if (environment == Environment.PRODUCTION) {
this.withCallCredentials(BearerTokenCallCredentials { "MY_CLIENT_ACCESS_TOKEN" })
}
}
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 = StreamFirstAttachmentEventsRequest.newBuilder().apply {
streamConfigurationBuilder.maxInFlight = MAX_IN_FLIGHT
}.build()
stub.streamFirstAttachmentEvents(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: StreamFirstAttachmentEventsResponse) {
println("Got response:\n$response")
}
private fun ack(response: StreamFirstAttachmentEventsResponse) {
val ackInfo = response.metadata.ackInfo
val request = AckFirstAttachmentEventRequest.newBuilder().setAckInfo(ackInfo).build()
stub.ackFirstAttachmentEvent(request)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
Example result
first_attachment_event {
number {
e164: "+47xxxxxxxx"
}
imsi {
value: "24206000010001"
}
}
# Ack success
first_attachment_event {
number {
e164: "+47xxxxxxxx"
}
imsi {
value: "24206000020001"
}
}
# Ack success
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21