Showing
492 changed files
with
4885 additions
and
0 deletions
line-bot-sdk-java/.codecov.yml
0 → 100644
1 | +codecov: | ||
2 | + notify: | ||
3 | + require_ci_to_pass: no | ||
4 | + | ||
5 | +ignore: | ||
6 | + - 'line-bot-model/src/test' # Workaround for line-bot-model's test source is wrongly included by coverage report. | ||
7 | + | ||
8 | +coverage: | ||
9 | + range: 50..100 | ||
10 | + round: down | ||
11 | + precision: 2 | ||
12 | + status: | ||
13 | + patch: | ||
14 | + default: | ||
15 | + # basic | ||
16 | + target: auto | ||
17 | + threshold: null | ||
18 | + base: auto | ||
19 | + # advanced | ||
20 | + branches: null | ||
21 | + if_no_uploads: error | ||
22 | + if_not_found: success | ||
23 | + if_ci_failed: error | ||
24 | + only_pulls: false | ||
25 | + flags: null | ||
26 | + paths: null | ||
27 | + | ||
28 | +comment: | ||
29 | + layout: "reach, diff, flags, files" | ||
30 | + behavior: default | ||
31 | + require_changes: false # if true: only post the comment if coverage changes | ||
32 | + require_base: no # [yes :: must have a base report to post] | ||
33 | + require_head: no # [yes :: must have a head report to post] | ||
34 | + branches: null |
line-bot-sdk-java/.editorconfig
0 → 100644
1 | +root=true | ||
2 | + | ||
3 | +[*] | ||
4 | +charset=utf-8 | ||
5 | +end_of_line=lf | ||
6 | +insert_final_newline=true | ||
7 | +trim_trailing_whitespace=true | ||
8 | +indent_style=space | ||
9 | +indent_size=4 | ||
10 | + | ||
11 | +[*.java] | ||
12 | +continuation_indent_size=8 | ||
13 | +wildcard_import_limit=0 | ||
14 | + | ||
15 | +[*.{yaml,yml}] | ||
16 | +indent_size=2 | ||
17 | + | ||
18 | +[*.json] | ||
19 | +indent_size=2 | ||
20 | + | ||
21 | +[*.xml] | ||
22 | +indent_size=2 |
line-bot-sdk-java/.github/ISSUE_TEMPLATE.md
0 → 100644
1 | +## Before creating an issue | ||
2 | + | ||
3 | +- Check [documentation](https://developers.line.me/en/docs/) and [FAQ](https://developers.line.me/en/faq/messaging-api/) page for more information on LINE bots and Messaging API | ||
4 | +- Make sure your issue is **related to** the LINE Bot SDK | ||
5 | +- For general queries about LINE bots, post a question to [LINE developers community](https://www.line-community.me/questions) website | ||
6 | +- Note that we don't provide technical support | ||
7 | + | ||
8 | +## If you still need to create an issue | ||
9 | + | ||
10 | +- Provide detailed information about the issue you are facing with the SDK | ||
11 | +- Provide logs whenever possible | ||
12 | + | ||
13 | +Thank you :) |
1 | +--- | ||
2 | +name: Bug report | ||
3 | +about: Create a report to help us improve | ||
4 | +title: '[BUG]' | ||
5 | +labels: 'bug' | ||
6 | +assignees: 'imasahiro' | ||
7 | + | ||
8 | +--- | ||
9 | + | ||
10 | +## Bug Report | ||
11 | +<!-- First of all: Have you checked the docs https://developers.line.biz/en/docs/messaging-api/overview/, Q&A page https://developers.line.biz/en/faq/, https://www.line-community.me/questions, GitHub issues whether someone else has already reported your issue? --> | ||
12 | + | ||
13 | +**Describe the bug** | ||
14 | +A clear and concise description of what the bug is. | ||
15 | + | ||
16 | +**To Reproduce** | ||
17 | +<!-- It would be appreciate if you share the minimal complete reproducible Java/Kotlin/Scala/Groovy/… code or Repo link: --> | ||
18 | +Steps to reproduce the behavior: | ||
19 | +1. Send message on '...' | ||
20 | +2. Receive message on '....' | ||
21 | +3. Scroll down to '....' | ||
22 | +4. See error | ||
23 | + | ||
24 | +**Expected behavior** | ||
25 | +A clear and concise description of what you expected to happen. | ||
26 | + | ||
27 | +**Screenshots** | ||
28 | +If applicable, add screenshots to help explain your problem. | ||
29 | + | ||
30 | +**Environment (please complete the following information):** | ||
31 | + - OS: [e.g. Ubuntu] | ||
32 | + - JDK Version [e.g. openjdk 1.8.0_211] | ||
33 | + - line-bot-sdk-java version(s) [e.g. 2.6.1] | ||
34 | + | ||
35 | +**Additional context** | ||
36 | +Add any other context about the problem here. |
1 | +--- | ||
2 | +name: Feature request | ||
3 | +about: Suggest an idea for this project | ||
4 | +title: "[Feature Request]" | ||
5 | +labels: feature request | ||
6 | +assignees: imasahiro | ||
7 | + | ||
8 | +--- | ||
9 | + | ||
10 | +## Feature Request | ||
11 | +<!-- First of all: Have you checked the docs https://developers.line.biz/en/docs/messaging-api/overview/, Q&A page https://developers.line.biz/en/faq/, https://www.line-community.me/questions, GitHub issues whether someone else has already reported your issue? --> | ||
12 | + | ||
13 | +**Is your feature request related to a problem? Please describe.** | ||
14 | +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] | ||
15 | + | ||
16 | +**Describe the solution you'd like** | ||
17 | +A clear and concise description of what you want to happen. | ||
18 | + | ||
19 | +**Describe alternatives you've considered** | ||
20 | +A clear and concise description of any alternative solutions or features you've considered. | ||
21 | + | ||
22 | +**Additional context** | ||
23 | +Add any other context or screenshots about the feature request here. |
line-bot-sdk-java/.gitignore
0 → 100644
1 | +# Build output | ||
2 | +target/ | ||
3 | +build/ | ||
4 | +out/ | ||
5 | + | ||
6 | +# gradle | ||
7 | +/.gradle/ | ||
8 | + | ||
9 | +# Mobile Tools for Java (J2ME) | ||
10 | +.mtj.tmp/ | ||
11 | + | ||
12 | +# Package Files # | ||
13 | +*.jar | ||
14 | +*.war | ||
15 | +*.ear | ||
16 | + | ||
17 | +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml | ||
18 | +hs_err_pid* | ||
19 | + | ||
20 | +# IntelliJ | ||
21 | +.idea | ||
22 | +*.iml | ||
23 | +*.iws | ||
24 | +*.ipr | ||
25 | +*.ids | ||
26 | +*.orig | ||
27 | + | ||
28 | +# Eclipse | ||
29 | +*.pydevproject | ||
30 | +.project | ||
31 | +.metadata | ||
32 | +/bin/** | ||
33 | +/tmp/** | ||
34 | +/tmp/**/* | ||
35 | +*.tmp | ||
36 | +*.bak | ||
37 | +*.swp | ||
38 | +*~.nib | ||
39 | +local.properties | ||
40 | +.classpath | ||
41 | +.settings/** | ||
42 | +.loadpath | ||
43 | +/src/main/resources/rebel.xml | ||
44 | + | ||
45 | +# External tool builders | ||
46 | +.externalToolBuilders/** | ||
47 | + | ||
48 | +# Locally stored "Eclipse launch configurations" | ||
49 | +*.launch | ||
50 | + | ||
51 | +# CDT-specific | ||
52 | +.cproject | ||
53 | + | ||
54 | +# PDT-specific | ||
55 | +.buildpath | ||
56 | +integration_test_settings.yml |
line-bot-sdk-java/.travis.yml
0 → 100644
line-bot-sdk-java/CODE_OF_CONDUCT.md
0 → 100644
1 | +# Contributor Covenant Code of Conduct | ||
2 | + | ||
3 | +## Our Pledge | ||
4 | + | ||
5 | +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. | ||
6 | + | ||
7 | +## Our Standards | ||
8 | + | ||
9 | +Examples of behavior that contributes to creating a positive environment include: | ||
10 | + | ||
11 | +* Using welcoming and inclusive language | ||
12 | +* Being respectful of differing viewpoints and experiences | ||
13 | +* Gracefully accepting constructive criticism | ||
14 | +* Focusing on what is best for the community | ||
15 | +* Showing empathy towards other community members | ||
16 | + | ||
17 | +Examples of unacceptable behavior by participants include: | ||
18 | + | ||
19 | +* The use of sexualized language or imagery and unwelcome sexual attention or advances | ||
20 | +* Trolling, insulting/derogatory comments, and personal or political attacks | ||
21 | +* Public or private harassment | ||
22 | +* Publishing others' private information, such as a physical or electronic address, without explicit permission | ||
23 | +* Other conduct which could reasonably be considered inappropriate in a professional setting | ||
24 | + | ||
25 | +## Our Responsibilities | ||
26 | + | ||
27 | +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. | ||
28 | + | ||
29 | +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. | ||
30 | + | ||
31 | +## Scope | ||
32 | + | ||
33 | +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. | ||
34 | + | ||
35 | +## Enforcement | ||
36 | + | ||
37 | +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at dl_oss_dev@linecorp.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. | ||
38 | + | ||
39 | +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. | ||
40 | + | ||
41 | +## Attribution | ||
42 | + | ||
43 | +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] | ||
44 | + | ||
45 | +[homepage]: http://contributor-covenant.org | ||
46 | +[version]: http://contributor-covenant.org/version/1/4/ |
line-bot-sdk-java/CONTRIBUTING.md
0 → 100644
1 | +## How to contribute to LINE Bot SDK for Java project | ||
2 | + | ||
3 | +First of all, thank you so much for taking your time to contribute! LINE Bot SDK for Java is not very different from any other open | ||
4 | +source projects you are aware of. It will be amazing if you could help us by doing any of the following: | ||
5 | + | ||
6 | +- File an issue in [the issue tracker](https://github.com/line/line-bot-sdk-java/issues) to report bugs and propose new features and | ||
7 | + improvements. | ||
8 | +- Ask a question using [the issue tracker](https://github.com/line/line-bot-sdk-java/issues). | ||
9 | +- Contribute your work by sending [a pull request](https://github.com/line/line-bot-sdk-java/pulls). | ||
10 | + | ||
11 | +### Contributor license agreement | ||
12 | + | ||
13 | +When you are sending a pull request and it's a non-trivial change beyond fixing typos, please make sure to sign | ||
14 | +[the ICLA (individual contributor license agreement)](https://cla-assistant.io/line/line-bot-sdk-java). Please | ||
15 | +[contact us](mailto:dl_oss_dev@linecorp.com) if you need the CCLA (corporate contributor license agreement). | ||
16 | + | ||
17 | +# Detect outdated dependencies | ||
18 | + | ||
19 | +Run `./gradlew dependencyUpdates -Drevision=release` checks dependency list | ||
20 | +and reports outdated dependencies excepts SpringManaged dependency. | ||
21 | + | ||
22 | +## ./gradlew dependencyUpdates example | ||
23 | +``` | ||
24 | +% ./gradlew dependencyUpdates -Drevision=release | ||
25 | +Download https://plugins.gradle.org/m2/org/springframework/boot/spring-boot-gradle-plugin/maven-metadata.xml | ||
26 | + | ||
27 | +> Task :dependencyUpdates | ||
28 | + | ||
29 | +------------------------------------------------------------ | ||
30 | +: Project Dependency Updates (report to plain text file) | ||
31 | +------------------------------------------------------------ | ||
32 | + | ||
33 | +The following dependencies are using the latest release version: | ||
34 | + - com.github.ben-manes:gradle-versions-plugin:0.20.0 | ||
35 | + - com.github.stefanbirkner:system-rules:1.18.0 | ||
36 | + - com.squareup.okhttp3:logging-interceptor:3.11.0 | ||
37 | + - com.squareup.okhttp3:mockwebserver:3.11.0 | ||
38 | + - com.squareup.retrofit2:converter-jackson:2.4.0 | ||
39 | + - com.squareup.retrofit2:retrofit:2.4.0 | ||
40 | + - io.franzbecker:gradle-lombok:1.14 | ||
41 | + - io.spring.gradle:dependency-management-plugin:1.0.6.RELEASE | ||
42 | + - org.projectlombok:lombok:1.18.2 | ||
43 | + - org.slf4j:slf4j-api:1.7.25 | ||
44 | + | ||
45 | +The following dependencies have later release versions: | ||
46 | + - com.google.guava:guava [25.1-jre -> 26.0-jre] | ||
47 | + https://github.com/google/guava | ||
48 | + - gradle.plugin.com.github.spotbugs:spotbugs-gradle-plugin [1.6.2 -> 1.6.3] | ||
49 | + - gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties [1.4.17 -> 1.5.2] | ||
50 | + - io.spring.gradle:propdeps-plugin [0.0.9.RELEASE -> 0.0.10.RELEASE] | ||
51 | + - org.jetbrains.kotlin:kotlin-gradle-plugin [1.2.61 -> 1.2.70] | ||
52 | + https://kotlinlang.org/ | ||
53 | + - org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable [1.2.61 -> 1.2.70] | ||
54 | + https://kotlinlang.org/ | ||
55 | + - org.jetbrains.kotlin:kotlin-stdlib-jdk8 [1.2.61 -> 1.2.70] | ||
56 | + https://kotlinlang.org/ | ||
57 | + | ||
58 | +Failed to determine the latest version for the following dependencies (use --info for details): | ||
59 | + - com.fasterxml.jackson.core:jackson-annotations | ||
60 | + - com.fasterxml.jackson.core:jackson-core | ||
61 | + - com.fasterxml.jackson.core:jackson-databind | ||
62 | + - com.fasterxml.jackson.datatype:jackson-datatype-jsr310 | ||
63 | + - com.fasterxml.jackson.module:jackson-module-parameter-names | ||
64 | + - javax.servlet:javax.servlet-api | ||
65 | + - javax.validation:validation-api | ||
66 | + - org.hibernate:hibernate-validator | ||
67 | + - org.springframework.boot:spring-boot-autoconfigure | ||
68 | + - org.springframework.boot:spring-boot-configuration-processor | ||
69 | + - org.springframework.boot:spring-boot-gradle-plugin | ||
70 | + - org.springframework.boot:spring-boot-starter-logging | ||
71 | + - org.springframework.boot:spring-boot-starter-test | ||
72 | + - org.springframework.boot:spring-boot-starter-web | ||
73 | + | ||
74 | +Gradle updates: | ||
75 | + - Gradle: [4.8 -> 4.10.1] | ||
76 | + | ||
77 | +Generated report file build/dependencyUpdates/report.txt | ||
78 | +``` | ||
79 | + |
line-bot-sdk-java/LICENSE.txt
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/Procfile
0 → 100644
1 | +web: java $JAVA_OPTS -jar sample-spring-boot-kitchensink/build/libs/sample-spring-boot-kitchensink-*.jar --server.port=$PORT |
line-bot-sdk-java/README.md
0 → 100644
1 | +# LINE Messaging API SDK for Java | ||
2 | + | ||
3 | +[](https://travis-ci.org/line/line-bot-sdk-java) | ||
4 | +[](https://maven-badges.herokuapp.com/maven-central/com.linecorp.bot/line-bot-model) | ||
5 | +[](https://javadoc.io/doc/com.linecorp.bot/line-bot-model) | ||
6 | +[](https://codecov.io/gh/line/line-bot-sdk-java) | ||
7 | + | ||
8 | + | ||
9 | +## Introduction | ||
10 | + | ||
11 | +The LINE Messaging API SDK for Java makes it easy to develop bots using LINE Messaging API, and you can create a sample bot within minutes. | ||
12 | + | ||
13 | + | ||
14 | +## Documentation | ||
15 | + | ||
16 | +See the official API documentation for more information. | ||
17 | + | ||
18 | +- English: https://developers.line.biz/en/docs/messaging-api/overview/ | ||
19 | +- Japanese: https://developers.line.biz/ja/docs/messaging-api/overview/ | ||
20 | + | ||
21 | + | ||
22 | +## Requirements | ||
23 | + | ||
24 | +This library requires Java 8 or later. | ||
25 | + | ||
26 | + | ||
27 | +## Installation | ||
28 | + | ||
29 | +We've uploaded this library to the Maven Central Repository. You can install the modules using Maven or Gradle. | ||
30 | + | ||
31 | +http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.linecorp.bot%22 | ||
32 | + | ||
33 | + | ||
34 | +## Modules | ||
35 | + | ||
36 | +This project contains the following modules: | ||
37 | + | ||
38 | + * line-bot-api-client: API client library for the Messaging API | ||
39 | + * line-bot-model: Model classes for the Messaging API | ||
40 | + * line-bot-servlet: Java servlet utilities for bot servers | ||
41 | + * line-bot-spring-boot: Spring Boot auto configuration library for bot servers | ||
42 | + | ||
43 | +This project contains the following sample projects: | ||
44 | + | ||
45 | + * sample-spring-boot-echo: A simple echo server. It includes a Heroku button. | ||
46 | + * sample-spring-boot-kitchensink: Full featured sample code. | ||
47 | + | ||
48 | + | ||
49 | +## Spring Boot integration | ||
50 | + | ||
51 | +The line-bot-spring-boot module lets you build a bot application as a Spring Boot application. | ||
52 | + | ||
53 | +```java | ||
54 | +/* | ||
55 | + * Copyright 2016 LINE Corporation | ||
56 | + * | ||
57 | + * LINE Corporation licenses this file to you under the Apache License, | ||
58 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
59 | + * with the License. You may obtain a copy of the License at: | ||
60 | + * | ||
61 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
62 | + * | ||
63 | + * Unless required by applicable law or agreed to in writing, software | ||
64 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
65 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
66 | + * License for the specific language governing permissions and limitations | ||
67 | + * under the License. | ||
68 | + */ | ||
69 | + | ||
70 | +package com.example.bot.spring.echo; | ||
71 | + | ||
72 | +import org.springframework.boot.SpringApplication; | ||
73 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
74 | + | ||
75 | +import com.linecorp.bot.model.event.Event; | ||
76 | +import com.linecorp.bot.model.event.MessageEvent; | ||
77 | +import com.linecorp.bot.model.event.message.TextMessageContent; | ||
78 | +import com.linecorp.bot.model.message.TextMessage; | ||
79 | +import com.linecorp.bot.spring.boot.annotation.EventMapping; | ||
80 | +import com.linecorp.bot.spring.boot.annotation.LineMessageHandler; | ||
81 | + | ||
82 | +@SpringBootApplication | ||
83 | +@LineMessageHandler | ||
84 | +public class EchoApplication { | ||
85 | + public static void main(String[] args) { | ||
86 | + SpringApplication.run(EchoApplication.class, args); | ||
87 | + } | ||
88 | + | ||
89 | + @EventMapping | ||
90 | + public TextMessage handleTextMessageEvent(MessageEvent<TextMessageContent> event) { | ||
91 | + System.out.println("event: " + event); | ||
92 | + return new TextMessage(event.getMessage().getText()); | ||
93 | + } | ||
94 | + | ||
95 | + @EventMapping | ||
96 | + public void handleDefaultMessageEvent(Event event) { | ||
97 | + System.out.println("event: " + event); | ||
98 | + } | ||
99 | +} | ||
100 | +``` | ||
101 | + | ||
102 | +## How do I use a proxy server? | ||
103 | + | ||
104 | +You can use `LineMessagingServiceBuilder` to configure a proxy server. It accepts your own OkHttpBuilder instance. | ||
105 | + | ||
106 | +Note: You don't need to use an add-on like Fixie to have static IP addresses for proxy servers. You can make API calls without entering IP addresses on the server IP whitelist. | ||
107 | + | ||
108 | + | ||
109 | +## Help and media | ||
110 | +FAQ: https://developers.line.biz/en/faq/ | ||
111 | + | ||
112 | +Community Q&A: https://www.line-community.me/questions | ||
113 | + | ||
114 | +News: https://developers.line.biz/en/news/ | ||
115 | + | ||
116 | +Twitter: [@LINE_DEV](https://twitter.com/LINE_DEV) | ||
117 | + | ||
118 | + | ||
119 | +## Versioning | ||
120 | + | ||
121 | +This project respects semantic versioning. | ||
122 | + | ||
123 | +See http://semver.org/. | ||
124 | + | ||
125 | + | ||
126 | +## Contributing | ||
127 | + | ||
128 | +Please check [CONTRIBUTING](CONTRIBUTING.md) before making a contribution. | ||
129 | + | ||
130 | + | ||
131 | +## License | ||
132 | + | ||
133 | + Copyright (C) 2016 LINE Corp. | ||
134 | + | ||
135 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
136 | + you may not use this file except in compliance with the License. | ||
137 | + You may obtain a copy of the License at | ||
138 | + | ||
139 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
140 | + | ||
141 | + Unless required by applicable law or agreed to in writing, software | ||
142 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
143 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
144 | + See the License for the specific language governing permissions and | ||
145 | + limitations under the License. |
line-bot-sdk-java/app.json
0 → 100644
1 | +{ | ||
2 | + "name": "echo bot - LINE Messaging API", | ||
3 | + "description": "This is a sample application for the LINE Messaging API", | ||
4 | + "keywords": ["chatbot", "line", "java"], | ||
5 | + "env": { | ||
6 | + "LINE_BOT_CHANNEL_TOKEN": { | ||
7 | + "description": "LINE bot Channel access token from the Channel Console", | ||
8 | + "required": true | ||
9 | + }, | ||
10 | + "LINE_BOT_CHANNEL_SECRET": { | ||
11 | + "description": "LINE bot Channel secret from the Channel Console", | ||
12 | + "required": true | ||
13 | + } | ||
14 | + } | ||
15 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
line-bot-sdk-java/build.gradle
0 → 100644
This diff is collapsed. Click to expand it.
1 | +<?xml version="1.0"?> | ||
2 | +<!DOCTYPE suppressions PUBLIC | ||
3 | + "-//Puppy Crawl//DTD Suppressions 1.1//EN" | ||
4 | + "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd"> | ||
5 | + | ||
6 | +<suppressions> | ||
7 | + <!-- Suppress Javadoc-related checks in test directories --> | ||
8 | + <suppress checks="JavadocPackage" files="[\\/](jmh|test|internal|example)[\\/]" /> | ||
9 | + <suppress checks="JavadocMethod" files="[\\/](jmh|test|internal|example)[\\/]" /> | ||
10 | + <suppress checks="VisibilityModifier" files="[\\/](jmh|test|internal|example)[\\/]" /> | ||
11 | + | ||
12 | + <!-- Suppress all checks in generated sources --> | ||
13 | + <suppress checks=".*" files="[\\/]gen-src[\\/]" /> | ||
14 | +</suppressions> |
This diff is collapsed. Click to expand it.
1 | +<FindBugsFilter> | ||
2 | + <Match> | ||
3 | + <Bug pattern="OBL_UNSATISFIED_OBLIGATION" /> | ||
4 | + </Match> | ||
5 | + | ||
6 | + <!-- False positive with Java 11 https://github.com/spotbugs/spotbugs/issues/878 --> | ||
7 | + <Match> | ||
8 | + <Bug pattern="RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE" /> | ||
9 | + </Match> | ||
10 | + | ||
11 | + <!-- Ignore lombok's redundant check --> | ||
12 | + <Match> | ||
13 | + <Class name="com.linecorp.bot.client.IntegrationTestSettings" /> | ||
14 | + <Bug pattern="RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE" /> | ||
15 | + </Match> | ||
16 | +</FindBugsFilter> |
line-bot-sdk-java/gradle.properties
0 → 100644
1 | +org.gradle.warning.mode=all |
line-bot-sdk-java/gradlew
0 → 100644
1 | +#!/usr/bin/env sh | ||
2 | + | ||
3 | +# | ||
4 | +# Copyright 2015 the original author or authors. | ||
5 | +# | ||
6 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | +# you may not use this file except in compliance with the License. | ||
8 | +# You may obtain a copy of the License at | ||
9 | +# | ||
10 | +# https://www.apache.org/licenses/LICENSE-2.0 | ||
11 | +# | ||
12 | +# Unless required by applicable law or agreed to in writing, software | ||
13 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | +# See the License for the specific language governing permissions and | ||
16 | +# limitations under the License. | ||
17 | +# | ||
18 | + | ||
19 | +############################################################################## | ||
20 | +## | ||
21 | +## Gradle start up script for UN*X | ||
22 | +## | ||
23 | +############################################################################## | ||
24 | + | ||
25 | +# Attempt to set APP_HOME | ||
26 | +# Resolve links: $0 may be a link | ||
27 | +PRG="$0" | ||
28 | +# Need this for relative symlinks. | ||
29 | +while [ -h "$PRG" ] ; do | ||
30 | + ls=`ls -ld "$PRG"` | ||
31 | + link=`expr "$ls" : '.*-> \(.*\)$'` | ||
32 | + if expr "$link" : '/.*' > /dev/null; then | ||
33 | + PRG="$link" | ||
34 | + else | ||
35 | + PRG=`dirname "$PRG"`"/$link" | ||
36 | + fi | ||
37 | +done | ||
38 | +SAVED="`pwd`" | ||
39 | +cd "`dirname \"$PRG\"`/" >/dev/null | ||
40 | +APP_HOME="`pwd -P`" | ||
41 | +cd "$SAVED" >/dev/null | ||
42 | + | ||
43 | +APP_NAME="Gradle" | ||
44 | +APP_BASE_NAME=`basename "$0"` | ||
45 | + | ||
46 | +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
47 | +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||
48 | + | ||
49 | +# Use the maximum available, or set MAX_FD != -1 to use that value. | ||
50 | +MAX_FD="maximum" | ||
51 | + | ||
52 | +warn () { | ||
53 | + echo "$*" | ||
54 | +} | ||
55 | + | ||
56 | +die () { | ||
57 | + echo | ||
58 | + echo "$*" | ||
59 | + echo | ||
60 | + exit 1 | ||
61 | +} | ||
62 | + | ||
63 | +# OS specific support (must be 'true' or 'false'). | ||
64 | +cygwin=false | ||
65 | +msys=false | ||
66 | +darwin=false | ||
67 | +nonstop=false | ||
68 | +case "`uname`" in | ||
69 | + CYGWIN* ) | ||
70 | + cygwin=true | ||
71 | + ;; | ||
72 | + Darwin* ) | ||
73 | + darwin=true | ||
74 | + ;; | ||
75 | + MINGW* ) | ||
76 | + msys=true | ||
77 | + ;; | ||
78 | + NONSTOP* ) | ||
79 | + nonstop=true | ||
80 | + ;; | ||
81 | +esac | ||
82 | + | ||
83 | +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar | ||
84 | + | ||
85 | + | ||
86 | +# Determine the Java command to use to start the JVM. | ||
87 | +if [ -n "$JAVA_HOME" ] ; then | ||
88 | + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | ||
89 | + # IBM's JDK on AIX uses strange locations for the executables | ||
90 | + JAVACMD="$JAVA_HOME/jre/sh/java" | ||
91 | + else | ||
92 | + JAVACMD="$JAVA_HOME/bin/java" | ||
93 | + fi | ||
94 | + if [ ! -x "$JAVACMD" ] ; then | ||
95 | + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | ||
96 | + | ||
97 | +Please set the JAVA_HOME variable in your environment to match the | ||
98 | +location of your Java installation." | ||
99 | + fi | ||
100 | +else | ||
101 | + JAVACMD="java" | ||
102 | + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
103 | + | ||
104 | +Please set the JAVA_HOME variable in your environment to match the | ||
105 | +location of your Java installation." | ||
106 | +fi | ||
107 | + | ||
108 | +# Increase the maximum file descriptors if we can. | ||
109 | +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | ||
110 | + MAX_FD_LIMIT=`ulimit -H -n` | ||
111 | + if [ $? -eq 0 ] ; then | ||
112 | + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | ||
113 | + MAX_FD="$MAX_FD_LIMIT" | ||
114 | + fi | ||
115 | + ulimit -n $MAX_FD | ||
116 | + if [ $? -ne 0 ] ; then | ||
117 | + warn "Could not set maximum file descriptor limit: $MAX_FD" | ||
118 | + fi | ||
119 | + else | ||
120 | + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | ||
121 | + fi | ||
122 | +fi | ||
123 | + | ||
124 | +# For Darwin, add options to specify how the application appears in the dock | ||
125 | +if $darwin; then | ||
126 | + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | ||
127 | +fi | ||
128 | + | ||
129 | +# For Cygwin or MSYS, switch paths to Windows format before running java | ||
130 | +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then | ||
131 | + APP_HOME=`cygpath --path --mixed "$APP_HOME"` | ||
132 | + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | ||
133 | + | ||
134 | + JAVACMD=`cygpath --unix "$JAVACMD"` | ||
135 | + | ||
136 | + # We build the pattern for arguments to be converted via cygpath | ||
137 | + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | ||
138 | + SEP="" | ||
139 | + for dir in $ROOTDIRSRAW ; do | ||
140 | + ROOTDIRS="$ROOTDIRS$SEP$dir" | ||
141 | + SEP="|" | ||
142 | + done | ||
143 | + OURCYGPATTERN="(^($ROOTDIRS))" | ||
144 | + # Add a user-defined pattern to the cygpath arguments | ||
145 | + if [ "$GRADLE_CYGPATTERN" != "" ] ; then | ||
146 | + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | ||
147 | + fi | ||
148 | + # Now convert the arguments - kludge to limit ourselves to /bin/sh | ||
149 | + i=0 | ||
150 | + for arg in "$@" ; do | ||
151 | + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | ||
152 | + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | ||
153 | + | ||
154 | + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | ||
155 | + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | ||
156 | + else | ||
157 | + eval `echo args$i`="\"$arg\"" | ||
158 | + fi | ||
159 | + i=`expr $i + 1` | ||
160 | + done | ||
161 | + case $i in | ||
162 | + 0) set -- ;; | ||
163 | + 1) set -- "$args0" ;; | ||
164 | + 2) set -- "$args0" "$args1" ;; | ||
165 | + 3) set -- "$args0" "$args1" "$args2" ;; | ||
166 | + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; | ||
167 | + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | ||
168 | + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | ||
169 | + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | ||
170 | + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | ||
171 | + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | ||
172 | + esac | ||
173 | +fi | ||
174 | + | ||
175 | +# Escape application args | ||
176 | +save () { | ||
177 | + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | ||
178 | + echo " " | ||
179 | +} | ||
180 | +APP_ARGS=`save "$@"` | ||
181 | + | ||
182 | +# Collect all arguments for the java command, following the shell quoting and substitution rules | ||
183 | +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | ||
184 | + | ||
185 | +exec "$JAVACMD" "$@" |
line-bot-sdk-java/gradlew.bat
0 → 100644
1 | +@rem | ||
2 | +@rem Copyright 2015 the original author or authors. | ||
3 | +@rem | ||
4 | +@rem Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | +@rem you may not use this file except in compliance with the License. | ||
6 | +@rem You may obtain a copy of the License at | ||
7 | +@rem | ||
8 | +@rem https://www.apache.org/licenses/LICENSE-2.0 | ||
9 | +@rem | ||
10 | +@rem Unless required by applicable law or agreed to in writing, software | ||
11 | +@rem distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | +@rem See the License for the specific language governing permissions and | ||
14 | +@rem limitations under the License. | ||
15 | +@rem | ||
16 | + | ||
17 | +@if "%DEBUG%" == "" @echo off | ||
18 | +@rem ########################################################################## | ||
19 | +@rem | ||
20 | +@rem Gradle startup script for Windows | ||
21 | +@rem | ||
22 | +@rem ########################################################################## | ||
23 | + | ||
24 | +@rem Set local scope for the variables with windows NT shell | ||
25 | +if "%OS%"=="Windows_NT" setlocal | ||
26 | + | ||
27 | +set DIRNAME=%~dp0 | ||
28 | +if "%DIRNAME%" == "" set DIRNAME=. | ||
29 | +set APP_BASE_NAME=%~n0 | ||
30 | +set APP_HOME=%DIRNAME% | ||
31 | + | ||
32 | +@rem Resolve any "." and ".." in APP_HOME to make it shorter. | ||
33 | +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi | ||
34 | + | ||
35 | +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||
36 | +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | ||
37 | + | ||
38 | +@rem Find java.exe | ||
39 | +if defined JAVA_HOME goto findJavaFromJavaHome | ||
40 | + | ||
41 | +set JAVA_EXE=java.exe | ||
42 | +%JAVA_EXE% -version >NUL 2>&1 | ||
43 | +if "%ERRORLEVEL%" == "0" goto init | ||
44 | + | ||
45 | +echo. | ||
46 | +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | ||
47 | +echo. | ||
48 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
49 | +echo location of your Java installation. | ||
50 | + | ||
51 | +goto fail | ||
52 | + | ||
53 | +:findJavaFromJavaHome | ||
54 | +set JAVA_HOME=%JAVA_HOME:"=% | ||
55 | +set JAVA_EXE=%JAVA_HOME%/bin/java.exe | ||
56 | + | ||
57 | +if exist "%JAVA_EXE%" goto init | ||
58 | + | ||
59 | +echo. | ||
60 | +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | ||
61 | +echo. | ||
62 | +echo Please set the JAVA_HOME variable in your environment to match the | ||
63 | +echo location of your Java installation. | ||
64 | + | ||
65 | +goto fail | ||
66 | + | ||
67 | +:init | ||
68 | +@rem Get command-line arguments, handling Windows variants | ||
69 | + | ||
70 | +if not "%OS%" == "Windows_NT" goto win9xME_args | ||
71 | + | ||
72 | +:win9xME_args | ||
73 | +@rem Slurp the command line arguments. | ||
74 | +set CMD_LINE_ARGS= | ||
75 | +set _SKIP=2 | ||
76 | + | ||
77 | +:win9xME_args_slurp | ||
78 | +if "x%~1" == "x" goto execute | ||
79 | + | ||
80 | +set CMD_LINE_ARGS=%* | ||
81 | + | ||
82 | +:execute | ||
83 | +@rem Setup the command line | ||
84 | + | ||
85 | +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | ||
86 | + | ||
87 | + | ||
88 | +@rem Execute Gradle | ||
89 | +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | ||
90 | + | ||
91 | +:end | ||
92 | +@rem End local scope for the variables with windows NT shell | ||
93 | +if "%ERRORLEVEL%"=="0" goto mainEnd | ||
94 | + | ||
95 | +:fail | ||
96 | +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | ||
97 | +rem the _cmd.exe /c_ return code! | ||
98 | +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | ||
99 | +exit /b 1 | ||
100 | + | ||
101 | +:mainEnd | ||
102 | +if "%OS%"=="Windows_NT" endlocal | ||
103 | + | ||
104 | +:omega |
1 | +# line-bot-api-client | ||
2 | + | ||
3 | +LINE Messaging API client for Java 8 or later. | ||
4 | + | ||
5 | +## Synopsis | ||
6 | + | ||
7 | +```java | ||
8 | +LineMessagingClient client = LineMessagingClient.builder("YOUR_CHANNEL_TOKEN").build(); | ||
9 | +``` | ||
10 | + | ||
11 | +## Description | ||
12 | + | ||
13 | +This module provides an API client for the LINE Messaging API. | ||
14 | + | ||
15 | +## Integration test | ||
16 | + | ||
17 | +By default, the integration test suite does nothing. You need to put the configuration file to run the integration test. | ||
18 | +If you want to run this test suite, put `src/test/resources/integration_test_settings.yml`. | ||
19 | + | ||
20 | +The YAML file is mapped to `com.linecorp.bot.client.IntegrationTestSettings`. | ||
21 | + | ||
22 | +(It's bit hard to run all test cases since some test cases depend on the number of the targeted reaches). |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +// https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests | ||
18 | +sourceSets { | ||
19 | + integrationTest { | ||
20 | + compileClasspath += sourceSets.main.output | ||
21 | + runtimeClasspath += sourceSets.main.output | ||
22 | + } | ||
23 | +} | ||
24 | + | ||
25 | +configurations { | ||
26 | + integrationTestImplementation.extendsFrom implementation | ||
27 | + integrationTestRuntimeOnly.extendsFrom runtimeOnly | ||
28 | + integrationTestCompileOnly.extendsFrom compileOnly | ||
29 | + integrationTestAnnotationProcessor.extendsFrom annotationProcessor | ||
30 | +} | ||
31 | + | ||
32 | +task integrationTest(type: Test) { | ||
33 | + description = 'Runs integration tests.' | ||
34 | + group = 'verification' | ||
35 | + | ||
36 | + testClassesDirs = sourceSets.integrationTest.output.classesDirs | ||
37 | + classpath = sourceSets.integrationTest.runtimeClasspath | ||
38 | + shouldRunAfter test | ||
39 | +} | ||
40 | + | ||
41 | +check.dependsOn integrationTest | ||
42 | + | ||
43 | +dependencies { | ||
44 | + api project(':line-bot-model') | ||
45 | + implementation 'org.slf4j:slf4j-api' | ||
46 | + implementation 'com.squareup.okhttp3:logging-interceptor' | ||
47 | + implementation 'com.squareup.retrofit2:converter-jackson' | ||
48 | + implementation 'com.squareup.retrofit2:retrofit' | ||
49 | + | ||
50 | + testCompileOnly 'org.projectlombok:lombok' | ||
51 | + testAnnotationProcessor 'org.projectlombok:lombok' | ||
52 | + | ||
53 | + integrationTestCompileOnly 'org.projectlombok:lombok' | ||
54 | + integrationTestAnnotationProcessor 'org.projectlombok:lombok' | ||
55 | + integrationTestImplementation 'com.google.guava:guava' | ||
56 | + integrationTestImplementation 'io.jsonwebtoken:jjwt-api' | ||
57 | + integrationTestImplementation 'io.jsonwebtoken:jjwt-jackson' | ||
58 | + integrationTestImplementation 'org.springframework.boot:spring-boot-starter-test' | ||
59 | + integrationTestImplementation 'org.springframework.boot:spring-boot-starter-logging' | ||
60 | + integrationTestImplementation 'com.fasterxml.jackson.core:jackson-core' | ||
61 | + integrationTestImplementation 'com.fasterxml.jackson.core:jackson-databind' | ||
62 | + integrationTestImplementation 'com.fasterxml.jackson.core:jackson-annotations' | ||
63 | + integrationTestImplementation 'com.fasterxml.jackson.module:jackson-module-parameter-names' | ||
64 | + integrationTestImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml' | ||
65 | + integrationTestRuntime 'io.jsonwebtoken:jjwt-impl' | ||
66 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.util.Collections; | ||
21 | + | ||
22 | +import org.junit.Before; | ||
23 | +import org.junit.Test; | ||
24 | + | ||
25 | +import com.linecorp.bot.model.Narrowcast; | ||
26 | +import com.linecorp.bot.model.message.TextMessage; | ||
27 | +import com.linecorp.bot.model.narrowcast.Filter; | ||
28 | +import com.linecorp.bot.model.narrowcast.filter.GenderDemographicFilter; | ||
29 | +import com.linecorp.bot.model.narrowcast.filter.GenderDemographicFilter.Gender; | ||
30 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
31 | +import com.linecorp.bot.model.response.GetMessageEventResponse; | ||
32 | +import com.linecorp.bot.model.response.NarrowcastProgressResponse; | ||
33 | +import com.linecorp.bot.model.response.NarrowcastProgressResponse.Phase; | ||
34 | + | ||
35 | +import lombok.extern.slf4j.Slf4j; | ||
36 | + | ||
37 | +@Slf4j | ||
38 | +public class InsightIntegrationTest { | ||
39 | + private LineMessagingClient target; | ||
40 | + | ||
41 | + @Before | ||
42 | + public void setUp() throws IOException { | ||
43 | + IntegrationTestSettings settings = IntegrationTestSettingsLoader.load(); | ||
44 | + target = LineMessagingClientFactory.create(settings); | ||
45 | + } | ||
46 | + | ||
47 | + @Test | ||
48 | + public void testGetMessageEvent() throws Exception { | ||
49 | + // Send narrowcast message. | ||
50 | + BotApiResponse response = target.narrowcast( | ||
51 | + new Narrowcast(new TextMessage("Narrowcast test(gender=male)"), | ||
52 | + Filter.builder() | ||
53 | + .demographic( | ||
54 | + GenderDemographicFilter | ||
55 | + .builder() | ||
56 | + .oneOf(Collections.singletonList(Gender.MALE)) | ||
57 | + .build() | ||
58 | + ).build())).get(); | ||
59 | + log.info("Narrowcast response={}", response); | ||
60 | + | ||
61 | + // Waiting sending process | ||
62 | + for (int i = 0; i < 10; i++) { | ||
63 | + NarrowcastProgressResponse progressResponse = target.getNarrowcastProgress( | ||
64 | + response.getRequestId()).get(); | ||
65 | + log.info("Progress={}", progressResponse); | ||
66 | + log.info("Progress response={}", progressResponse); | ||
67 | + if (progressResponse.getPhase() == Phase.SUCCEEDED | ||
68 | + || progressResponse.getPhase() == Phase.FAILED) { | ||
69 | + break; | ||
70 | + } | ||
71 | + Thread.sleep(1000); | ||
72 | + } | ||
73 | + | ||
74 | + GetMessageEventResponse messageEvent = target.getMessageEvent( | ||
75 | + response.getRequestId()).get(); | ||
76 | + log.info("messageEvent={}", messageEvent); | ||
77 | + } | ||
78 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.util.List; | ||
20 | + | ||
21 | +import org.junit.Assume; | ||
22 | + | ||
23 | +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||
24 | +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; | ||
25 | + | ||
26 | +import com.linecorp.bot.client.IntegrationTestSettings.IntegrationTestSettingsBuilder; | ||
27 | + | ||
28 | +import lombok.AllArgsConstructor; | ||
29 | +import lombok.Builder; | ||
30 | +import lombok.Value; | ||
31 | + | ||
32 | +@AllArgsConstructor | ||
33 | +@Value | ||
34 | +@Builder | ||
35 | +@JsonDeserialize(builder = IntegrationTestSettingsBuilder.class) | ||
36 | +public class IntegrationTestSettings { | ||
37 | + private String token; | ||
38 | + private String endpoint; | ||
39 | + private String userId; | ||
40 | + private List<String> audienceIfas; | ||
41 | + private String retargetingRequestId; | ||
42 | + private boolean failOnUnknownProperties = true; | ||
43 | + | ||
44 | + public String getUserId() { | ||
45 | + Assume.assumeNotNull(userId); | ||
46 | + return userId; | ||
47 | + } | ||
48 | + | ||
49 | + public List<String> getAudienceIfas() { | ||
50 | + Assume.assumeNotNull(audienceIfas); | ||
51 | + Assume.assumeFalse(audienceIfas.isEmpty()); | ||
52 | + return audienceIfas; | ||
53 | + } | ||
54 | + | ||
55 | + public String getRetargetingRequestId() { | ||
56 | + Assume.assumeNotNull(retargetingRequestId); | ||
57 | + return retargetingRequestId; | ||
58 | + } | ||
59 | + | ||
60 | + @JsonPOJOBuilder(withPrefix = "") | ||
61 | + public static class IntegrationTestSettingsBuilder { | ||
62 | + // filled by lombok. | ||
63 | + } | ||
64 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.net.URL; | ||
21 | + | ||
22 | +import org.junit.Assume; | ||
23 | + | ||
24 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
25 | +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; | ||
26 | +import com.fasterxml.jackson.module.paramnames.ParameterNamesModule; | ||
27 | + | ||
28 | +public class IntegrationTestSettingsLoader { | ||
29 | + private static final URL TEST_RESOURCE = ClassLoader.getSystemResource("integration_test_settings.yml"); | ||
30 | + | ||
31 | + public static IntegrationTestSettings load() throws IOException { | ||
32 | + // Do not run all test cases in this class when src/test/resources/integration_test_settings.yml doesn't | ||
33 | + // exist. | ||
34 | + Assume.assumeTrue("exists integration_test_settings.yml in resource directory", | ||
35 | + TEST_RESOURCE != null); | ||
36 | + | ||
37 | + return new ObjectMapper(new YAMLFactory()) | ||
38 | + .registerModule(new ParameterNamesModule()) | ||
39 | + .readValue(TEST_RESOURCE, IntegrationTestSettings.class); | ||
40 | + } | ||
41 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.net.URI; | ||
20 | + | ||
21 | +import com.fasterxml.jackson.databind.DeserializationFeature; | ||
22 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
23 | + | ||
24 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
25 | + | ||
26 | +import retrofit2.Retrofit; | ||
27 | +import retrofit2.converter.jackson.JacksonConverterFactory; | ||
28 | + | ||
29 | +public class LineMessagingClientFactory { | ||
30 | + public static LineMessagingClient create(IntegrationTestSettings settings) { | ||
31 | + ObjectMapper objectMapper = ModelObjectMapper | ||
32 | + .createNewObjectMapper() | ||
33 | + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, | ||
34 | + settings.isFailOnUnknownProperties()); | ||
35 | + | ||
36 | + Retrofit.Builder retrofitBuilder = new Retrofit.Builder() | ||
37 | + .addConverterFactory(JacksonConverterFactory.create(objectMapper)); | ||
38 | + | ||
39 | + return LineMessagingClient | ||
40 | + .builder(settings.getToken()) | ||
41 | + .apiEndPoint(URI.create(settings.getEndpoint())) | ||
42 | + .retrofitBuilder(retrofitBuilder) | ||
43 | + .build(); | ||
44 | + } | ||
45 | +} |
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Collections.singleton; | ||
20 | + | ||
21 | +import java.io.IOException; | ||
22 | +import java.util.concurrent.Callable; | ||
23 | + | ||
24 | +import org.junit.Before; | ||
25 | +import org.junit.Test; | ||
26 | + | ||
27 | +import com.linecorp.bot.model.Broadcast; | ||
28 | +import com.linecorp.bot.model.Multicast; | ||
29 | +import com.linecorp.bot.model.PushMessage; | ||
30 | +import com.linecorp.bot.model.message.TextMessage; | ||
31 | +import com.linecorp.bot.model.response.GetNumberOfFollowersResponse; | ||
32 | +import com.linecorp.bot.model.response.GetNumberOfMessageDeliveriesResponse; | ||
33 | +import com.linecorp.bot.model.response.NumberOfMessagesResponse; | ||
34 | + | ||
35 | +import lombok.extern.slf4j.Slf4j; | ||
36 | + | ||
37 | +/** | ||
38 | + * Integration test of {@link LineMessagingClient}. | ||
39 | + * | ||
40 | + * <p>To run this test, please put config file resources/integration_test_settings.yml. | ||
41 | + */ | ||
42 | +@Slf4j | ||
43 | +public class LineMessagingClientImplIntegrationTest { | ||
44 | + private LineMessagingClient target; | ||
45 | + private IntegrationTestSettings settings; | ||
46 | + | ||
47 | + @Before | ||
48 | + public void setUp() throws IOException { | ||
49 | + settings = IntegrationTestSettingsLoader.load(); | ||
50 | + target = LineMessagingClientFactory.create(settings); | ||
51 | + } | ||
52 | + | ||
53 | + private static void testApiCall(Callable<Object> f) throws Exception { | ||
54 | + final Object response = f.call(); | ||
55 | + log.info(response.toString()); | ||
56 | + } | ||
57 | + | ||
58 | + @Test | ||
59 | + public void broadcast() throws Exception { | ||
60 | + testApiCall( | ||
61 | + () -> target.broadcast(new Broadcast(new TextMessage("Broadcast"), true)).get() | ||
62 | + ); | ||
63 | + testApiCall( | ||
64 | + () -> target.broadcast(new Broadcast(new TextMessage("Broadcast"))).get() | ||
65 | + ); | ||
66 | + } | ||
67 | + | ||
68 | + @Test | ||
69 | + public void multicast() throws Exception { | ||
70 | + testApiCall( | ||
71 | + () -> target.multicast( | ||
72 | + new Multicast(singleton(settings.getUserId()), new TextMessage("Multicast"), true)) | ||
73 | + .get() | ||
74 | + ); | ||
75 | + testApiCall( | ||
76 | + () -> target | ||
77 | + .multicast(new Multicast(singleton(settings.getUserId()), new TextMessage("Multicast"))) | ||
78 | + .get() | ||
79 | + ); | ||
80 | + } | ||
81 | + | ||
82 | + @Test | ||
83 | + public void pushMessage() throws Exception { | ||
84 | + testApiCall( | ||
85 | + () -> target.pushMessage(new PushMessage(settings.getUserId(), new TextMessage("Push"), true)) | ||
86 | + .get() | ||
87 | + ); | ||
88 | + testApiCall( | ||
89 | + () -> target.pushMessage(new PushMessage(settings.getUserId(), new TextMessage("Push"))).get() | ||
90 | + ); | ||
91 | + } | ||
92 | + | ||
93 | + @Test | ||
94 | + public void getNumberOfMessageDeliveries() throws Exception { | ||
95 | + final GetNumberOfMessageDeliveriesResponse getNumberOfMessageDeliveriesResponse = | ||
96 | + target.getNumberOfMessageDeliveries("20191231").get(); | ||
97 | + | ||
98 | + log.info(getNumberOfMessageDeliveriesResponse.toString()); | ||
99 | + } | ||
100 | + | ||
101 | + @Test | ||
102 | + public void getNumberOfSentBroadcastMessages() throws Exception { | ||
103 | + final NumberOfMessagesResponse getNumberOfSentBroadcastMessages = | ||
104 | + target.getNumberOfSentBroadcastMessages("20191231").get(); | ||
105 | + | ||
106 | + log.info(getNumberOfSentBroadcastMessages.toString()); | ||
107 | + } | ||
108 | + | ||
109 | + @Test | ||
110 | + public void getNumberOfFollowers() throws Exception { | ||
111 | + final GetNumberOfFollowersResponse getNumberOfFollowersResponse = | ||
112 | + target.getNumberOfFollowers("20191231").get(); | ||
113 | + | ||
114 | + log.info(getNumberOfFollowersResponse.toString()); | ||
115 | + } | ||
116 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static org.assertj.core.api.Assertions.assertThat; | ||
20 | + | ||
21 | +import java.io.IOException; | ||
22 | +import java.net.URL; | ||
23 | +import java.security.KeyFactory; | ||
24 | +import java.security.PrivateKey; | ||
25 | +import java.security.spec.PKCS8EncodedKeySpec; | ||
26 | +import java.time.Duration; | ||
27 | +import java.time.Instant; | ||
28 | +import java.util.Map; | ||
29 | + | ||
30 | +import org.junit.Assume; | ||
31 | +import org.junit.Before; | ||
32 | +import org.junit.Test; | ||
33 | +import org.slf4j.bridge.SLF4JBridgeHandler; | ||
34 | +import org.yaml.snakeyaml.Yaml; | ||
35 | + | ||
36 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
37 | +import com.google.common.collect.ImmutableMap; | ||
38 | +import com.google.common.io.BaseEncoding; | ||
39 | + | ||
40 | +import com.linecorp.bot.model.oauth.IssueChannelAccessTokenResponse; | ||
41 | + | ||
42 | +import io.jsonwebtoken.Jwts; | ||
43 | +import io.jsonwebtoken.SignatureAlgorithm; | ||
44 | +import io.jsonwebtoken.jackson.io.JacksonSerializer; | ||
45 | +import lombok.extern.slf4j.Slf4j; | ||
46 | + | ||
47 | +@Slf4j | ||
48 | +public class LineOAuthClientIntegrationTest { | ||
49 | + private static final URL TEST_RESOURCE = ClassLoader.getSystemResource("integration_test_settings.yml"); | ||
50 | + | ||
51 | + private LineOAuthClient target; | ||
52 | + private String endpoint; | ||
53 | + private String pemPrivateKey; | ||
54 | + private String channelId; | ||
55 | + private String channelSecret; | ||
56 | + private String kid; | ||
57 | + | ||
58 | + @Before | ||
59 | + public void setUp() throws IOException { | ||
60 | + Assume.assumeTrue(TEST_RESOURCE != null); | ||
61 | + | ||
62 | + final Map<?, ?> map = new ObjectMapper() | ||
63 | + .convertValue(new Yaml().load(TEST_RESOURCE.openStream()), Map.class); | ||
64 | + | ||
65 | + endpoint = (String) map.get("endpoint"); | ||
66 | + target = LineOAuthClient | ||
67 | + .builder() | ||
68 | + .apiEndPoint(endpoint) | ||
69 | + .build(); | ||
70 | + | ||
71 | + pemPrivateKey = ((String) map.get("pemPrivateKey")).replaceAll("\n", ""); | ||
72 | + kid = (String) map.get("kid"); | ||
73 | + channelId = String.valueOf(map.get("channelId")); | ||
74 | + channelSecret = (String) map.get("channelSecret"); | ||
75 | + } | ||
76 | + | ||
77 | + static { | ||
78 | + SLF4JBridgeHandler.removeHandlersForRootLogger(); | ||
79 | + SLF4JBridgeHandler.install(); | ||
80 | + } | ||
81 | + | ||
82 | + @Test | ||
83 | + public void gwtTokenIntegrationTest() throws Exception { | ||
84 | + final Map<String, Object> header = ImmutableMap.of( | ||
85 | + "alg", "RS256", | ||
86 | + "typ", "JWT", | ||
87 | + "kid", kid | ||
88 | + ); | ||
89 | + | ||
90 | + final Map<String, Object> body = ImmutableMap.of( | ||
91 | + "iss", channelId, | ||
92 | + "sub", channelId, | ||
93 | + "aud", endpoint, | ||
94 | + "exp", Instant.now().plusSeconds(10).getEpochSecond(), | ||
95 | + "token_exp", Duration.ofMinutes(1).getSeconds() | ||
96 | + ); | ||
97 | + | ||
98 | + byte[] bytes = BaseEncoding.base64().decode(pemPrivateKey); | ||
99 | + | ||
100 | + KeyFactory kf = KeyFactory.getInstance("RSA"); | ||
101 | + PrivateKey privateKey = kf.generatePrivate(new PKCS8EncodedKeySpec(bytes)); | ||
102 | + | ||
103 | + String jws = Jwts.builder() | ||
104 | + .serializeToJsonWith(new JacksonSerializer(new ObjectMapper())) | ||
105 | + .setHeader(header) | ||
106 | + .setClaims(body) | ||
107 | + .signWith(privateKey, SignatureAlgorithm.RS256) | ||
108 | + .compact(); | ||
109 | + | ||
110 | + log.info("{}", jws); | ||
111 | + | ||
112 | + // Issue | ||
113 | + IssueChannelAccessTokenResponse issueChannelAccessTokenResponse = | ||
114 | + target.issueChannelTokenByJWT(jws).get(); | ||
115 | + | ||
116 | + log.info("{}", issueChannelAccessTokenResponse); | ||
117 | + assertThat(issueChannelAccessTokenResponse.getExpiresInSecs()).isEqualTo(60); | ||
118 | + | ||
119 | + // Revoke | ||
120 | + target.revokeChannelTokenByJWT( | ||
121 | + channelId, | ||
122 | + channelSecret, | ||
123 | + issueChannelAccessTokenResponse.getAccessToken()) | ||
124 | + .get(); | ||
125 | + } | ||
126 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.net.URI; | ||
20 | + | ||
21 | +import com.fasterxml.jackson.databind.DeserializationFeature; | ||
22 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
23 | + | ||
24 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
25 | + | ||
26 | +import retrofit2.Retrofit; | ||
27 | +import retrofit2.converter.jackson.JacksonConverterFactory; | ||
28 | + | ||
29 | +public class ManageAudienceClientFactory { | ||
30 | + public static ManageAudienceClient create(IntegrationTestSettings settings) { | ||
31 | + ObjectMapper objectMapper = ModelObjectMapper | ||
32 | + .createNewObjectMapper() | ||
33 | + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, | ||
34 | + settings.isFailOnUnknownProperties()); | ||
35 | + | ||
36 | + Retrofit.Builder retrofitBuilder = new Retrofit.Builder() | ||
37 | + .addConverterFactory(JacksonConverterFactory.create(objectMapper)); | ||
38 | + | ||
39 | + return ManageAudienceClient | ||
40 | + .builder() | ||
41 | + .channelToken(settings.getToken()) | ||
42 | + .apiEndPoint(URI.create(settings.getEndpoint())) | ||
43 | + .retrofitBuilder(retrofitBuilder) | ||
44 | + .build(); | ||
45 | + } | ||
46 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.util.List; | ||
21 | +import java.util.UUID; | ||
22 | +import java.util.concurrent.ExecutionException; | ||
23 | +import java.util.stream.Collectors; | ||
24 | + | ||
25 | +import org.junit.Assert; | ||
26 | +import org.junit.Before; | ||
27 | +import org.junit.Test; | ||
28 | + | ||
29 | +import com.linecorp.bot.model.manageaudience.AudienceGroup; | ||
30 | +import com.linecorp.bot.model.manageaudience.AudienceGroupAuthorityLevel; | ||
31 | +import com.linecorp.bot.model.manageaudience.AudienceGroupCreateRoute; | ||
32 | +import com.linecorp.bot.model.manageaudience.request.AddAudienceToAudienceGroupRequest; | ||
33 | +import com.linecorp.bot.model.manageaudience.request.Audience; | ||
34 | +import com.linecorp.bot.model.manageaudience.request.CreateAudienceGroupRequest; | ||
35 | +import com.linecorp.bot.model.manageaudience.request.CreateClickBasedAudienceGroupRequest; | ||
36 | +import com.linecorp.bot.model.manageaudience.request.CreateImpBasedAudienceGroupRequest; | ||
37 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupAuthorityLevelRequest; | ||
38 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupDescriptionRequest; | ||
39 | +import com.linecorp.bot.model.manageaudience.response.CreateAudienceGroupResponse; | ||
40 | +import com.linecorp.bot.model.manageaudience.response.CreateClickBasedAudienceGroupResponse; | ||
41 | +import com.linecorp.bot.model.manageaudience.response.CreateImpBasedAudienceGroupResponse; | ||
42 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceDataResponse; | ||
43 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupAuthorityLevelResponse; | ||
44 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupsResponse; | ||
45 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
46 | + | ||
47 | +import lombok.extern.slf4j.Slf4j; | ||
48 | + | ||
49 | +@Slf4j | ||
50 | +public class ManageAudienceIntegrationTest { | ||
51 | + private ManageAudienceClient target; | ||
52 | + private IntegrationTestSettings settings; | ||
53 | + | ||
54 | + @Before | ||
55 | + public void setUp() throws IOException { | ||
56 | + settings = IntegrationTestSettingsLoader.load(); | ||
57 | + target = ManageAudienceClientFactory.create(settings); | ||
58 | + } | ||
59 | + | ||
60 | + @Test | ||
61 | + public void createAudienceGroup() throws Exception { | ||
62 | + CreateAudienceGroupResponse createResponse = target | ||
63 | + .createAudienceGroup(CreateAudienceGroupRequest | ||
64 | + .builder() | ||
65 | + .description("test" + UUID.randomUUID()) | ||
66 | + .isIfaAudience(true) | ||
67 | + .uploadDescription("test") | ||
68 | + .audiences( | ||
69 | + settings.getAudienceIfas().stream() | ||
70 | + .map(Audience::new) | ||
71 | + .collect(Collectors.toList()) | ||
72 | + ).build() | ||
73 | + ).get(); | ||
74 | + log.info(createResponse.toString()); | ||
75 | + | ||
76 | + long audienceGroupId = createResponse.getAudienceGroupId(); | ||
77 | + | ||
78 | + BotApiResponse addResponse = target | ||
79 | + .addAudienceToAudienceGroup( | ||
80 | + AddAudienceToAudienceGroupRequest | ||
81 | + .builder() | ||
82 | + .audienceGroupId(audienceGroupId) | ||
83 | + .audiences(settings.getAudienceIfas().stream() | ||
84 | + .map(Audience::new) | ||
85 | + .collect(Collectors | ||
86 | + .toList())) | ||
87 | + .build() | ||
88 | + ) | ||
89 | + .get(); | ||
90 | + log.info(addResponse.toString()); | ||
91 | + | ||
92 | + BotApiResponse updateResponse = target.updateAudienceGroupDescription( | ||
93 | + audienceGroupId, | ||
94 | + UpdateAudienceGroupDescriptionRequest | ||
95 | + .builder() | ||
96 | + .description("Hello" + UUID.randomUUID()) | ||
97 | + .build() | ||
98 | + ).get(); | ||
99 | + log.info(updateResponse.toString()); | ||
100 | + | ||
101 | + BotApiResponse deleteResponse = target.deleteAudienceGroup(audienceGroupId).get(); | ||
102 | + log.info(deleteResponse.toString()); | ||
103 | + } | ||
104 | + | ||
105 | + @Test | ||
106 | + public void createClickBasedAudienceGroup() throws Exception { | ||
107 | + CreateClickBasedAudienceGroupResponse response = target | ||
108 | + .createClickBasedAudienceGroup(CreateClickBasedAudienceGroupRequest | ||
109 | + .builder() | ||
110 | + .description("test " + UUID.randomUUID()) | ||
111 | + .requestId(settings.getRetargetingRequestId()) | ||
112 | + .build() | ||
113 | + ) | ||
114 | + .get(); | ||
115 | + log.info(response.toString()); | ||
116 | + } | ||
117 | + | ||
118 | + @Test | ||
119 | + public void createImpBasedAudienceGroup() throws Exception { | ||
120 | + CreateImpBasedAudienceGroupResponse response = target | ||
121 | + .createImpBasedAudienceGroup(CreateImpBasedAudienceGroupRequest | ||
122 | + .builder() | ||
123 | + .description("test " + UUID.randomUUID()) | ||
124 | + .requestId(settings.getRetargetingRequestId()) | ||
125 | + .build() | ||
126 | + ) | ||
127 | + .get(); | ||
128 | + log.info(response.toString()); | ||
129 | + } | ||
130 | + | ||
131 | + @Test | ||
132 | + public void getAudienceGroups() throws ExecutionException, InterruptedException { | ||
133 | + GetAudienceGroupsResponse response = target | ||
134 | + .getAudienceGroups(1L, null, null, 40L, | ||
135 | + false, AudienceGroupCreateRoute.OA_MANAGER) | ||
136 | + .get(); | ||
137 | + Assert.assertEquals(1L, response.getPage().longValue()); | ||
138 | + Assert.assertEquals(40L, response.getSize().longValue()); | ||
139 | + Assert.assertNotNull(response.getTotalCount()); | ||
140 | + log.info(response.toString()); | ||
141 | + | ||
142 | + List<AudienceGroup> audienceGroups = response.getAudienceGroups(); | ||
143 | + for (AudienceGroup audienceGroup : audienceGroups) { | ||
144 | + GetAudienceDataResponse dataResponse = target.getAudienceData( | ||
145 | + audienceGroup.getAudienceGroupId()).get(); | ||
146 | + Assert.assertNotNull(dataResponse.getAudienceGroup()); | ||
147 | + Assert.assertEquals(audienceGroup.getAudienceGroupId(), | ||
148 | + dataResponse.getAudienceGroup().getAudienceGroupId()); | ||
149 | + log.info("id={} data={}", audienceGroup.getAudienceGroupId(), dataResponse); | ||
150 | + } | ||
151 | + } | ||
152 | + | ||
153 | + @Test | ||
154 | + public void getAudienceGroupAuthorityLevel() throws ExecutionException, InterruptedException { | ||
155 | + GetAudienceGroupAuthorityLevelResponse response = target | ||
156 | + .getAudienceGroupAuthorityLevel() | ||
157 | + .get(); | ||
158 | + log.info(response.toString()); | ||
159 | + | ||
160 | + AudienceGroupAuthorityLevel origLevel = response.getAuthorityLevel(); | ||
161 | + AudienceGroupAuthorityLevel inverted = origLevel == AudienceGroupAuthorityLevel.PRIVATE | ||
162 | + ? AudienceGroupAuthorityLevel.PUBLIC | ||
163 | + : AudienceGroupAuthorityLevel.PRIVATE; | ||
164 | + | ||
165 | + BotApiResponse invertResponse = target.updateAudienceGroupAuthorityLevel( | ||
166 | + UpdateAudienceGroupAuthorityLevelRequest | ||
167 | + .builder() | ||
168 | + .authorityLevel(inverted) | ||
169 | + .build()).get(); | ||
170 | + log.info(invertResponse.toString()); | ||
171 | + | ||
172 | + BotApiResponse revertResponse = target.updateAudienceGroupAuthorityLevel( | ||
173 | + UpdateAudienceGroupAuthorityLevelRequest | ||
174 | + .builder() | ||
175 | + .authorityLevel(origLevel) | ||
176 | + .build()).get(); | ||
177 | + log.info(revertResponse.toString()); | ||
178 | + } | ||
179 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.util.Collections; | ||
21 | + | ||
22 | +import org.junit.Before; | ||
23 | +import org.junit.Test; | ||
24 | + | ||
25 | +import com.linecorp.bot.model.Narrowcast; | ||
26 | +import com.linecorp.bot.model.message.TextMessage; | ||
27 | +import com.linecorp.bot.model.narrowcast.Filter; | ||
28 | +import com.linecorp.bot.model.narrowcast.filter.AgeDemographicFilter; | ||
29 | +import com.linecorp.bot.model.narrowcast.filter.AgeDemographicFilter.Age; | ||
30 | +import com.linecorp.bot.model.narrowcast.filter.AppTypeDemographicFilter; | ||
31 | +import com.linecorp.bot.model.narrowcast.filter.AppTypeDemographicFilter.AppType; | ||
32 | +import com.linecorp.bot.model.narrowcast.filter.GenderDemographicFilter; | ||
33 | +import com.linecorp.bot.model.narrowcast.filter.GenderDemographicFilter.Gender; | ||
34 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
35 | +import com.linecorp.bot.model.response.NarrowcastProgressResponse; | ||
36 | +import com.linecorp.bot.model.response.NarrowcastProgressResponse.Phase; | ||
37 | + | ||
38 | +import lombok.extern.slf4j.Slf4j; | ||
39 | + | ||
40 | +@Slf4j | ||
41 | +public class NarrowcastIntegrationTest { | ||
42 | + private LineMessagingClient target; | ||
43 | + | ||
44 | + @Before | ||
45 | + public void setUp() throws IOException { | ||
46 | + IntegrationTestSettings settings = IntegrationTestSettingsLoader.load(); | ||
47 | + target = LineMessagingClientFactory.create(settings); | ||
48 | + } | ||
49 | + | ||
50 | + @Test | ||
51 | + public void narrowcastGender() throws Exception { | ||
52 | + testNarrowcast(new Narrowcast(new TextMessage("Narrowcast test(gender=male)"), | ||
53 | + Filter.builder() | ||
54 | + .demographic( | ||
55 | + GenderDemographicFilter | ||
56 | + .builder() | ||
57 | + .oneOf(Collections.singletonList(Gender.MALE)) | ||
58 | + .build() | ||
59 | + ).build())); | ||
60 | + } | ||
61 | + | ||
62 | + @Test | ||
63 | + public void narrowcastAge() throws Exception { | ||
64 | + testNarrowcast(new Narrowcast(new TextMessage("Narrowcast test(Age)"), | ||
65 | + Filter.builder() | ||
66 | + .demographic( | ||
67 | + AgeDemographicFilter | ||
68 | + .builder() | ||
69 | + .gte(Age.AGE_15) | ||
70 | + .lt(Age.AGE_40) | ||
71 | + .build() | ||
72 | + ).build())); | ||
73 | + } | ||
74 | + | ||
75 | + @Test | ||
76 | + public void narrowcastAppType() throws Exception { | ||
77 | + testNarrowcast(new Narrowcast(new TextMessage("Narrowcast test(AppType)"), | ||
78 | + Filter.builder() | ||
79 | + .demographic( | ||
80 | + AppTypeDemographicFilter | ||
81 | + .builder() | ||
82 | + .oneOf(Collections.singletonList(AppType.IOS)) | ||
83 | + .build() | ||
84 | + ).build())); | ||
85 | + } | ||
86 | + | ||
87 | + private void testNarrowcast(Narrowcast narrowcast) throws Exception { | ||
88 | + BotApiResponse response = target.narrowcast(narrowcast).get(); | ||
89 | + log.info("Narrowcast response={}", response); | ||
90 | + for (int i = 0; i < 10; i++) { | ||
91 | + NarrowcastProgressResponse progressResponse = target.getNarrowcastProgress( | ||
92 | + response.getRequestId()).get(); | ||
93 | + log.info("Progress={}", progressResponse); | ||
94 | + log.info("Progress response={}", progressResponse); | ||
95 | + if (progressResponse.getPhase() == Phase.SUCCEEDED | ||
96 | + || progressResponse.getPhase() == Phase.FAILED) { | ||
97 | + break; | ||
98 | + } | ||
99 | + Thread.sleep(1000); | ||
100 | + } | ||
101 | + } | ||
102 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/BotApiResponseBody.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Collections.emptyList; | ||
20 | + | ||
21 | +import java.util.List; | ||
22 | + | ||
23 | +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; | ||
24 | +import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder; | ||
25 | + | ||
26 | +import com.linecorp.bot.client.BotApiResponseBody.BotApiResponseBodyBuilder; | ||
27 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
28 | + | ||
29 | +import lombok.Builder; | ||
30 | +import lombok.Builder.Default; | ||
31 | +import lombok.Value; | ||
32 | + | ||
33 | +/** | ||
34 | + * Response body of BotApiResponse. | ||
35 | + * | ||
36 | + * <p>Developer will use {@link BotApiResponse} returned by {@link #withRequestId} method. | ||
37 | + * | ||
38 | + * @see BotApiResponse | ||
39 | + */ | ||
40 | +@Value | ||
41 | +@Builder | ||
42 | +@JsonDeserialize(builder = BotApiResponseBodyBuilder.class) | ||
43 | +class BotApiResponseBody { | ||
44 | + @JsonPOJOBuilder(withPrefix = "") | ||
45 | + public static class BotApiResponseBodyBuilder { | ||
46 | + // filled by lombok. | ||
47 | + } | ||
48 | + | ||
49 | + String message; | ||
50 | + @Default | ||
51 | + List<String> details = emptyList(); | ||
52 | + | ||
53 | + BotApiResponse withRequestId(final String requestId) { | ||
54 | + return new BotApiResponse(requestId, message, details); | ||
55 | + } | ||
56 | +} |
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static com.linecorp.bot.client.LineMessagingClientBuilder.buildAuthenticationInterceptor; | ||
20 | +import static com.linecorp.bot.client.LineMessagingClientBuilder.buildLoggingInterceptor; | ||
21 | +import static com.linecorp.bot.client.LineMessagingClientBuilder.createDefaultRetrofitBuilder; | ||
22 | + | ||
23 | +import java.net.URI; | ||
24 | + | ||
25 | +import lombok.NonNull; | ||
26 | +import lombok.Setter; | ||
27 | +import lombok.experimental.Accessors; | ||
28 | +import okhttp3.OkHttpClient; | ||
29 | +import okhttp3.OkHttpClient.Builder; | ||
30 | +import retrofit2.Retrofit; | ||
31 | + | ||
32 | +@Setter | ||
33 | +@Accessors(fluent = true) | ||
34 | +public class ChannelManagementClientBuilder { | ||
35 | + private URI apiEndPoint = LineClientConstants.DEFAULT_API_END_POINT; | ||
36 | + private ChannelTokenSupplier channelTokenSupplier; | ||
37 | + | ||
38 | + /** | ||
39 | + * Create a new {@link ChannelManagementClientBuilder} with specified {@link ChannelTokenSupplier}. | ||
40 | + */ | ||
41 | + public static ChannelManagementClientBuilder create(@NonNull ChannelTokenSupplier channelTokenSupplier) { | ||
42 | + return new ChannelManagementClientBuilder() | ||
43 | + .channelTokenSupplier(channelTokenSupplier); | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * Build a new {@link ChannelManagementSyncClient}. | ||
48 | + */ | ||
49 | + public ChannelManagementSyncClient build() { | ||
50 | + final Builder okHttpClientBuilder = new Builder(); | ||
51 | + | ||
52 | + okHttpClientBuilder | ||
53 | + .addInterceptor(buildAuthenticationInterceptor(channelTokenSupplier)) | ||
54 | + .addInterceptor(buildLoggingInterceptor()); | ||
55 | + | ||
56 | + final OkHttpClient okHttpClient = okHttpClientBuilder.build(); | ||
57 | + | ||
58 | + final Retrofit.Builder retrofitBuilder = createDefaultRetrofitBuilder(); | ||
59 | + | ||
60 | + retrofitBuilder.client(okHttpClient); | ||
61 | + retrofitBuilder.baseUrl(apiEndPoint.toString()); | ||
62 | + final Retrofit retrofit = retrofitBuilder.build(); | ||
63 | + | ||
64 | + final ChannelManagementClientRetrofitIface retrofitIface = | ||
65 | + retrofit.create(ChannelManagementClientRetrofitIface.class); | ||
66 | + return ChannelManagementSyncClientImpl.of(retrofitIface); | ||
67 | + } | ||
68 | +} |
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import com.linecorp.bot.liff.LiffView; | ||
20 | +import com.linecorp.bot.liff.request.LiffAppAddRequest; | ||
21 | +import com.linecorp.bot.liff.response.LiffAppAddResponse; | ||
22 | +import com.linecorp.bot.liff.response.LiffAppsResponse; | ||
23 | + | ||
24 | +import retrofit2.Call; | ||
25 | +import retrofit2.http.Body; | ||
26 | +import retrofit2.http.DELETE; | ||
27 | +import retrofit2.http.GET; | ||
28 | +import retrofit2.http.POST; | ||
29 | +import retrofit2.http.PUT; | ||
30 | +import retrofit2.http.Path; | ||
31 | + | ||
32 | +/** | ||
33 | + * Package private interface for Retrofit binding. | ||
34 | + * | ||
35 | + * <p>You can use LIFF API via {@link ChannelManagementSyncClient}. | ||
36 | + * It's independent from Retrofit implementation. | ||
37 | + */ | ||
38 | +interface ChannelManagementClientRetrofitIface { | ||
39 | + @POST("liff/v1/apps") | ||
40 | + Call<LiffAppAddResponse> addLiffApp(@Body LiffAppAddRequest liffAppAddRequest); | ||
41 | + | ||
42 | + @PUT("liff/v1/apps/{liffId}/view") | ||
43 | + Call<Void> updateLiffApp(@Path("liffId") String liffId, @Body LiffView liffView); | ||
44 | + | ||
45 | + @GET("liff/v1/apps") | ||
46 | + Call<LiffAppsResponse> getAllLiffApps(); | ||
47 | + | ||
48 | + @DELETE("liff/v1/apps/{liffId}") | ||
49 | + Call<Void> deleteLiffApp(@Path("liffId") String liffId); | ||
50 | +} |
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import com.linecorp.bot.liff.LiffView; | ||
20 | +import com.linecorp.bot.liff.request.LiffAppAddRequest; | ||
21 | +import com.linecorp.bot.liff.response.LiffAppAddResponse; | ||
22 | +import com.linecorp.bot.liff.response.LiffAppsResponse; | ||
23 | + | ||
24 | +public interface ChannelManagementSyncClient { | ||
25 | + LiffAppAddResponse addLiffApp(LiffAppAddRequest liffView); | ||
26 | + | ||
27 | + void updateLiffApp(String liffId, LiffView liffView); | ||
28 | + | ||
29 | + LiffAppsResponse getAllLiffApps(); | ||
30 | + | ||
31 | + void deleteLiffApp(String liffId); | ||
32 | + | ||
33 | + static ChannelManagementClientBuilder builder(final ChannelTokenSupplier channelTokenSupplier) { | ||
34 | + return ChannelManagementClientBuilder.create(channelTokenSupplier); | ||
35 | + } | ||
36 | +} |
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static com.linecorp.bot.client.LineMessagingClientImpl.toFuture; | ||
20 | + | ||
21 | +import java.util.concurrent.ExecutionException; | ||
22 | + | ||
23 | +import com.linecorp.bot.client.exception.LineMessagingException; | ||
24 | +import com.linecorp.bot.liff.LiffView; | ||
25 | +import com.linecorp.bot.liff.request.LiffAppAddRequest; | ||
26 | +import com.linecorp.bot.liff.response.LiffAppAddResponse; | ||
27 | +import com.linecorp.bot.liff.response.LiffAppsResponse; | ||
28 | + | ||
29 | +import lombok.AllArgsConstructor; | ||
30 | +import retrofit2.Call; | ||
31 | + | ||
32 | +@AllArgsConstructor(staticName = "of") | ||
33 | +public class ChannelManagementSyncClientImpl implements ChannelManagementSyncClient { | ||
34 | + ChannelManagementClientRetrofitIface retrofitImpl; | ||
35 | + | ||
36 | + @Override | ||
37 | + public LiffAppAddResponse addLiffApp(final LiffAppAddRequest liffAppAddRequest) { | ||
38 | + return syncGet(retrofitImpl.addLiffApp(liffAppAddRequest)); | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public void updateLiffApp(String liffId, LiffView liffView) { | ||
43 | + syncGet(retrofitImpl.updateLiffApp(liffId, liffView)); | ||
44 | + } | ||
45 | + | ||
46 | + @Override | ||
47 | + public LiffAppsResponse getAllLiffApps() { | ||
48 | + return syncGet(retrofitImpl.getAllLiffApps()); | ||
49 | + } | ||
50 | + | ||
51 | + @Override | ||
52 | + public void deleteLiffApp(final String liffId) { | ||
53 | + syncGet(retrofitImpl.deleteLiffApp(liffId)); | ||
54 | + } | ||
55 | + | ||
56 | + private <T> T syncGet(Call<T> wrap) { | ||
57 | + try { | ||
58 | + return toFuture(wrap).get(); | ||
59 | + } catch (ExecutionException | InterruptedException e) { | ||
60 | + final Throwable cause; | ||
61 | + if (e.getCause() instanceof LineMessagingException) { | ||
62 | + cause = e.getCause(); | ||
63 | + } else { | ||
64 | + cause = e; | ||
65 | + } | ||
66 | + throw new RuntimeException(cause); | ||
67 | + } | ||
68 | + } | ||
69 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.util.function.Supplier; | ||
20 | + | ||
21 | +/** | ||
22 | + * Special {@link Supplier} for Channel Access Token. | ||
23 | + * | ||
24 | + * <p>You can implement it to return same channel tokens. | ||
25 | + * Or refresh tokens internally. | ||
26 | + */ | ||
27 | +@FunctionalInterface | ||
28 | +public interface ChannelTokenSupplier extends Supplier<String> { | ||
29 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/ExceptionConverter.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Collections.singletonMap; | ||
20 | + | ||
21 | +import java.io.IOException; | ||
22 | +import java.util.function.Function; | ||
23 | + | ||
24 | +import com.fasterxml.jackson.databind.InjectableValues; | ||
25 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
26 | +import com.fasterxml.jackson.databind.ObjectReader; | ||
27 | + | ||
28 | +import com.linecorp.bot.client.exception.BadRequestException; | ||
29 | +import com.linecorp.bot.client.exception.ForbiddenException; | ||
30 | +import com.linecorp.bot.client.exception.GeneralLineMessagingException; | ||
31 | +import com.linecorp.bot.client.exception.LineMessagingException; | ||
32 | +import com.linecorp.bot.client.exception.LineServerException; | ||
33 | +import com.linecorp.bot.client.exception.NotFoundException; | ||
34 | +import com.linecorp.bot.client.exception.TooManyRequestsException; | ||
35 | +import com.linecorp.bot.client.exception.UnauthorizedException; | ||
36 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
37 | + | ||
38 | +import okhttp3.ResponseBody; | ||
39 | +import retrofit2.Response; | ||
40 | + | ||
41 | +class ExceptionConverter implements Function<Response<?>, LineMessagingException> { | ||
42 | + public static final ObjectReader OBJECT_READER = new ObjectMapper().readerFor(ErrorResponse.class); | ||
43 | + | ||
44 | + @Override | ||
45 | + public LineMessagingException apply(Response<?> response) { | ||
46 | + final String requestId = response.headers().get("x-line-request-id"); | ||
47 | + try { | ||
48 | + return applyInternal(requestId, response); | ||
49 | + } catch (Exception e) { | ||
50 | + final ErrorResponse errorResponse = new ErrorResponse(requestId, null, null); | ||
51 | + return new GeneralLineMessagingException(e.getMessage(), errorResponse, e); | ||
52 | + } | ||
53 | + } | ||
54 | + | ||
55 | + private static LineMessagingException applyInternal(final String requestId, final Response<?> response) | ||
56 | + throws IOException { | ||
57 | + final int code = response.code(); | ||
58 | + final ResponseBody responseBody = response.errorBody(); | ||
59 | + | ||
60 | + final ErrorResponse errorResponse = OBJECT_READER | ||
61 | + .with(new InjectableValues.Std(singletonMap("requestId", requestId))) | ||
62 | + .readValue(responseBody.byteStream()); | ||
63 | + | ||
64 | + switch (code) { | ||
65 | + case 400: | ||
66 | + return new BadRequestException( | ||
67 | + errorResponse.getMessage(), errorResponse); | ||
68 | + case 401: | ||
69 | + return new UnauthorizedException( | ||
70 | + errorResponse.getMessage(), errorResponse); | ||
71 | + case 403: | ||
72 | + return new ForbiddenException( | ||
73 | + errorResponse.getMessage(), errorResponse); | ||
74 | + case 404: | ||
75 | + return new NotFoundException( | ||
76 | + errorResponse.getMessage(), errorResponse); | ||
77 | + case 429: | ||
78 | + return new TooManyRequestsException( | ||
79 | + errorResponse.getMessage(), errorResponse); | ||
80 | + case 500: | ||
81 | + return new LineServerException( | ||
82 | + errorResponse.getMessage(), errorResponse); | ||
83 | + } | ||
84 | + | ||
85 | + return new GeneralLineMessagingException(errorResponse.getMessage(), errorResponse, null); | ||
86 | + } | ||
87 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import lombok.AllArgsConstructor; | ||
20 | +import lombok.NonNull; | ||
21 | +import lombok.ToString; | ||
22 | + | ||
23 | +/** | ||
24 | + * Implementation of {@link ChannelTokenSupplier} which always return fixed channel token. | ||
25 | + */ | ||
26 | +@AllArgsConstructor(staticName = "of") | ||
27 | +@ToString | ||
28 | +public final class FixedChannelTokenSupplier implements ChannelTokenSupplier { | ||
29 | + @NonNull | ||
30 | + private final String channelToken; | ||
31 | + | ||
32 | + @Override | ||
33 | + public String get() { | ||
34 | + return channelToken; | ||
35 | + } | ||
36 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/HeaderInterceptor.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | + | ||
21 | +import lombok.AllArgsConstructor; | ||
22 | +import okhttp3.Interceptor; | ||
23 | +import okhttp3.Request; | ||
24 | +import okhttp3.Response; | ||
25 | + | ||
26 | +@AllArgsConstructor(staticName = "forChannelTokenSupplier") | ||
27 | +class HeaderInterceptor implements Interceptor { | ||
28 | + private static final String USER_AGENT = | ||
29 | + "line-botsdk-java/" + HeaderInterceptor.class.getPackage().getImplementationVersion(); | ||
30 | + private final ChannelTokenSupplier channelTokenSupplier; | ||
31 | + | ||
32 | + @Override | ||
33 | + public Response intercept(Chain chain) throws IOException { | ||
34 | + final String channelToken = channelTokenSupplier.get(); | ||
35 | + Request request = chain.request().newBuilder() | ||
36 | + .addHeader("Authorization", "Bearer " + channelToken) | ||
37 | + .addHeader("User-Agent", USER_AGENT) | ||
38 | + .build(); | ||
39 | + return chain.proceed(request); | ||
40 | + } | ||
41 | + | ||
42 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineBlobClient.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.util.concurrent.CompletableFuture; | ||
20 | + | ||
21 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
22 | + | ||
23 | +/** | ||
24 | + * API client of blog (binary large object). | ||
25 | + */ | ||
26 | +public interface LineBlobClient { | ||
27 | + /** | ||
28 | + * Download image, video, and audio data sent from users. | ||
29 | + * | ||
30 | + * @see <a href="https://developers.line.me/en/reference/messaging-api/#get-content">//developers.line.me/en/reference/messaging-api/#get-content</a> | ||
31 | + */ | ||
32 | + CompletableFuture<MessageContentResponse> getMessageContent(String messageId); | ||
33 | + | ||
34 | + /** | ||
35 | + * Download rich menu image. | ||
36 | + * | ||
37 | + * @see <a href="https://developers.line.me/en/docs/messaging-api/reference/#download-rich-menu-image">//developers.line.me/en/docs/messaging-api/reference/#download-rich-menu-image</a> | ||
38 | + */ | ||
39 | + CompletableFuture<MessageContentResponse> getRichMenuImage(String richMenuId); | ||
40 | + | ||
41 | + /** | ||
42 | + * Set RichMenu image. | ||
43 | + * | ||
44 | + * @see <a href="https://developers.line.me/en/docs/messaging-api/reference/#upload-rich-menu-image">//developers.line.me/en/docs/messaging-api/reference/#upload-rich-menu-image</a> | ||
45 | + */ | ||
46 | + CompletableFuture<BotApiResponse> setRichMenuImage( | ||
47 | + String richMenuId, String contentType, byte[] content); | ||
48 | + | ||
49 | + static LineBlobClientBuilder builder(String channelToken) { | ||
50 | + return builder(FixedChannelTokenSupplier.of(channelToken)); | ||
51 | + } | ||
52 | + | ||
53 | + static LineBlobClientBuilder builder(ChannelTokenSupplier channelTokenSupplier) { | ||
54 | + return new LineBlobClientBuilder().channelTokenSupplier(channelTokenSupplier); | ||
55 | + } | ||
56 | +} |
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Objects.requireNonNull; | ||
20 | + | ||
21 | +import java.net.URI; | ||
22 | +import java.util.ArrayList; | ||
23 | +import java.util.List; | ||
24 | +import java.util.concurrent.TimeUnit; | ||
25 | + | ||
26 | +import org.slf4j.Logger; | ||
27 | +import org.slf4j.LoggerFactory; | ||
28 | + | ||
29 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
30 | + | ||
31 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
32 | + | ||
33 | +import lombok.NonNull; | ||
34 | +import lombok.Setter; | ||
35 | +import lombok.ToString; | ||
36 | +import lombok.experimental.Accessors; | ||
37 | +import lombok.experimental.PackagePrivate; | ||
38 | +import okhttp3.Interceptor; | ||
39 | +import okhttp3.OkHttpClient; | ||
40 | +import okhttp3.logging.HttpLoggingInterceptor; | ||
41 | +import okhttp3.logging.HttpLoggingInterceptor.Level; | ||
42 | +import retrofit2.Retrofit; | ||
43 | +import retrofit2.converter.jackson.JacksonConverterFactory; | ||
44 | + | ||
45 | +@ToString | ||
46 | +@Accessors(fluent = true) | ||
47 | +public class LineBlobClientBuilder { | ||
48 | + private static final ObjectMapper objectMapper = ModelObjectMapper.createNewObjectMapper(); | ||
49 | + | ||
50 | + /** | ||
51 | + * Use {@link LineBlobClient#builder} to create instance. | ||
52 | + */ | ||
53 | + @PackagePrivate | ||
54 | + LineBlobClientBuilder() { | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * API Endpoint. | ||
59 | + * | ||
60 | + * <p>Default value = "https://api-data.line.me/". | ||
61 | + */ | ||
62 | + private URI apiEndPoint = LineClientConstants.DEFAULT_BLOB_END_POINT; | ||
63 | + | ||
64 | + /** | ||
65 | + * API Endpoint. | ||
66 | + * | ||
67 | + * @deprecated use {@link #apiEndPoint(URI)}. | ||
68 | + */ | ||
69 | + @Deprecated | ||
70 | + public LineBlobClientBuilder apiEndPoint(String apiEndPoint) { | ||
71 | + return apiEndPoint(URI.create(apiEndPoint)); | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * API Endpoint. | ||
76 | + * | ||
77 | + * <p>Default value = "https://api-data.line.me/". | ||
78 | + */ // We can remove this after delete `setApiEndPoint(String apiEndPoint)`. | ||
79 | + public LineBlobClientBuilder apiEndPoint(URI apiEndPoint) { | ||
80 | + this.apiEndPoint = requireNonNull(apiEndPoint, "apiEndPoint"); | ||
81 | + return this; | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * Connection timeout. | ||
86 | + * | ||
87 | + * <p>Default value = {@value LineClientConstants#DEFAULT_CONNECT_TIMEOUT_MILLIS}ms. | ||
88 | + */ | ||
89 | + @Setter | ||
90 | + private long connectTimeout = LineClientConstants.DEFAULT_CONNECT_TIMEOUT_MILLIS; | ||
91 | + | ||
92 | + /** | ||
93 | + * Connection timeout. | ||
94 | + * | ||
95 | + * <p>Default value = {@value LineClientConstants#DEFAULT_READ_TIMEOUT_MILLIS}ms. | ||
96 | + */ | ||
97 | + @Setter | ||
98 | + private long readTimeout = LineClientConstants.DEFAULT_READ_TIMEOUT_MILLIS; | ||
99 | + | ||
100 | + /** | ||
101 | + * Write timeout. | ||
102 | + * | ||
103 | + * <p>Default value = {@value LineClientConstants#DEFAULT_WRITE_TIMEOUT_MILLIS}ms. | ||
104 | + */ | ||
105 | + @Setter | ||
106 | + private long writeTimeout = LineClientConstants.DEFAULT_WRITE_TIMEOUT_MILLIS; | ||
107 | + | ||
108 | + /** | ||
109 | + * Channel token supplier of this client. | ||
110 | + * | ||
111 | + * <p>MUST BE NULL except you configured your own | ||
112 | + */ | ||
113 | + @Setter | ||
114 | + private ChannelTokenSupplier channelTokenSupplier; | ||
115 | + | ||
116 | + /** | ||
117 | + * Custom {@link Retrofit.Builder} used internally. | ||
118 | + * | ||
119 | + * <p>If you want to use your own setting, specify {@link Retrofit.Builder} instance. | ||
120 | + * Default builder is used in case of {@code null} (default). | ||
121 | + * | ||
122 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
123 | + * | ||
124 | + * @see #createDefaultRetrofitBuilder() | ||
125 | + */ | ||
126 | + @Setter | ||
127 | + private Retrofit.Builder retrofitBuilder; | ||
128 | + | ||
129 | + /** | ||
130 | + * Add authentication header. | ||
131 | + * | ||
132 | + * <p>Default = {@value}. If you manage authentication header yourself, set to {@code false}. | ||
133 | + */ | ||
134 | + @Setter | ||
135 | + private boolean addAuthenticationHeader = true; | ||
136 | + | ||
137 | + private OkHttpClient.Builder okHttpClientBuilder; | ||
138 | + | ||
139 | + /** | ||
140 | + * Custom interceptors. | ||
141 | + * | ||
142 | + * <p>You can add your own interceptors. | ||
143 | + * | ||
144 | + * <p>Note: Authentication interceptor is automatically added by default. | ||
145 | + * | ||
146 | + * @see #addAuthenticationHeader(boolean) | ||
147 | + */ | ||
148 | + @Setter | ||
149 | + private List<Interceptor> additionalInterceptors = new ArrayList<>(); | ||
150 | + | ||
151 | + /** | ||
152 | + * Set fixed channel token. This overwrites {@link #channelTokenSupplier(ChannelTokenSupplier)}. | ||
153 | + * | ||
154 | + * @see #channelTokenSupplier(ChannelTokenSupplier) | ||
155 | + */ | ||
156 | + public LineBlobClientBuilder channelToken(String channelToken) { | ||
157 | + channelTokenSupplier(FixedChannelTokenSupplier.of(channelToken)); | ||
158 | + return this; | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * Set customized OkHttpClient.Builder. | ||
163 | + * | ||
164 | + * <p>In case of you need your own customized {@link OkHttpClient}, | ||
165 | + * this builder allows specify {@link OkHttpClient.Builder} instance. | ||
166 | + * | ||
167 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
168 | + * | ||
169 | + * @param addAuthenticationHeader If true, all default okhttp interceptors ignored. | ||
170 | + * You should insert authentication headers yourself. | ||
171 | + */ | ||
172 | + public LineBlobClientBuilder okHttpClientBuilder( | ||
173 | + final @NonNull OkHttpClient.Builder okHttpClientBuilder, | ||
174 | + final boolean addAuthenticationHeader) { | ||
175 | + this.okHttpClientBuilder = okHttpClientBuilder; | ||
176 | + this.addAuthenticationHeader = addAuthenticationHeader; | ||
177 | + | ||
178 | + return this; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Creates a new {@link LineBlobService}. | ||
183 | + */ | ||
184 | + <T> T buildRetrofitIface(URI apiEndPoint, Class<T> retrofitIFace) { | ||
185 | + if (okHttpClientBuilder == null) { | ||
186 | + okHttpClientBuilder = new OkHttpClient.Builder(); | ||
187 | + } | ||
188 | + | ||
189 | + // Add interceptors. | ||
190 | + if (addAuthenticationHeader) { | ||
191 | + okHttpClientBuilder.addInterceptor(buildAuthenticationInterceptor(channelTokenSupplier)); | ||
192 | + } | ||
193 | + if (additionalInterceptors != null) { | ||
194 | + additionalInterceptors.forEach(okHttpClientBuilder::addInterceptor); | ||
195 | + } | ||
196 | + okHttpClientBuilder.addInterceptor(buildLoggingInterceptor()); | ||
197 | + | ||
198 | + // Set timeout. | ||
199 | + okHttpClientBuilder | ||
200 | + .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) | ||
201 | + .readTimeout(readTimeout, TimeUnit.MILLISECONDS) | ||
202 | + .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS); | ||
203 | + | ||
204 | + final OkHttpClient okHttpClient = okHttpClientBuilder.build(); | ||
205 | + | ||
206 | + if (retrofitBuilder == null) { | ||
207 | + retrofitBuilder = createDefaultRetrofitBuilder(); | ||
208 | + } | ||
209 | + retrofitBuilder.client(okHttpClient); | ||
210 | + retrofitBuilder.baseUrl(apiEndPoint.toString()); | ||
211 | + | ||
212 | + final Retrofit retrofit = retrofitBuilder.build(); | ||
213 | + | ||
214 | + return retrofit.create(retrofitIFace); | ||
215 | + } | ||
216 | + | ||
217 | + static HeaderInterceptor buildAuthenticationInterceptor(ChannelTokenSupplier channelTokenSupplier) { | ||
218 | + requireNonNull(channelTokenSupplier, "channelTokenSupplier"); | ||
219 | + return HeaderInterceptor.forChannelTokenSupplier(channelTokenSupplier); | ||
220 | + } | ||
221 | + | ||
222 | + static Interceptor buildLoggingInterceptor() { | ||
223 | + final Logger slf4jLogger = LoggerFactory.getLogger("com.linecorp.bot.client.wire"); | ||
224 | + | ||
225 | + return new HttpLoggingInterceptor(slf4jLogger::info) | ||
226 | + .setLevel(Level.BODY); | ||
227 | + } | ||
228 | + | ||
229 | + static Retrofit.Builder createDefaultRetrofitBuilder() { | ||
230 | + return new Retrofit.Builder() | ||
231 | + .addConverterFactory(JacksonConverterFactory.create(objectMapper)); | ||
232 | + } | ||
233 | + | ||
234 | + /** | ||
235 | + * Creates a new {@link LineBlobService}. | ||
236 | + */ | ||
237 | + public LineBlobClient build() { | ||
238 | + return new LineBlobClientImpl( | ||
239 | + buildRetrofitIface(apiEndPoint, LineBlobService.class)); | ||
240 | + } | ||
241 | + | ||
242 | + /** | ||
243 | + * Creates a new {@link LineBlobService}. | ||
244 | + */ | ||
245 | + public LineBlobClient buildBlobClient() { | ||
246 | + return new LineBlobClientImpl(buildRetrofitIface( | ||
247 | + apiEndPoint, | ||
248 | + LineBlobService.class)); | ||
249 | + } | ||
250 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineBlobClientImpl.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.util.concurrent.CompletableFuture; | ||
20 | + | ||
21 | +import com.linecorp.bot.client.exception.GeneralLineMessagingException; | ||
22 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
23 | + | ||
24 | +import lombok.AllArgsConstructor; | ||
25 | +import okhttp3.MediaType; | ||
26 | +import okhttp3.RequestBody; | ||
27 | +import okhttp3.ResponseBody; | ||
28 | +import retrofit2.Call; | ||
29 | +import retrofit2.Callback; | ||
30 | +import retrofit2.Response; | ||
31 | + | ||
32 | +@AllArgsConstructor | ||
33 | +class LineBlobClientImpl implements LineBlobClient { | ||
34 | + private final LineBlobService retrofitImpl; | ||
35 | + | ||
36 | + @Override | ||
37 | + public CompletableFuture<MessageContentResponse> getMessageContent(final String messageId) { | ||
38 | + return toMessageContentResponseFuture(retrofitImpl.getMessageContent(messageId)); | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public CompletableFuture<MessageContentResponse> getRichMenuImage(final String richMenuId) { | ||
43 | + return toMessageContentResponseFuture(retrofitImpl.getRichMenuImage(richMenuId)); | ||
44 | + } | ||
45 | + | ||
46 | + @Override | ||
47 | + public CompletableFuture<BotApiResponse> setRichMenuImage( | ||
48 | + final String richMenuId, final String contentType, final byte[] content) { | ||
49 | + final RequestBody requestBody = RequestBody.create(MediaType.parse(contentType), content); | ||
50 | + return LineMessagingClientImpl.toBotApiFuture( | ||
51 | + retrofitImpl.uploadRichMenuImage(richMenuId, requestBody)); | ||
52 | + } | ||
53 | + | ||
54 | + private static CompletableFuture<MessageContentResponse> toMessageContentResponseFuture( | ||
55 | + final Call<ResponseBody> callToWrap) { | ||
56 | + final ResponseBodyCallbackAdaptor future = new ResponseBodyCallbackAdaptor(); | ||
57 | + callToWrap.enqueue(future); | ||
58 | + return future; | ||
59 | + } | ||
60 | + | ||
61 | + static class ResponseBodyCallbackAdaptor | ||
62 | + extends CompletableFuture<MessageContentResponse> | ||
63 | + implements Callback<ResponseBody> { | ||
64 | + | ||
65 | + @Override | ||
66 | + public void onResponse(final Call<ResponseBody> call, final Response<ResponseBody> response) { | ||
67 | + if (!response.isSuccessful()) { | ||
68 | + completeExceptionally(LineMessagingClientImpl.EXCEPTION_CONVERTER.apply(response)); | ||
69 | + return; | ||
70 | + } | ||
71 | + | ||
72 | + try { | ||
73 | + complete(convert(response)); | ||
74 | + } catch (RuntimeException exceptionInConvert) { | ||
75 | + completeExceptionally( | ||
76 | + new GeneralLineMessagingException(exceptionInConvert.getMessage(), | ||
77 | + null, exceptionInConvert)); | ||
78 | + } | ||
79 | + } | ||
80 | + | ||
81 | + @Override | ||
82 | + public void onFailure(final Call<ResponseBody> call, final Throwable t) { | ||
83 | + completeExceptionally( | ||
84 | + new GeneralLineMessagingException(t.getMessage(), null, t)); | ||
85 | + } | ||
86 | + | ||
87 | + private MessageContentResponse convert(final Response<ResponseBody> response) { | ||
88 | + return MessageContentResponse | ||
89 | + .builder() | ||
90 | + .length(response.body().contentLength()) | ||
91 | + .allHeaders(response.headers().toMultimap()) | ||
92 | + .mimeType(response.body().contentType().toString()) | ||
93 | + .stream(response.body().byteStream()) | ||
94 | + .build(); | ||
95 | + } | ||
96 | + } | ||
97 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineBlobService.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import okhttp3.RequestBody; | ||
20 | +import okhttp3.ResponseBody; | ||
21 | +import retrofit2.Call; | ||
22 | +import retrofit2.http.Body; | ||
23 | +import retrofit2.http.GET; | ||
24 | +import retrofit2.http.POST; | ||
25 | +import retrofit2.http.Path; | ||
26 | +import retrofit2.http.Streaming; | ||
27 | + | ||
28 | +interface LineBlobService { | ||
29 | + /** | ||
30 | + * Method for Retrofit. | ||
31 | + * | ||
32 | + * @see LineBlobClient#getMessageContent(String) | ||
33 | + */ | ||
34 | + @Streaming | ||
35 | + @GET("v2/bot/message/{messageId}/content") | ||
36 | + Call<ResponseBody> getMessageContent(@Path("messageId") String messageId); | ||
37 | + | ||
38 | + /** | ||
39 | + * Method for Retrofit. | ||
40 | + * | ||
41 | + * @see LineBlobClient#getRichMenuImage(String) | ||
42 | + */ | ||
43 | + @Streaming | ||
44 | + @GET("v2/bot/richmenu/{richMenuId}/content") | ||
45 | + Call<ResponseBody> getRichMenuImage(@Path("richMenuId") String richMenuId); | ||
46 | + | ||
47 | + /** | ||
48 | + * Method for Retrofit. | ||
49 | + * | ||
50 | + * @see LineBlobClient#setRichMenuImage(String, String, byte[]) | ||
51 | + */ | ||
52 | + @POST("v2/bot/richmenu/{richMenuId}/content") | ||
53 | + Call<Void> uploadRichMenuImage( | ||
54 | + @Path("richMenuId") String richMenuId, | ||
55 | + @Body RequestBody requestBody); | ||
56 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineClientConstants.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.net.URI; | ||
20 | + | ||
21 | +/** | ||
22 | + * Common constant holder. | ||
23 | + */ | ||
24 | +public enum LineClientConstants { | ||
25 | + /* Only public static final fields in this enum. */; | ||
26 | + public static final URI DEFAULT_API_END_POINT = URI.create("https://api.line.me/"); | ||
27 | + public static final URI DEFAULT_BLOB_END_POINT = URI.create("https://api-data.line.me/"); | ||
28 | + public static final long DEFAULT_CONNECT_TIMEOUT_MILLIS = 10_000; | ||
29 | + public static final long DEFAULT_READ_TIMEOUT_MILLIS = 10_000; | ||
30 | + public static final long DEFAULT_WRITE_TIMEOUT_MILLIS = 10_000; | ||
31 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineMessagingClient.java
0 → 100644
This diff is collapsed. Click to expand it.
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Objects.requireNonNull; | ||
20 | + | ||
21 | +import java.net.URI; | ||
22 | +import java.util.ArrayList; | ||
23 | +import java.util.List; | ||
24 | +import java.util.concurrent.TimeUnit; | ||
25 | + | ||
26 | +import org.slf4j.Logger; | ||
27 | +import org.slf4j.LoggerFactory; | ||
28 | + | ||
29 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
30 | + | ||
31 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
32 | + | ||
33 | +import lombok.NonNull; | ||
34 | +import lombok.Setter; | ||
35 | +import lombok.ToString; | ||
36 | +import lombok.experimental.Accessors; | ||
37 | +import lombok.experimental.PackagePrivate; | ||
38 | +import okhttp3.Interceptor; | ||
39 | +import okhttp3.OkHttpClient; | ||
40 | +import okhttp3.logging.HttpLoggingInterceptor; | ||
41 | +import okhttp3.logging.HttpLoggingInterceptor.Level; | ||
42 | +import retrofit2.Retrofit; | ||
43 | +import retrofit2.converter.jackson.JacksonConverterFactory; | ||
44 | + | ||
45 | +@ToString | ||
46 | +@Accessors(fluent = true) | ||
47 | +public class LineMessagingClientBuilder { | ||
48 | + private static final ObjectMapper objectMapper = ModelObjectMapper.createNewObjectMapper(); | ||
49 | + | ||
50 | + /** | ||
51 | + * Use {@link LineMessagingClient#builder(String)} to create instance. | ||
52 | + * | ||
53 | + * @see LineMessagingClient#builder(String) | ||
54 | + * @see LineMessagingClient#builder(ChannelTokenSupplier) | ||
55 | + */ | ||
56 | + @PackagePrivate | ||
57 | + LineMessagingClientBuilder() { | ||
58 | + } | ||
59 | + | ||
60 | + /** | ||
61 | + * API Endpoint. | ||
62 | + * | ||
63 | + * <p>Default value = "https://api.line.me/". | ||
64 | + */ | ||
65 | + private URI apiEndPoint = LineClientConstants.DEFAULT_API_END_POINT; | ||
66 | + | ||
67 | + /** | ||
68 | + * API Endpoint. | ||
69 | + * | ||
70 | + * @deprecated use {@link #apiEndPoint(URI apiEndPoint)}. | ||
71 | + */ | ||
72 | + @Deprecated | ||
73 | + public LineMessagingClientBuilder apiEndPoint(String apiEndPoint) { | ||
74 | + return apiEndPoint(URI.create(apiEndPoint)); | ||
75 | + } | ||
76 | + | ||
77 | + /** | ||
78 | + * API Endpoint. | ||
79 | + * | ||
80 | + * <p>Default value = "https://api.line.me/". | ||
81 | + */ // We can remove this after delete `setApiEndPoint(String apiEndPoint)`. | ||
82 | + public LineMessagingClientBuilder apiEndPoint(URI apiEndPoint) { | ||
83 | + this.apiEndPoint = requireNonNull(apiEndPoint, "apiEndPoint"); | ||
84 | + return this; | ||
85 | + } | ||
86 | + | ||
87 | + /** | ||
88 | + * Blob Endpoint. | ||
89 | + * | ||
90 | + * <p>Default value = "https://api-data.line.me/". | ||
91 | + */ | ||
92 | + @Setter | ||
93 | + private URI blobEndPoint = LineClientConstants.DEFAULT_BLOB_END_POINT; | ||
94 | + | ||
95 | + /** | ||
96 | + * Connection timeout. | ||
97 | + * | ||
98 | + * <p>Default value = {@value LineClientConstants#DEFAULT_CONNECT_TIMEOUT_MILLIS}ms. | ||
99 | + */ | ||
100 | + @Setter | ||
101 | + private long connectTimeout = LineClientConstants.DEFAULT_CONNECT_TIMEOUT_MILLIS; | ||
102 | + | ||
103 | + /** | ||
104 | + * Connection timeout. | ||
105 | + * | ||
106 | + * <p>Default value = {@value LineClientConstants#DEFAULT_READ_TIMEOUT_MILLIS}ms. | ||
107 | + */ | ||
108 | + @Setter | ||
109 | + private long readTimeout = LineClientConstants.DEFAULT_READ_TIMEOUT_MILLIS; | ||
110 | + | ||
111 | + /** | ||
112 | + * Write timeout. | ||
113 | + * | ||
114 | + * <p>Default value = {@value LineClientConstants#DEFAULT_WRITE_TIMEOUT_MILLIS}ms. | ||
115 | + */ | ||
116 | + @Setter | ||
117 | + private long writeTimeout = LineClientConstants.DEFAULT_WRITE_TIMEOUT_MILLIS; | ||
118 | + | ||
119 | + /** | ||
120 | + * Channel token supplier of this client. | ||
121 | + * | ||
122 | + * <p>MUST BE NULL except you configured your own | ||
123 | + */ | ||
124 | + @Setter | ||
125 | + private ChannelTokenSupplier channelTokenSupplier; | ||
126 | + | ||
127 | + /** | ||
128 | + * Custom {@link Retrofit.Builder} used internally. | ||
129 | + * | ||
130 | + * <p>If you want to use your own setting, specify {@link Retrofit.Builder} instance. | ||
131 | + * Default builder is used in case of {@code null} (default). | ||
132 | + * | ||
133 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
134 | + * | ||
135 | + * @see #createDefaultRetrofitBuilder() | ||
136 | + */ | ||
137 | + @Setter | ||
138 | + private Retrofit.Builder retrofitBuilder; | ||
139 | + | ||
140 | + /** | ||
141 | + * Add authentication header. | ||
142 | + * | ||
143 | + * <p>Default = {@value}. If you manage authentication header yourself, set to {@doe false}. | ||
144 | + */ | ||
145 | + @Setter | ||
146 | + private boolean addAuthenticationHeader = true; | ||
147 | + | ||
148 | + private OkHttpClient.Builder okHttpClientBuilder; | ||
149 | + | ||
150 | + /** | ||
151 | + * Custom interceptors. | ||
152 | + * | ||
153 | + * <p>You can add your own interceptors. | ||
154 | + * | ||
155 | + * <p>Note: Authentication interceptor is automatically added by default. | ||
156 | + * | ||
157 | + * @see #addAuthenticationHeader(boolean) | ||
158 | + */ | ||
159 | + @Setter | ||
160 | + private List<Interceptor> additionalInterceptors = new ArrayList<>(); | ||
161 | + | ||
162 | + /** | ||
163 | + * Set fixed channel token. This overwrites {@link #channelTokenSupplier(ChannelTokenSupplier)}. | ||
164 | + * | ||
165 | + * @see #channelTokenSupplier(ChannelTokenSupplier) | ||
166 | + */ | ||
167 | + public LineMessagingClientBuilder channelToken(String channelToken) { | ||
168 | + channelTokenSupplier(FixedChannelTokenSupplier.of(channelToken)); | ||
169 | + return this; | ||
170 | + } | ||
171 | + | ||
172 | + /** | ||
173 | + * Set customized OkHttpClient.Builder. | ||
174 | + * | ||
175 | + * <p>In case of you need your own customized {@link OkHttpClient}, | ||
176 | + * this builder allows specify {@link OkHttpClient.Builder} instance. | ||
177 | + * | ||
178 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
179 | + * | ||
180 | + * @param addAuthenticationHeader If true, all default okhttp interceptors ignored. | ||
181 | + * You should insert authentication headers yourself. | ||
182 | + */ | ||
183 | + public LineMessagingClientBuilder okHttpClientBuilder( | ||
184 | + final @NonNull OkHttpClient.Builder okHttpClientBuilder, | ||
185 | + final boolean addAuthenticationHeader) { | ||
186 | + this.okHttpClientBuilder = okHttpClientBuilder; | ||
187 | + this.addAuthenticationHeader = addAuthenticationHeader; | ||
188 | + | ||
189 | + return this; | ||
190 | + } | ||
191 | + | ||
192 | + /** | ||
193 | + * Creates a new {@link LineMessagingService}. | ||
194 | + */ | ||
195 | + <T> T buildRetrofitIface(URI apiEndPoint, Class<T> retrofitIFace) { | ||
196 | + if (okHttpClientBuilder == null) { | ||
197 | + okHttpClientBuilder = new OkHttpClient.Builder(); | ||
198 | + } | ||
199 | + | ||
200 | + // Add interceptors. | ||
201 | + if (addAuthenticationHeader) { | ||
202 | + okHttpClientBuilder.addInterceptor(buildAuthenticationInterceptor(channelTokenSupplier)); | ||
203 | + } | ||
204 | + if (additionalInterceptors != null) { | ||
205 | + additionalInterceptors.forEach(okHttpClientBuilder::addInterceptor); | ||
206 | + } | ||
207 | + okHttpClientBuilder.addInterceptor(buildLoggingInterceptor()); | ||
208 | + | ||
209 | + // Set timeout. | ||
210 | + okHttpClientBuilder | ||
211 | + .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) | ||
212 | + .readTimeout(readTimeout, TimeUnit.MILLISECONDS) | ||
213 | + .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS); | ||
214 | + | ||
215 | + final OkHttpClient okHttpClient = okHttpClientBuilder.build(); | ||
216 | + | ||
217 | + if (retrofitBuilder == null) { | ||
218 | + retrofitBuilder = createDefaultRetrofitBuilder(); | ||
219 | + } | ||
220 | + retrofitBuilder.client(okHttpClient); | ||
221 | + retrofitBuilder.baseUrl(apiEndPoint.toString()); | ||
222 | + | ||
223 | + final Retrofit retrofit = retrofitBuilder.build(); | ||
224 | + | ||
225 | + return retrofit.create(retrofitIFace); | ||
226 | + } | ||
227 | + | ||
228 | + static HeaderInterceptor buildAuthenticationInterceptor(ChannelTokenSupplier channelTokenSupplier) { | ||
229 | + requireNonNull(channelTokenSupplier, "channelTokenSupplier"); | ||
230 | + return HeaderInterceptor.forChannelTokenSupplier(channelTokenSupplier); | ||
231 | + } | ||
232 | + | ||
233 | + static Interceptor buildLoggingInterceptor() { | ||
234 | + final Logger slf4jLogger = LoggerFactory.getLogger("com.linecorp.bot.client.wire"); | ||
235 | + | ||
236 | + return new HttpLoggingInterceptor(slf4jLogger::info) | ||
237 | + .setLevel(Level.BODY); | ||
238 | + } | ||
239 | + | ||
240 | + static Retrofit.Builder createDefaultRetrofitBuilder() { | ||
241 | + return new Retrofit.Builder() | ||
242 | + .addConverterFactory(JacksonConverterFactory.create(objectMapper)); | ||
243 | + } | ||
244 | + | ||
245 | + /** | ||
246 | + * Creates a new {@link LineMessagingService}. | ||
247 | + */ | ||
248 | + public LineMessagingClient build() { | ||
249 | + return new LineMessagingClientImpl( | ||
250 | + buildRetrofitIface(apiEndPoint, LineMessagingService.class), | ||
251 | + buildBlobClient()); | ||
252 | + } | ||
253 | + | ||
254 | + /** | ||
255 | + * Creates a new {@link LineMessagingService}. | ||
256 | + */ | ||
257 | + private LineBlobClient buildBlobClient() { | ||
258 | + return new LineBlobClientImpl(buildRetrofitIface( | ||
259 | + blobEndPoint, | ||
260 | + LineBlobService.class)); | ||
261 | + } | ||
262 | +} |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineOAuthClient.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.util.concurrent.CompletableFuture; | ||
20 | + | ||
21 | +import com.linecorp.bot.model.oauth.ChannelAccessTokenException; | ||
22 | +import com.linecorp.bot.model.oauth.IssueChannelAccessTokenRequest; | ||
23 | +import com.linecorp.bot.model.oauth.IssueChannelAccessTokenResponse; | ||
24 | + | ||
25 | +/** | ||
26 | + * An OAuth client that issues or revokes channel access tokens. See | ||
27 | + * <a href="https://developers.line.biz/en/reference/messaging-api/#issue-channel-access-token">document</a> | ||
28 | + * for detail. | ||
29 | + */ | ||
30 | +public interface LineOAuthClient { | ||
31 | + /** | ||
32 | + * Creates a {@link LineOAuthClientBuilder}. | ||
33 | + */ | ||
34 | + static LineOAuthClientBuilder builder() { | ||
35 | + return new LineOAuthClientBuilder(); | ||
36 | + } | ||
37 | + | ||
38 | + /** | ||
39 | + * Issues a channel access token. This method lets you use JWT assertion for authentication. | ||
40 | + * | ||
41 | + * <p>You can issue up to 30 tokens. | ||
42 | + * If you reach the maximum limit, additional requests of issuing channel access tokens are blocked. | ||
43 | + * | ||
44 | + * @param clientAssertion A JSON Web Token the client needs to create and sign with the private key created | ||
45 | + * when issuing an assertion signing key. | ||
46 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#issue-channel-access-token-v2-1">Issue channel access token v2.1</a> | ||
47 | + */ | ||
48 | + CompletableFuture<IssueChannelAccessTokenResponse> issueChannelTokenByJWT( | ||
49 | + String clientAssertion); | ||
50 | + | ||
51 | + /** | ||
52 | + * Revokes a channel access token. | ||
53 | + * | ||
54 | + * @param clientId Channel ID | ||
55 | + * @param clientSecret Channel Secret | ||
56 | + * @param accessToken Channel access token | ||
57 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#revoke-channel-access-token-v2-1">Revoke channel access token v2.1</a> | ||
58 | + */ | ||
59 | + CompletableFuture<Void> revokeChannelTokenByJWT( | ||
60 | + String clientId, | ||
61 | + String clientSecret, | ||
62 | + String accessToken); | ||
63 | + | ||
64 | + /** | ||
65 | + * Issues a short-lived channel access token. Up to 30 tokens can be issued. If the maximum is exceeded, | ||
66 | + * existing channel access tokens are revoked in the order of when they were first issued. | ||
67 | + * It will return a failed {@link CompletableFuture} with {@link ChannelAccessTokenException} if | ||
68 | + * it has an error during calling the API. | ||
69 | + */ | ||
70 | + CompletableFuture<IssueChannelAccessTokenResponse> issueChannelToken(IssueChannelAccessTokenRequest req); | ||
71 | + | ||
72 | + /** | ||
73 | + * Revokes a channel access token. It will return a failed {@link CompletableFuture} with | ||
74 | + * {@link ChannelAccessTokenException} if it has an error during calling the API. | ||
75 | + */ | ||
76 | + CompletableFuture<Void> revokeChannelToken(String accessToken); | ||
77 | +} |
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Objects.requireNonNull; | ||
20 | + | ||
21 | +import java.net.URI; | ||
22 | +import java.util.ArrayList; | ||
23 | +import java.util.List; | ||
24 | +import java.util.concurrent.TimeUnit; | ||
25 | + | ||
26 | +import org.slf4j.Logger; | ||
27 | +import org.slf4j.LoggerFactory; | ||
28 | + | ||
29 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
30 | + | ||
31 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
32 | + | ||
33 | +import lombok.NonNull; | ||
34 | +import lombok.Setter; | ||
35 | +import lombok.ToString; | ||
36 | +import lombok.experimental.Accessors; | ||
37 | +import lombok.experimental.PackagePrivate; | ||
38 | +import okhttp3.Interceptor; | ||
39 | +import okhttp3.OkHttpClient; | ||
40 | +import okhttp3.logging.HttpLoggingInterceptor; | ||
41 | +import okhttp3.logging.HttpLoggingInterceptor.Level; | ||
42 | +import retrofit2.Retrofit; | ||
43 | +import retrofit2.converter.jackson.JacksonConverterFactory; | ||
44 | + | ||
45 | +@ToString | ||
46 | +@Accessors(fluent = true) | ||
47 | +public class LineOAuthClientBuilder { | ||
48 | + /** | ||
49 | + * Creates a {@link LineOAuthClient}. Use {@link LineOAuthClient#builder()} instead. | ||
50 | + */ | ||
51 | + @PackagePrivate | ||
52 | + LineOAuthClientBuilder() { | ||
53 | + } | ||
54 | + | ||
55 | + /** | ||
56 | + * API Endpoint. | ||
57 | + * | ||
58 | + * <p>Default value = "https://api.line.me/". | ||
59 | + */ | ||
60 | + private URI apiEndPoint = LineClientConstants.DEFAULT_API_END_POINT; | ||
61 | + | ||
62 | + /** | ||
63 | + * API Endpoint. | ||
64 | + * | ||
65 | + * @deprecated use {@link #apiEndPoint(URI apiEndPoint)}. | ||
66 | + */ | ||
67 | + @Deprecated | ||
68 | + public LineOAuthClientBuilder apiEndPoint(String apiEndPoint) { | ||
69 | + return apiEndPoint(URI.create(apiEndPoint)); | ||
70 | + } | ||
71 | + | ||
72 | + /** | ||
73 | + * API Endpoint. | ||
74 | + * | ||
75 | + * <p>Default value = "https://api.line.me/". | ||
76 | + */ | ||
77 | + public LineOAuthClientBuilder apiEndPoint(URI apiEndPoint) { | ||
78 | + this.apiEndPoint = requireNonNull(apiEndPoint, "apiEndPoint"); | ||
79 | + return this; | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Connection timeout. | ||
84 | + * | ||
85 | + * <p>Default value = {@value LineClientConstants#DEFAULT_CONNECT_TIMEOUT_MILLIS}ms. | ||
86 | + */ | ||
87 | + @Setter | ||
88 | + private long connectTimeout = LineClientConstants.DEFAULT_CONNECT_TIMEOUT_MILLIS; | ||
89 | + | ||
90 | + /** | ||
91 | + * Connection timeout. | ||
92 | + * | ||
93 | + * <p>Default value = {@value LineClientConstants#DEFAULT_READ_TIMEOUT_MILLIS}ms. | ||
94 | + */ | ||
95 | + @Setter | ||
96 | + private long readTimeout = LineClientConstants.DEFAULT_READ_TIMEOUT_MILLIS; | ||
97 | + | ||
98 | + /** | ||
99 | + * Write timeout. | ||
100 | + * | ||
101 | + * <p>Default value = {@value LineClientConstants#DEFAULT_WRITE_TIMEOUT_MILLIS}ms. | ||
102 | + */ | ||
103 | + @Setter | ||
104 | + private long writeTimeout = LineClientConstants.DEFAULT_WRITE_TIMEOUT_MILLIS; | ||
105 | + | ||
106 | + /** | ||
107 | + * Custom {@link Retrofit.Builder} used internally. | ||
108 | + * | ||
109 | + * <p>If you want to use your own setting, specify {@link Retrofit.Builder} instance. | ||
110 | + * Default builder is used in case of {@code null} (default). | ||
111 | + * | ||
112 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
113 | + * | ||
114 | + * @see #createDefaultRetrofitBuilder() | ||
115 | + */ | ||
116 | + @Setter | ||
117 | + private Retrofit.Builder retrofitBuilder; | ||
118 | + | ||
119 | + private OkHttpClient.Builder okHttpClientBuilder; | ||
120 | + | ||
121 | + /** | ||
122 | + * Custom interceptors. | ||
123 | + * | ||
124 | + * <p>You can add your own interceptors. | ||
125 | + */ | ||
126 | + @Setter | ||
127 | + private List<Interceptor> additionalInterceptors = new ArrayList<>(); | ||
128 | + | ||
129 | + /** | ||
130 | + * Set customized {@link OkHttpClient.Builder}. | ||
131 | + * | ||
132 | + * <p>In case of you need your own customized {@link OkHttpClient}, | ||
133 | + * this builder allows specify {@link OkHttpClient.Builder} instance. | ||
134 | + */ | ||
135 | + public LineOAuthClientBuilder okHttpClientBuilder(@NonNull OkHttpClient.Builder okHttpClientBuilder) { | ||
136 | + this.okHttpClientBuilder = okHttpClientBuilder; | ||
137 | + return this; | ||
138 | + } | ||
139 | + | ||
140 | + /** | ||
141 | + * Creates a new {@link LineOAuthService}. | ||
142 | + */ | ||
143 | + private LineOAuthService buildRetrofit() { | ||
144 | + if (okHttpClientBuilder == null) { | ||
145 | + okHttpClientBuilder = new OkHttpClient.Builder(); | ||
146 | + } | ||
147 | + | ||
148 | + if (additionalInterceptors != null) { | ||
149 | + additionalInterceptors.forEach(okHttpClientBuilder::addInterceptor); | ||
150 | + } | ||
151 | + okHttpClientBuilder.addInterceptor(buildLoggingInterceptor()); | ||
152 | + | ||
153 | + // Set timeout. | ||
154 | + okHttpClientBuilder | ||
155 | + .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) | ||
156 | + .readTimeout(readTimeout, TimeUnit.MILLISECONDS) | ||
157 | + .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS); | ||
158 | + | ||
159 | + final OkHttpClient okHttpClient = okHttpClientBuilder.build(); | ||
160 | + | ||
161 | + if (retrofitBuilder == null) { | ||
162 | + retrofitBuilder = createDefaultRetrofitBuilder(); | ||
163 | + } | ||
164 | + retrofitBuilder.client(okHttpClient); | ||
165 | + retrofitBuilder.baseUrl(apiEndPoint.toString()); | ||
166 | + | ||
167 | + final Retrofit retrofit = retrofitBuilder.build(); | ||
168 | + | ||
169 | + return retrofit.create(LineOAuthService.class); | ||
170 | + } | ||
171 | + | ||
172 | + private static Interceptor buildLoggingInterceptor() { | ||
173 | + final Logger slf4jLogger = LoggerFactory.getLogger("com.linecorp.bot.client.wire"); | ||
174 | + | ||
175 | + return new HttpLoggingInterceptor(slf4jLogger::info) | ||
176 | + .setLevel(Level.BODY); | ||
177 | + } | ||
178 | + | ||
179 | + private static Retrofit.Builder createDefaultRetrofitBuilder() { | ||
180 | + final ObjectMapper objectMapper = ModelObjectMapper.createNewObjectMapper(); | ||
181 | + | ||
182 | + return new Retrofit.Builder() | ||
183 | + .addConverterFactory(JacksonConverterFactory.create(objectMapper)); | ||
184 | + } | ||
185 | + | ||
186 | + /** | ||
187 | + * Creates a new {@link LineOAuthClient}. | ||
188 | + */ | ||
189 | + public LineOAuthClient build() { | ||
190 | + return new LineOAuthClientImpl(buildRetrofit()); | ||
191 | + } | ||
192 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineOAuthClientImpl.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.util.concurrent.CompletableFuture; | ||
21 | + | ||
22 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
23 | + | ||
24 | +import com.linecorp.bot.model.oauth.ChannelAccessTokenException; | ||
25 | +import com.linecorp.bot.model.oauth.IssueChannelAccessTokenRequest; | ||
26 | +import com.linecorp.bot.model.oauth.IssueChannelAccessTokenResponse; | ||
27 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
28 | + | ||
29 | +import lombok.AllArgsConstructor; | ||
30 | +import lombok.experimental.PackagePrivate; | ||
31 | +import retrofit2.Call; | ||
32 | +import retrofit2.Callback; | ||
33 | +import retrofit2.Response; | ||
34 | + | ||
35 | +/** | ||
36 | + * An implementation of {@link LineOAuthClient} that issues or revokes channel access tokens. | ||
37 | + */ | ||
38 | +@AllArgsConstructor | ||
39 | +@PackagePrivate | ||
40 | +class LineOAuthClientImpl implements LineOAuthClient { | ||
41 | + private static final ObjectMapper objectMapper = ModelObjectMapper.createNewObjectMapper(); | ||
42 | + | ||
43 | + private final LineOAuthService service; | ||
44 | + | ||
45 | + @Override | ||
46 | + public CompletableFuture<IssueChannelAccessTokenResponse> issueChannelTokenByJWT(final String jwt) { | ||
47 | + return toFuture(service.issueChannelTokenByJWT( | ||
48 | + "client_credentials", | ||
49 | + "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", | ||
50 | + jwt)); | ||
51 | + } | ||
52 | + | ||
53 | + @Override | ||
54 | + public CompletableFuture<Void> revokeChannelTokenByJWT( | ||
55 | + String clientId, String clientSecret, String accessToken) { | ||
56 | + return toFuture(service.revokeChannelTokenByJWT(clientId, clientSecret, accessToken)); | ||
57 | + } | ||
58 | + | ||
59 | + @Override | ||
60 | + public CompletableFuture<IssueChannelAccessTokenResponse> issueChannelToken( | ||
61 | + IssueChannelAccessTokenRequest req) { | ||
62 | + return toFuture(service.issueChannelToken(req.getGrantType(), | ||
63 | + req.getClientId(), | ||
64 | + req.getClientSecret())); | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + public CompletableFuture<Void> revokeChannelToken(String accessToken) { | ||
69 | + return toFuture(service.revokeChannelToken(accessToken)); | ||
70 | + } | ||
71 | + | ||
72 | + private static <T> CompletableFuture<T> toFuture(Call<T> call) { | ||
73 | + final CallbackCompletableFuture<T> future = new CallbackCompletableFuture<>(); | ||
74 | + call.enqueue(future); | ||
75 | + return future; | ||
76 | + } | ||
77 | + | ||
78 | + static class CallbackCompletableFuture<T> extends CompletableFuture<T> implements Callback<T> { | ||
79 | + @Override | ||
80 | + public void onResponse(final Call<T> call, final Response<T> response) { | ||
81 | + if (response.isSuccessful()) { | ||
82 | + complete(response.body()); | ||
83 | + return; | ||
84 | + } | ||
85 | + if (response.code() == 400) { | ||
86 | + try { | ||
87 | + completeExceptionally(objectMapper.readValue(response.errorBody().string(), | ||
88 | + ChannelAccessTokenException.class)); | ||
89 | + return; | ||
90 | + } catch (IOException e) { | ||
91 | + completeExceptionally(e); | ||
92 | + } | ||
93 | + } | ||
94 | + completeExceptionally(new ChannelAccessTokenException(response.message())); | ||
95 | + } | ||
96 | + | ||
97 | + @Override | ||
98 | + public void onFailure(final Call<T> call, final Throwable t) { | ||
99 | + completeExceptionally(new ChannelAccessTokenException(t.getMessage(), t)); | ||
100 | + } | ||
101 | + } | ||
102 | +} |
line-bot-sdk-java/line-bot-api-client/src/main/java/com/linecorp/bot/client/LineOAuthService.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.util.concurrent.CompletableFuture; | ||
20 | + | ||
21 | +import com.linecorp.bot.model.oauth.ChannelAccessTokenException; | ||
22 | +import com.linecorp.bot.model.oauth.IssueChannelAccessTokenResponse; | ||
23 | + | ||
24 | +import lombok.experimental.PackagePrivate; | ||
25 | +import retrofit2.Call; | ||
26 | +import retrofit2.http.Field; | ||
27 | +import retrofit2.http.FormUrlEncoded; | ||
28 | +import retrofit2.http.POST; | ||
29 | + | ||
30 | +/** | ||
31 | + * An OAuth client that issues or revokes channel access tokens. See {@link LineOAuthClient} and | ||
32 | + * <a href="https://developers.line.biz/en/reference/messaging-api/#issue-channel-access-token">document</a> | ||
33 | + * for detail. | ||
34 | + */ | ||
35 | +@PackagePrivate | ||
36 | +interface LineOAuthService { | ||
37 | + @POST("oauth2/v2.1/token") | ||
38 | + @FormUrlEncoded | ||
39 | + Call<IssueChannelAccessTokenResponse> issueChannelTokenByJWT( | ||
40 | + @Field("grant_type") String grantType, | ||
41 | + @Field("client_assertion_type") String clientAssertionType, | ||
42 | + @Field("client_assertion") String clientAssertion); | ||
43 | + | ||
44 | + @POST("/oauth2/v2.1/revoke") | ||
45 | + @FormUrlEncoded | ||
46 | + Call<Void> revokeChannelTokenByJWT( | ||
47 | + @Field("client_id") String clientId, | ||
48 | + @Field("client_secret") String clientSecret, | ||
49 | + @Field("access_token") String accessToken); | ||
50 | + | ||
51 | + /** | ||
52 | + * Issues a short-lived channel access token. Up to 30 tokens can be issued. If the maximum is exceeded, | ||
53 | + * existing channel access tokens are revoked in the order of when they were first issued. | ||
54 | + * It will return a failed {@link CompletableFuture} with {@link ChannelAccessTokenException} if | ||
55 | + * it has an error during calling the API. | ||
56 | + */ | ||
57 | + @FormUrlEncoded | ||
58 | + @POST("v2/oauth/accessToken") | ||
59 | + Call<IssueChannelAccessTokenResponse> issueChannelToken(@Field("grant_type") String grantType, | ||
60 | + @Field("client_id") String clientId, | ||
61 | + @Field("client_secret") String clientSecret); | ||
62 | + | ||
63 | + /** | ||
64 | + * Revokes a channel access token. It will return a failed {@link CompletableFuture} with | ||
65 | + * {@link ChannelAccessTokenException} if it has an error during calling the API. | ||
66 | + */ | ||
67 | + @FormUrlEncoded | ||
68 | + @POST("v2/oauth/revoke") | ||
69 | + Call<Void> revokeChannelToken(@Field("access_token") String accessToken); | ||
70 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | +package com.linecorp.bot.client; | ||
17 | + | ||
18 | +import java.util.concurrent.CompletableFuture; | ||
19 | + | ||
20 | +import com.linecorp.bot.model.manageaudience.AudienceGroupCreateRoute; | ||
21 | +import com.linecorp.bot.model.manageaudience.AudienceGroupStatus; | ||
22 | +import com.linecorp.bot.model.manageaudience.request.AddAudienceToAudienceGroupRequest; | ||
23 | +import com.linecorp.bot.model.manageaudience.request.CreateAudienceGroupRequest; | ||
24 | +import com.linecorp.bot.model.manageaudience.request.CreateClickBasedAudienceGroupRequest; | ||
25 | +import com.linecorp.bot.model.manageaudience.request.CreateImpBasedAudienceGroupRequest; | ||
26 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupAuthorityLevelRequest; | ||
27 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupDescriptionRequest; | ||
28 | +import com.linecorp.bot.model.manageaudience.response.CreateAudienceGroupResponse; | ||
29 | +import com.linecorp.bot.model.manageaudience.response.CreateClickBasedAudienceGroupResponse; | ||
30 | +import com.linecorp.bot.model.manageaudience.response.CreateImpBasedAudienceGroupResponse; | ||
31 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceDataResponse; | ||
32 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupAuthorityLevelResponse; | ||
33 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupsResponse; | ||
34 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
35 | + | ||
36 | +import retrofit2.http.Body; | ||
37 | + | ||
38 | +public interface ManageAudienceClient { | ||
39 | + | ||
40 | + /** | ||
41 | + * Creates an audience for uploading user IDs. You can create up to 1,000 audiences. | ||
42 | + * | ||
43 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#create-upload-audience-group"> | ||
44 | + * Create audience for uploading user IDs</a> | ||
45 | + */ | ||
46 | + CompletableFuture<CreateAudienceGroupResponse> createAudienceGroup(CreateAudienceGroupRequest request); | ||
47 | + | ||
48 | + /** | ||
49 | + * Adds new user IDs or IFAs to an audience for uploading user IDs. | ||
50 | + * | ||
51 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#update-upload-audience-group"> | ||
52 | + * Add user IDs or Identifiers for Advertisers (IFAs) to an audience for uploading user IDs</a> | ||
53 | + */ | ||
54 | + CompletableFuture<BotApiResponse> addAudienceToAudienceGroup( | ||
55 | + AddAudienceToAudienceGroupRequest request); | ||
56 | + | ||
57 | + /** | ||
58 | + * Creates an audience for click-based retargeting. | ||
59 | + * | ||
60 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#create-click-audience-group"> | ||
61 | + * Create audience for click-based retargeting</a> | ||
62 | + */ | ||
63 | + CompletableFuture<CreateClickBasedAudienceGroupResponse> createClickBasedAudienceGroup( | ||
64 | + CreateClickBasedAudienceGroupRequest request); | ||
65 | + | ||
66 | + /** | ||
67 | + * Creates an audience for impression-based retargeting. | ||
68 | + * | ||
69 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#create-imp-audience-group"> | ||
70 | + * Create audience for impression-based retargeting</a> | ||
71 | + */ | ||
72 | + CompletableFuture<CreateImpBasedAudienceGroupResponse> createImpBasedAudienceGroup( | ||
73 | + CreateImpBasedAudienceGroupRequest request); | ||
74 | + | ||
75 | + /** | ||
76 | + * Renames an existing audience. | ||
77 | + * | ||
78 | + * @param audienceGroupId The audience ID. | ||
79 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#set-description-audience-group"> | ||
80 | + * Rename an audience</a> | ||
81 | + */ | ||
82 | + CompletableFuture<BotApiResponse> updateAudienceGroupDescription( | ||
83 | + long audienceGroupId, UpdateAudienceGroupDescriptionRequest request); | ||
84 | + | ||
85 | + /** | ||
86 | + * Deletes an audience. | ||
87 | + * | ||
88 | + * @param audienceGroupId The audience ID. | ||
89 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#delete-audience-group"> | ||
90 | + * Delete audience</a> | ||
91 | + */ | ||
92 | + CompletableFuture<BotApiResponse> deleteAudienceGroup(long audienceGroupId); | ||
93 | + | ||
94 | + /** | ||
95 | + * Gets audience data. | ||
96 | + * | ||
97 | + * @param audienceGroupId The audience ID. | ||
98 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-audience-group"> | ||
99 | + * Get audience data</a> | ||
100 | + */ | ||
101 | + CompletableFuture<GetAudienceDataResponse> getAudienceData(long audienceGroupId); | ||
102 | + | ||
103 | + /** | ||
104 | + * Gets data for more than one audience. | ||
105 | + * | ||
106 | + * @param page The page to return when getting (paginated) results. Specify a value of 1 or more. | ||
107 | + * @param description The name of the audience(s) to return. You can search for partial matches. | ||
108 | + * Comparisons are case-insensitive, so the names AUDIENCE and audience are considered | ||
109 | + * identical. | ||
110 | + * @param status The audience's status. | ||
111 | + * @param size The number of audiences per page. This is 20 by default. | ||
112 | + * Max: 40 | ||
113 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-audience-groups"> | ||
114 | + * Get data for multiple audiences</a> | ||
115 | + */ | ||
116 | + CompletableFuture<GetAudienceGroupsResponse> getAudienceGroups( | ||
117 | + long page, String description, AudienceGroupStatus status, Long size, | ||
118 | + Boolean includesExternalPublicGroups, AudienceGroupCreateRoute createRoute); | ||
119 | + | ||
120 | + /** | ||
121 | + * Get audience group authority level. | ||
122 | + * | ||
123 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-authority-level"> | ||
124 | + * Get authority level</a> | ||
125 | + */ | ||
126 | + CompletableFuture<GetAudienceGroupAuthorityLevelResponse> getAudienceGroupAuthorityLevel(); | ||
127 | + | ||
128 | + /** | ||
129 | + * Update audience group authority level. | ||
130 | + * | ||
131 | + * @see <a href="https://developers.line.biz/en/reference/messaging-api/#change-authority-level"> | ||
132 | + * Change authority level</a> | ||
133 | + */ | ||
134 | + CompletableFuture<BotApiResponse> updateAudienceGroupAuthorityLevel( | ||
135 | + @Body UpdateAudienceGroupAuthorityLevelRequest request); | ||
136 | + | ||
137 | + static ManageAudienceClientBuilder builder() { | ||
138 | + return new ManageAudienceClientBuilder(); | ||
139 | + } | ||
140 | +} |
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Objects.requireNonNull; | ||
20 | + | ||
21 | +import java.net.URI; | ||
22 | +import java.util.ArrayList; | ||
23 | +import java.util.List; | ||
24 | +import java.util.concurrent.TimeUnit; | ||
25 | + | ||
26 | +import org.slf4j.Logger; | ||
27 | +import org.slf4j.LoggerFactory; | ||
28 | + | ||
29 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
30 | + | ||
31 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
32 | + | ||
33 | +import lombok.NonNull; | ||
34 | +import lombok.Setter; | ||
35 | +import lombok.ToString; | ||
36 | +import lombok.experimental.Accessors; | ||
37 | +import lombok.experimental.PackagePrivate; | ||
38 | +import okhttp3.Interceptor; | ||
39 | +import okhttp3.OkHttpClient; | ||
40 | +import okhttp3.logging.HttpLoggingInterceptor; | ||
41 | +import okhttp3.logging.HttpLoggingInterceptor.Level; | ||
42 | +import retrofit2.Retrofit; | ||
43 | +import retrofit2.converter.jackson.JacksonConverterFactory; | ||
44 | + | ||
45 | +@ToString | ||
46 | +@Accessors(fluent = true) | ||
47 | +public class ManageAudienceClientBuilder { | ||
48 | + private static final ObjectMapper objectMapper = ModelObjectMapper.createNewObjectMapper(); | ||
49 | + | ||
50 | + /** | ||
51 | + * Use {@link ManageAudienceClient#builder()} to create instance. | ||
52 | + */ | ||
53 | + @PackagePrivate | ||
54 | + ManageAudienceClientBuilder() { | ||
55 | + } | ||
56 | + | ||
57 | + /** | ||
58 | + * API Endpoint. | ||
59 | + * | ||
60 | + * <p>Default value = "https://api.line.me/". | ||
61 | + */ | ||
62 | + private URI apiEndPoint = LineClientConstants.DEFAULT_API_END_POINT; | ||
63 | + | ||
64 | + /** | ||
65 | + * API Endpoint. | ||
66 | + * | ||
67 | + * @deprecated use {@link #apiEndPoint(URI apiEndPoint)}. | ||
68 | + */ | ||
69 | + @Deprecated | ||
70 | + public ManageAudienceClientBuilder apiEndPoint(String apiEndPoint) { | ||
71 | + return apiEndPoint(URI.create(apiEndPoint)); | ||
72 | + } | ||
73 | + | ||
74 | + /** | ||
75 | + * API Endpoint. | ||
76 | + * | ||
77 | + * <p>Default value = "https://api.line.me/". | ||
78 | + */ // We can remove this after delete `setApiEndPoint(String apiEndPoint)`. | ||
79 | + public ManageAudienceClientBuilder apiEndPoint(URI apiEndPoint) { | ||
80 | + this.apiEndPoint = requireNonNull(apiEndPoint, "apiEndPoint"); | ||
81 | + return this; | ||
82 | + } | ||
83 | + | ||
84 | + /** | ||
85 | + * Connection timeout. | ||
86 | + * | ||
87 | + * <p>Default value = {@value LineClientConstants#DEFAULT_CONNECT_TIMEOUT_MILLIS}ms. | ||
88 | + */ | ||
89 | + @Setter | ||
90 | + private long connectTimeout = LineClientConstants.DEFAULT_CONNECT_TIMEOUT_MILLIS; | ||
91 | + | ||
92 | + /** | ||
93 | + * Connection timeout. | ||
94 | + * | ||
95 | + * <p>Default value = {@value LineClientConstants#DEFAULT_READ_TIMEOUT_MILLIS}ms. | ||
96 | + */ | ||
97 | + @Setter | ||
98 | + private long readTimeout = LineClientConstants.DEFAULT_READ_TIMEOUT_MILLIS; | ||
99 | + | ||
100 | + /** | ||
101 | + * Write timeout. | ||
102 | + * | ||
103 | + * <p>Default value = {@value LineClientConstants#DEFAULT_WRITE_TIMEOUT_MILLIS}ms. | ||
104 | + */ | ||
105 | + @Setter | ||
106 | + private long writeTimeout = LineClientConstants.DEFAULT_WRITE_TIMEOUT_MILLIS; | ||
107 | + | ||
108 | + /** | ||
109 | + * Channel token supplier of this client. | ||
110 | + * | ||
111 | + * <p>MUST BE NULL except you configured your own | ||
112 | + */ | ||
113 | + @Setter | ||
114 | + private ChannelTokenSupplier channelTokenSupplier; | ||
115 | + | ||
116 | + /** | ||
117 | + * Custom {@link Retrofit.Builder} used internally. | ||
118 | + * | ||
119 | + * <p>If you want to use your own setting, specify {@link Retrofit.Builder} instance. | ||
120 | + * Default builder is used in case of {@code null} (default). | ||
121 | + * | ||
122 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
123 | + * | ||
124 | + * @see #createDefaultRetrofitBuilder() | ||
125 | + */ | ||
126 | + @Setter | ||
127 | + private Retrofit.Builder retrofitBuilder; | ||
128 | + | ||
129 | + /** | ||
130 | + * Add authentication header. | ||
131 | + * | ||
132 | + * <p>Default = {@value}. If you manage authentication header yourself, set to {@code false}. | ||
133 | + */ | ||
134 | + @Setter | ||
135 | + private boolean addAuthenticationHeader = true; | ||
136 | + | ||
137 | + private OkHttpClient.Builder okHttpClientBuilder; | ||
138 | + | ||
139 | + /** | ||
140 | + * Custom interceptors. | ||
141 | + * | ||
142 | + * <p>You can add your own interceptors. | ||
143 | + * | ||
144 | + * <p>Note: Authentication interceptor is automatically added by default. | ||
145 | + * | ||
146 | + * @see #addAuthenticationHeader(boolean) | ||
147 | + */ | ||
148 | + @Setter | ||
149 | + private List<Interceptor> additionalInterceptors = new ArrayList<>(); | ||
150 | + | ||
151 | + /** | ||
152 | + * Set fixed channel token. This overwrites {@link #channelTokenSupplier(ChannelTokenSupplier)}. | ||
153 | + * | ||
154 | + * @see #channelTokenSupplier(ChannelTokenSupplier) | ||
155 | + */ | ||
156 | + public ManageAudienceClientBuilder channelToken(String channelToken) { | ||
157 | + channelTokenSupplier(FixedChannelTokenSupplier.of(channelToken)); | ||
158 | + return this; | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * Set customized OkHttpClient.Builder. | ||
163 | + * | ||
164 | + * <p>In case of you need your own customized {@link OkHttpClient}, | ||
165 | + * this builder allows specify {@link OkHttpClient.Builder} instance. | ||
166 | + * | ||
167 | + * <p>To use this method, please add dependency to 'com.squareup.retrofit2:retrofit'. | ||
168 | + * | ||
169 | + * @param addAuthenticationHeader If true, all default okhttp interceptors ignored. | ||
170 | + * You should insert authentication headers yourself. | ||
171 | + */ | ||
172 | + public ManageAudienceClientBuilder okHttpClientBuilder( | ||
173 | + final @NonNull OkHttpClient.Builder okHttpClientBuilder, | ||
174 | + final boolean addAuthenticationHeader) { | ||
175 | + this.okHttpClientBuilder = okHttpClientBuilder; | ||
176 | + this.addAuthenticationHeader = addAuthenticationHeader; | ||
177 | + | ||
178 | + return this; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Creates a new {@link LineMessagingService}. | ||
183 | + */ | ||
184 | + <T> T buildRetrofitIface(URI apiEndPoint, Class<T> retrofitIFace) { | ||
185 | + if (okHttpClientBuilder == null) { | ||
186 | + okHttpClientBuilder = new OkHttpClient.Builder(); | ||
187 | + } | ||
188 | + | ||
189 | + // Add interceptors. | ||
190 | + if (addAuthenticationHeader) { | ||
191 | + okHttpClientBuilder.addInterceptor(buildAuthenticationInterceptor(channelTokenSupplier)); | ||
192 | + } | ||
193 | + if (additionalInterceptors != null) { | ||
194 | + additionalInterceptors.forEach(okHttpClientBuilder::addInterceptor); | ||
195 | + } | ||
196 | + okHttpClientBuilder.addInterceptor(buildLoggingInterceptor()); | ||
197 | + | ||
198 | + // Set timeout. | ||
199 | + okHttpClientBuilder | ||
200 | + .connectTimeout(connectTimeout, TimeUnit.MILLISECONDS) | ||
201 | + .readTimeout(readTimeout, TimeUnit.MILLISECONDS) | ||
202 | + .writeTimeout(writeTimeout, TimeUnit.MILLISECONDS); | ||
203 | + | ||
204 | + final OkHttpClient okHttpClient = okHttpClientBuilder.build(); | ||
205 | + | ||
206 | + if (retrofitBuilder == null) { | ||
207 | + retrofitBuilder = createDefaultRetrofitBuilder(); | ||
208 | + } | ||
209 | + retrofitBuilder.client(okHttpClient); | ||
210 | + retrofitBuilder.baseUrl(apiEndPoint.toString()); | ||
211 | + | ||
212 | + final Retrofit retrofit = retrofitBuilder.build(); | ||
213 | + | ||
214 | + return retrofit.create(retrofitIFace); | ||
215 | + } | ||
216 | + | ||
217 | + static HeaderInterceptor buildAuthenticationInterceptor(ChannelTokenSupplier channelTokenSupplier) { | ||
218 | + requireNonNull(channelTokenSupplier, "channelTokenSupplier"); | ||
219 | + return HeaderInterceptor.forChannelTokenSupplier(channelTokenSupplier); | ||
220 | + } | ||
221 | + | ||
222 | + static Interceptor buildLoggingInterceptor() { | ||
223 | + final Logger slf4jLogger = LoggerFactory.getLogger("com.linecorp.bot.client.wire"); | ||
224 | + | ||
225 | + return new HttpLoggingInterceptor(slf4jLogger::info) | ||
226 | + .setLevel(Level.BODY); | ||
227 | + } | ||
228 | + | ||
229 | + static Retrofit.Builder createDefaultRetrofitBuilder() { | ||
230 | + return new Retrofit.Builder() | ||
231 | + .addConverterFactory(JacksonConverterFactory.create(objectMapper)); | ||
232 | + } | ||
233 | + | ||
234 | + /** | ||
235 | + * Creates a new {@link LineMessagingService}. | ||
236 | + */ | ||
237 | + public ManageAudienceClient build() { | ||
238 | + return new ManageAudienceClientImpl( | ||
239 | + buildRetrofitIface(apiEndPoint, ManageAudienceService.class)); | ||
240 | + } | ||
241 | +} |
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.util.concurrent.CompletableFuture; | ||
21 | + | ||
22 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
23 | + | ||
24 | +import com.linecorp.bot.client.LineMessagingClientImpl.VoidToBotApiCallbackAdaptor; | ||
25 | +import com.linecorp.bot.model.manageaudience.AudienceGroupCreateRoute; | ||
26 | +import com.linecorp.bot.model.manageaudience.AudienceGroupStatus; | ||
27 | +import com.linecorp.bot.model.manageaudience.request.AddAudienceToAudienceGroupRequest; | ||
28 | +import com.linecorp.bot.model.manageaudience.request.CreateAudienceGroupRequest; | ||
29 | +import com.linecorp.bot.model.manageaudience.request.CreateClickBasedAudienceGroupRequest; | ||
30 | +import com.linecorp.bot.model.manageaudience.request.CreateImpBasedAudienceGroupRequest; | ||
31 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupAuthorityLevelRequest; | ||
32 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupDescriptionRequest; | ||
33 | +import com.linecorp.bot.model.manageaudience.response.CreateAudienceGroupResponse; | ||
34 | +import com.linecorp.bot.model.manageaudience.response.CreateClickBasedAudienceGroupResponse; | ||
35 | +import com.linecorp.bot.model.manageaudience.response.CreateImpBasedAudienceGroupResponse; | ||
36 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceDataResponse; | ||
37 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupAuthorityLevelResponse; | ||
38 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupsResponse; | ||
39 | +import com.linecorp.bot.model.oauth.ChannelAccessTokenException; | ||
40 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
41 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
42 | + | ||
43 | +import lombok.AllArgsConstructor; | ||
44 | +import retrofit2.Call; | ||
45 | +import retrofit2.Callback; | ||
46 | +import retrofit2.Response; | ||
47 | +import retrofit2.http.Body; | ||
48 | + | ||
49 | +/** | ||
50 | + * An implementation of {@link ManageAudienceClient} that issues or revokes channel access tokens. | ||
51 | + */ | ||
52 | +@AllArgsConstructor | ||
53 | +class ManageAudienceClientImpl implements ManageAudienceClient { | ||
54 | + private static final ObjectMapper objectMapper = ModelObjectMapper.createNewObjectMapper(); | ||
55 | + | ||
56 | + private final ManageAudienceService retrofitImpl; | ||
57 | + | ||
58 | + @Override | ||
59 | + public CompletableFuture<CreateAudienceGroupResponse> createAudienceGroup( | ||
60 | + CreateAudienceGroupRequest request) { | ||
61 | + return toFuture(retrofitImpl.createAudienceGroup(request)); | ||
62 | + } | ||
63 | + | ||
64 | + @Override | ||
65 | + public CompletableFuture<BotApiResponse> addAudienceToAudienceGroup( | ||
66 | + AddAudienceToAudienceGroupRequest request) { | ||
67 | + return toBotApiFuture(retrofitImpl.addAudienceToAudienceGroup(request)); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + public CompletableFuture<CreateClickBasedAudienceGroupResponse> createClickBasedAudienceGroup( | ||
72 | + CreateClickBasedAudienceGroupRequest request) { | ||
73 | + return toFuture(retrofitImpl.createClickBasedAudienceGroup(request)); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public CompletableFuture<CreateImpBasedAudienceGroupResponse> createImpBasedAudienceGroup( | ||
78 | + CreateImpBasedAudienceGroupRequest request) { | ||
79 | + return toFuture(retrofitImpl.createImpBasedAudienceGroup(request)); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public CompletableFuture<BotApiResponse> updateAudienceGroupDescription( | ||
84 | + long audienceGroupId, UpdateAudienceGroupDescriptionRequest request) { | ||
85 | + return toBotApiFuture(retrofitImpl.updateAudienceGroupDescription(audienceGroupId, request)); | ||
86 | + } | ||
87 | + | ||
88 | + @Override | ||
89 | + public CompletableFuture<BotApiResponse> deleteAudienceGroup(long audienceGroupId) { | ||
90 | + return toBotApiFuture(retrofitImpl.deleteAudienceGroup(audienceGroupId)); | ||
91 | + } | ||
92 | + | ||
93 | + @Override | ||
94 | + public CompletableFuture<GetAudienceGroupsResponse> getAudienceGroups( | ||
95 | + long page, String description, AudienceGroupStatus status, Long size, | ||
96 | + Boolean includesExternalPublicGroups, AudienceGroupCreateRoute createRoute) { | ||
97 | + return toFuture(retrofitImpl.getAudienceGroups( | ||
98 | + page, description, status, size, | ||
99 | + includesExternalPublicGroups, createRoute)); | ||
100 | + } | ||
101 | + | ||
102 | + @Override | ||
103 | + public CompletableFuture<GetAudienceDataResponse> getAudienceData(long audienceGroupId) { | ||
104 | + return toFuture(retrofitImpl.getAudienceData(audienceGroupId)); | ||
105 | + } | ||
106 | + | ||
107 | + @Override | ||
108 | + public CompletableFuture<GetAudienceGroupAuthorityLevelResponse> getAudienceGroupAuthorityLevel() { | ||
109 | + return toFuture(retrofitImpl.getAudienceGroupAuthorityLevel()); | ||
110 | + } | ||
111 | + | ||
112 | + @Override | ||
113 | + public CompletableFuture<BotApiResponse> updateAudienceGroupAuthorityLevel( | ||
114 | + @Body UpdateAudienceGroupAuthorityLevelRequest request) { | ||
115 | + return toBotApiFuture(retrofitImpl.updateAudienceGroupAuthorityLevel(request)); | ||
116 | + } | ||
117 | + | ||
118 | + private static <T> CompletableFuture<T> toFuture(Call<T> call) { | ||
119 | + final CallbackCompletableFuture<T> future = new CallbackCompletableFuture<>(); | ||
120 | + call.enqueue(future); | ||
121 | + return future; | ||
122 | + } | ||
123 | + | ||
124 | + static class CallbackCompletableFuture<T> extends CompletableFuture<T> implements Callback<T> { | ||
125 | + @Override | ||
126 | + public void onResponse(final Call<T> call, final Response<T> response) { | ||
127 | + if (response.isSuccessful()) { | ||
128 | + complete(response.body()); | ||
129 | + return; | ||
130 | + } | ||
131 | + if (response.code() == 400) { | ||
132 | + try { | ||
133 | + completeExceptionally(objectMapper.readValue(response.errorBody().string(), | ||
134 | + ChannelAccessTokenException.class)); | ||
135 | + return; | ||
136 | + } catch (IOException e) { | ||
137 | + completeExceptionally(e); | ||
138 | + } | ||
139 | + } | ||
140 | + completeExceptionally(new ChannelAccessTokenException(response.message())); | ||
141 | + } | ||
142 | + | ||
143 | + @Override | ||
144 | + public void onFailure(final Call<T> call, final Throwable t) { | ||
145 | + completeExceptionally(new ChannelAccessTokenException(t.getMessage(), t)); | ||
146 | + } | ||
147 | + } | ||
148 | + | ||
149 | + static CompletableFuture<BotApiResponse> toBotApiFuture(Call<Void> callToWrap) { | ||
150 | + final VoidToBotApiCallbackAdaptor completableFuture = new VoidToBotApiCallbackAdaptor(); | ||
151 | + callToWrap.enqueue(completableFuture); | ||
152 | + return completableFuture; | ||
153 | + } | ||
154 | +} |
1 | +/* | ||
2 | + * Copyright 2020 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | +package com.linecorp.bot.client; | ||
17 | + | ||
18 | +import com.linecorp.bot.model.manageaudience.AudienceGroupCreateRoute; | ||
19 | +import com.linecorp.bot.model.manageaudience.AudienceGroupStatus; | ||
20 | +import com.linecorp.bot.model.manageaudience.request.AddAudienceToAudienceGroupRequest; | ||
21 | +import com.linecorp.bot.model.manageaudience.request.CreateAudienceGroupRequest; | ||
22 | +import com.linecorp.bot.model.manageaudience.request.CreateClickBasedAudienceGroupRequest; | ||
23 | +import com.linecorp.bot.model.manageaudience.request.CreateImpBasedAudienceGroupRequest; | ||
24 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupAuthorityLevelRequest; | ||
25 | +import com.linecorp.bot.model.manageaudience.request.UpdateAudienceGroupDescriptionRequest; | ||
26 | +import com.linecorp.bot.model.manageaudience.response.CreateAudienceGroupResponse; | ||
27 | +import com.linecorp.bot.model.manageaudience.response.CreateClickBasedAudienceGroupResponse; | ||
28 | +import com.linecorp.bot.model.manageaudience.response.CreateImpBasedAudienceGroupResponse; | ||
29 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceDataResponse; | ||
30 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupAuthorityLevelResponse; | ||
31 | +import com.linecorp.bot.model.manageaudience.response.GetAudienceGroupsResponse; | ||
32 | + | ||
33 | +import retrofit2.Call; | ||
34 | +import retrofit2.http.Body; | ||
35 | +import retrofit2.http.DELETE; | ||
36 | +import retrofit2.http.GET; | ||
37 | +import retrofit2.http.POST; | ||
38 | +import retrofit2.http.PUT; | ||
39 | +import retrofit2.http.Path; | ||
40 | +import retrofit2.http.Query; | ||
41 | + | ||
42 | +interface ManageAudienceService { | ||
43 | + @POST("v2/bot/audienceGroup/upload") | ||
44 | + Call<CreateAudienceGroupResponse> createAudienceGroup(@Body CreateAudienceGroupRequest request); | ||
45 | + | ||
46 | + @PUT("v2/bot/audienceGroup/upload") | ||
47 | + Call<Void> addAudienceToAudienceGroup(@Body AddAudienceToAudienceGroupRequest request); | ||
48 | + | ||
49 | + @POST("v2/bot/audienceGroup/click") | ||
50 | + Call<CreateClickBasedAudienceGroupResponse> createClickBasedAudienceGroup( | ||
51 | + @Body CreateClickBasedAudienceGroupRequest request); | ||
52 | + | ||
53 | + @POST("v2/bot/audienceGroup/imp") | ||
54 | + Call<CreateImpBasedAudienceGroupResponse> createImpBasedAudienceGroup( | ||
55 | + @Body CreateImpBasedAudienceGroupRequest request); | ||
56 | + | ||
57 | + @PUT("v2/bot/audienceGroup/{audienceGroupId}/updateDescription") | ||
58 | + Call<Void> updateAudienceGroupDescription( | ||
59 | + @Path("audienceGroupId") long audienceGroupId, @Body UpdateAudienceGroupDescriptionRequest request); | ||
60 | + | ||
61 | + @DELETE("v2/bot/audienceGroup/{audienceGroupId}") | ||
62 | + Call<Void> deleteAudienceGroup(@Path("audienceGroupId") long audienceGroupId); | ||
63 | + | ||
64 | + @GET("v2/bot/audienceGroup/{audienceGroupId}") | ||
65 | + Call<GetAudienceDataResponse> getAudienceData(@Path("audienceGroupId") long audienceGroupId); | ||
66 | + | ||
67 | + @GET("v2/bot/audienceGroup/list") | ||
68 | + Call<GetAudienceGroupsResponse> getAudienceGroups( | ||
69 | + @Query("page") long page, | ||
70 | + @Query("description") String description, | ||
71 | + @Query("status") AudienceGroupStatus status, | ||
72 | + @Query("size") Long size, | ||
73 | + @Query("includesExternalPublicGroups") Boolean includesExternalPublicGroups, | ||
74 | + @Query("createRoute") AudienceGroupCreateRoute createRoute); | ||
75 | + | ||
76 | + @GET("v2/bot/audienceGroup/authorityLevel") | ||
77 | + Call<GetAudienceGroupAuthorityLevelResponse> getAudienceGroupAuthorityLevel(); | ||
78 | + | ||
79 | + @PUT("v2/bot/audienceGroup/authorityLevel") | ||
80 | + Call<Void> updateAudienceGroupAuthorityLevel(@Body UpdateAudienceGroupAuthorityLevelRequest request); | ||
81 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.io.IOException; | ||
20 | +import java.io.InputStream; | ||
21 | +import java.util.List; | ||
22 | +import java.util.Map; | ||
23 | + | ||
24 | +import lombok.Builder; | ||
25 | +import lombok.Getter; | ||
26 | +import lombok.ToString; | ||
27 | + | ||
28 | +@Getter | ||
29 | +@Builder | ||
30 | +@ToString | ||
31 | +public class MessageContentResponse implements AutoCloseable { | ||
32 | + /** File size of this content. */ | ||
33 | + final long length; | ||
34 | + | ||
35 | + /** File input stream of this content. */ | ||
36 | + final InputStream stream; | ||
37 | + | ||
38 | + /** File contents type represented by MIME. */ | ||
39 | + final String mimeType; | ||
40 | + | ||
41 | + /** | ||
42 | + * All HTTP headers of API response. | ||
43 | + * | ||
44 | + * <p>Note: there are no SPEC for those headers. | ||
45 | + * Current field values are provided AS-IS and can be changed/removed without announces. | ||
46 | + */ | ||
47 | + final Map<String, List<String>> allHeaders; | ||
48 | + | ||
49 | + @Override | ||
50 | + public void close() throws IOException { | ||
51 | + stream.close(); | ||
52 | + } | ||
53 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +public class BadRequestException extends LineMessagingException { | ||
22 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
23 | + | ||
24 | + public BadRequestException( | ||
25 | + final String message, | ||
26 | + final ErrorResponse errorResponse) { | ||
27 | + super(message, errorResponse, null); | ||
28 | + } | ||
29 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +public class ForbiddenException extends LineMessagingException { | ||
22 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
23 | + | ||
24 | + public ForbiddenException( | ||
25 | + final String message, | ||
26 | + final ErrorResponse errorResponse) { | ||
27 | + super(message, errorResponse, null); | ||
28 | + } | ||
29 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +/** | ||
22 | + * General exceptions both in api server and SDK internal exceptions. | ||
23 | + */ | ||
24 | +public class GeneralLineMessagingException extends LineMessagingException { | ||
25 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
26 | + | ||
27 | + public GeneralLineMessagingException( | ||
28 | + final String message, final ErrorResponse errorResponse, final Throwable cause) { | ||
29 | + super(message, errorResponse, cause); | ||
30 | + } | ||
31 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +import lombok.Getter; | ||
22 | + | ||
23 | +@Getter | ||
24 | +public abstract class LineMessagingException extends Exception { | ||
25 | + static final long SERIAL_VERSION_UID = 0x001_003; // 1.3.x | ||
26 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
27 | + | ||
28 | + /** | ||
29 | + * Original error response from server. | ||
30 | + * | ||
31 | + * <p>Null when error response is not exist. | ||
32 | + */ | ||
33 | + private final ErrorResponse errorResponse; | ||
34 | + | ||
35 | + LineMessagingException(final String message, final ErrorResponse errorResponse, | ||
36 | + final Throwable cause) { | ||
37 | + super(message + (errorResponse != null ? " : " + errorResponse : ""), cause); | ||
38 | + this.errorResponse = errorResponse; | ||
39 | + } | ||
40 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +public class LineServerException extends LineMessagingException { | ||
22 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
23 | + | ||
24 | + public LineServerException( | ||
25 | + final String message, | ||
26 | + final ErrorResponse errorResponse) { | ||
27 | + super(message, errorResponse, null); | ||
28 | + } | ||
29 | +} |
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +public class NotFoundException extends LineMessagingException { | ||
22 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
23 | + | ||
24 | + public NotFoundException( | ||
25 | + final String message, | ||
26 | + final ErrorResponse errorResponse) { | ||
27 | + super(message, errorResponse, null); | ||
28 | + } | ||
29 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +public class TooManyRequestsException extends LineMessagingException { | ||
22 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
23 | + | ||
24 | + public TooManyRequestsException( | ||
25 | + final String message, | ||
26 | + final ErrorResponse errorResponse) { | ||
27 | + super(message, errorResponse, null); | ||
28 | + } | ||
29 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client.exception; | ||
18 | + | ||
19 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
20 | + | ||
21 | +public class UnauthorizedException extends LineMessagingException { | ||
22 | + private static final long serialVersionUID = SERIAL_VERSION_UID; | ||
23 | + | ||
24 | + public UnauthorizedException( | ||
25 | + final String message, | ||
26 | + final ErrorResponse errorResponse) { | ||
27 | + super(message, errorResponse, null); | ||
28 | + } | ||
29 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import java.net.URI; | ||
20 | + | ||
21 | +import org.junit.After; | ||
22 | +import org.junit.Before; | ||
23 | +import org.slf4j.bridge.SLF4JBridgeHandler; | ||
24 | + | ||
25 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
26 | +import com.fasterxml.jackson.databind.ObjectWriter; | ||
27 | + | ||
28 | +import com.linecorp.bot.model.error.ErrorResponse; | ||
29 | + | ||
30 | +import lombok.SneakyThrows; | ||
31 | +import okhttp3.mockwebserver.MockResponse; | ||
32 | +import okhttp3.mockwebserver.MockWebServer; | ||
33 | + | ||
34 | +public abstract class AbstractWiremockTest { | ||
35 | + public static final int ASYNC_TEST_TIMEOUT = 1_000; | ||
36 | + private static final ObjectWriter ERROR_RESPONSE_READER = new ObjectMapper().writerFor(ErrorResponse.class); | ||
37 | + | ||
38 | + static { | ||
39 | + SLF4JBridgeHandler.install(); | ||
40 | + SLF4JBridgeHandler.removeHandlersForRootLogger(); | ||
41 | + } | ||
42 | + | ||
43 | + protected MockWebServer mockWebServer; | ||
44 | + protected LineMessagingClient lineMessagingClient; | ||
45 | + protected LineBlobClient lineBlobClient; | ||
46 | + protected ChannelManagementSyncClient channelManagementSyncClient; | ||
47 | + | ||
48 | + @Before | ||
49 | + public void setUpWireMock() { | ||
50 | + mockWebServer = new MockWebServer(); | ||
51 | + lineMessagingClient = createLineMessagingClient(mockWebServer); | ||
52 | + lineBlobClient = createLineBlobClient(mockWebServer); | ||
53 | + channelManagementSyncClient = createChannelManagementSyncClient(mockWebServer); | ||
54 | + } | ||
55 | + | ||
56 | + @After | ||
57 | + public void shutDownWireMock() throws Exception { | ||
58 | + mockWebServer.shutdown(); | ||
59 | + } | ||
60 | + | ||
61 | + @SneakyThrows | ||
62 | + public void mocking(final int responseCode, final ErrorResponse errorResponse) { | ||
63 | + mockWebServer | ||
64 | + .enqueue(new MockResponse() | ||
65 | + .setResponseCode(responseCode) | ||
66 | + .setBody(ERROR_RESPONSE_READER.writeValueAsString(errorResponse))); | ||
67 | + } | ||
68 | + | ||
69 | + protected LineMessagingClient createLineMessagingClient(final MockWebServer mockWebServer) { | ||
70 | + return LineMessagingClient.builder("token") | ||
71 | + .apiEndPoint(URI.create("http://localhost:" + mockWebServer.getPort())) | ||
72 | + .blobEndPoint(URI.create("http://localhost:" + mockWebServer.getPort())) | ||
73 | + .build(); | ||
74 | + } | ||
75 | + | ||
76 | + protected LineBlobClient createLineBlobClient(MockWebServer mockWebServer) { | ||
77 | + return LineBlobClient.builder("token") | ||
78 | + .apiEndPoint(URI.create("http://localhost:" + mockWebServer.getPort())) | ||
79 | + .build(); | ||
80 | + } | ||
81 | + | ||
82 | + protected ChannelManagementSyncClient createChannelManagementSyncClient(final MockWebServer mockWebServer) { | ||
83 | + return ChannelManagementSyncClient | ||
84 | + .builder(() -> "token") | ||
85 | + .apiEndPoint(URI.create("http://localhost:" + mockWebServer.getPort())) | ||
86 | + .build(); | ||
87 | + } | ||
88 | +} |
line-bot-sdk-java/line-bot-api-client/src/test/java/com/linecorp/bot/client/CallbackAdaptorTest.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static okhttp3.MediaType.parse; | ||
20 | +import static org.assertj.core.api.Assertions.assertThat; | ||
21 | +import static org.mockito.Mockito.mock; | ||
22 | +import static org.mockito.Mockito.when; | ||
23 | + | ||
24 | +import org.junit.Before; | ||
25 | +import org.junit.Rule; | ||
26 | +import org.junit.Test; | ||
27 | +import org.junit.rules.Timeout; | ||
28 | +import org.mockito.Mock; | ||
29 | +import org.mockito.junit.MockitoJUnit; | ||
30 | +import org.mockito.junit.MockitoRule; | ||
31 | + | ||
32 | +import com.linecorp.bot.client.LineMessagingClientImpl.CallbackAdaptor; | ||
33 | +import com.linecorp.bot.client.exception.GeneralLineMessagingException; | ||
34 | + | ||
35 | +import okhttp3.ResponseBody; | ||
36 | +import retrofit2.Call; | ||
37 | +import retrofit2.Response; | ||
38 | + | ||
39 | +public class CallbackAdaptorTest { | ||
40 | + private CallbackAdaptor<Object> target; | ||
41 | + | ||
42 | + @Rule | ||
43 | + public final MockitoRule mockitoRule = MockitoJUnit.rule(); | ||
44 | + | ||
45 | + @Rule | ||
46 | + public final Timeout timeoutRule = Timeout.seconds(10); | ||
47 | + | ||
48 | + @Mock | ||
49 | + private Call<Object> call; | ||
50 | + | ||
51 | + @Before | ||
52 | + public void setUp() throws Exception { | ||
53 | + target = new CallbackAdaptor<>(); | ||
54 | + } | ||
55 | + | ||
56 | + @Test | ||
57 | + public void onResponseSuccessfullyTest() throws Exception { | ||
58 | + final Object value = new Object(); | ||
59 | + Response<Object> response = Response.success(value); | ||
60 | + | ||
61 | + // Do | ||
62 | + target.onResponse(call, response); | ||
63 | + | ||
64 | + // Verify | ||
65 | + assertThat(target).isCompletedWithValue(value); | ||
66 | + } | ||
67 | + | ||
68 | + @Test | ||
69 | + public void onResponseWithErrorTest() throws Exception { | ||
70 | + Response<Object> response = | ||
71 | + Response.error(400, ResponseBody.create(parse("application/json"), "{}")); | ||
72 | + | ||
73 | + // Do | ||
74 | + target.onResponse(call, response); | ||
75 | + | ||
76 | + // Verify | ||
77 | + assertThat(target).isCompletedExceptionally(); | ||
78 | + } | ||
79 | + | ||
80 | + @Test | ||
81 | + public void onFailureTest() throws Exception { | ||
82 | + Throwable t = mock(Throwable.class); | ||
83 | + when(t.getMessage()).thenReturn("Message"); | ||
84 | + | ||
85 | + // Do | ||
86 | + target.onFailure(call, t); | ||
87 | + | ||
88 | + // Verify | ||
89 | + assertThat(target).isCompletedExceptionally(); | ||
90 | + assertThat(target.handle((ignored, e) -> e).get()) | ||
91 | + .isInstanceOf(GeneralLineMessagingException.class) | ||
92 | + .hasMessageContaining("Message"); | ||
93 | + } | ||
94 | +} |
1 | +/* | ||
2 | + * Copyright 2018 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static org.assertj.core.api.Assertions.assertThat; | ||
20 | + | ||
21 | +import java.net.URI; | ||
22 | +import java.nio.charset.StandardCharsets; | ||
23 | + | ||
24 | +import org.junit.Test; | ||
25 | + | ||
26 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
27 | + | ||
28 | +import com.linecorp.bot.liff.LiffView; | ||
29 | +import com.linecorp.bot.liff.LiffView.Type; | ||
30 | +import com.linecorp.bot.liff.request.LiffAppAddRequest; | ||
31 | +import com.linecorp.bot.liff.response.LiffAppAddResponse; | ||
32 | +import com.linecorp.bot.model.objectmapper.ModelObjectMapper; | ||
33 | + | ||
34 | +import okhttp3.mockwebserver.MockResponse; | ||
35 | +import okhttp3.mockwebserver.RecordedRequest; | ||
36 | + | ||
37 | +public class ChannelManagementSyncClientIntegrationWiremockTest | ||
38 | + extends AbstractWiremockTest { | ||
39 | + private static final ObjectMapper OBJECT_MAPPER = ModelObjectMapper.createNewObjectMapper(); | ||
40 | + | ||
41 | + @Test(timeout = ASYNC_TEST_TIMEOUT) | ||
42 | + public void testAddLiffMenu() throws Exception { | ||
43 | + // Mocking | ||
44 | + LiffAppAddResponse response = new LiffAppAddResponse("NEW_LIFF_ID"); | ||
45 | + mockWebServer.enqueue(new MockResponse().setResponseCode(200) | ||
46 | + .setBody(OBJECT_MAPPER.writeValueAsString(response))); | ||
47 | + | ||
48 | + // Do | ||
49 | + LiffView liffView = new LiffView(Type.COMPACT, URI.create("https://example.com")); | ||
50 | + LiffAppAddRequest request = new LiffAppAddRequest(liffView); | ||
51 | + final LiffAppAddResponse liffAppAddResponse = channelManagementSyncClient.addLiffApp(request); | ||
52 | + | ||
53 | + // Verify | ||
54 | + final RecordedRequest recordedRequest = mockWebServer.takeRequest(); | ||
55 | + final LiffAppAddRequest requestedBody = OBJECT_MAPPER | ||
56 | + .readValue(recordedRequest.getBody().readString(StandardCharsets.UTF_8), | ||
57 | + LiffAppAddRequest.class); | ||
58 | + assertThat(requestedBody) | ||
59 | + .isEqualTo(request); | ||
60 | + assertThat(recordedRequest.getPath()) | ||
61 | + .isEqualTo("/liff/v1/apps"); | ||
62 | + assertThat(liffAppAddResponse.getLiffId()) | ||
63 | + .isEqualTo("NEW_LIFF_ID"); | ||
64 | + } | ||
65 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static org.assertj.core.api.Assertions.assertThat; | ||
20 | +import static org.mockito.Mockito.mock; | ||
21 | +import static org.mockito.Mockito.when; | ||
22 | + | ||
23 | +import org.junit.Test; | ||
24 | + | ||
25 | +import com.linecorp.bot.client.exception.GeneralLineMessagingException; | ||
26 | +import com.linecorp.bot.client.exception.LineMessagingException; | ||
27 | +import com.linecorp.bot.client.exception.UnauthorizedException; | ||
28 | + | ||
29 | +import okhttp3.MediaType; | ||
30 | +import okhttp3.Protocol; | ||
31 | +import okhttp3.Request; | ||
32 | +import okhttp3.Response.Builder; | ||
33 | +import okhttp3.ResponseBody; | ||
34 | +import retrofit2.Response; | ||
35 | + | ||
36 | +public class ExceptionConverterTest { | ||
37 | + private final ExceptionConverter target = new ExceptionConverter(); | ||
38 | + | ||
39 | + @Test | ||
40 | + public void convertTest() { | ||
41 | + final ResponseBody responseBody = | ||
42 | + ResponseBody.create(MediaType.parse("application/json"), | ||
43 | + "{}"); | ||
44 | + final LineMessagingException result = | ||
45 | + target.apply(Response.error(401, responseBody)); | ||
46 | + | ||
47 | + assertThat(result) | ||
48 | + .isInstanceOf(UnauthorizedException.class); | ||
49 | + } | ||
50 | + | ||
51 | + @Test | ||
52 | + public void convertUnknownExceptionTest() { | ||
53 | + final ResponseBody responseBody = | ||
54 | + ResponseBody.create(MediaType.parse("application/json"), | ||
55 | + "{}"); | ||
56 | + final LineMessagingException result = | ||
57 | + target.apply(Response.error(999, responseBody)); | ||
58 | + | ||
59 | + assertThat(result) | ||
60 | + .isInstanceOf(GeneralLineMessagingException.class); | ||
61 | + } | ||
62 | + | ||
63 | + @Test | ||
64 | + public void exceptionInConvertFallbackedTest() { | ||
65 | + final ResponseBody responseBody = mock(ResponseBody.class); | ||
66 | + when(responseBody.source()).thenThrow(new RuntimeException()); | ||
67 | + | ||
68 | + final LineMessagingException result = | ||
69 | + target.apply(Response.error(401, responseBody)); | ||
70 | + | ||
71 | + assertThat(result) | ||
72 | + .isInstanceOf(GeneralLineMessagingException.class); | ||
73 | + } | ||
74 | + | ||
75 | + @Test | ||
76 | + public void requestIdDeserializationTest() { | ||
77 | + final ResponseBody responseBody = | ||
78 | + ResponseBody.create(MediaType.parse("application/json"), | ||
79 | + "{\"message\":\"Invalid reply token\"}"); | ||
80 | + | ||
81 | + final okhttp3.Response rawResponse = new Builder() | ||
82 | + .code(400) | ||
83 | + .message("") | ||
84 | + .request(new Request.Builder().get().url("https://api.line.me/v2/bot/message/reply").build()) | ||
85 | + .addHeader("X-Line-Request-Id", "5ac44e02-e6be-49c3-a55f-6b2a29bc3aa4") | ||
86 | + .protocol(Protocol.HTTP_1_1) | ||
87 | + .build(); | ||
88 | + | ||
89 | + // Precondition | ||
90 | + assertThat(rawResponse.header("X-Line-Request-Id")).isEqualTo("5ac44e02-e6be-49c3-a55f-6b2a29bc3aa4"); | ||
91 | + | ||
92 | + // Do | ||
93 | + final LineMessagingException result = | ||
94 | + target.apply(Response.error(responseBody, rawResponse)); | ||
95 | + | ||
96 | + // Verify | ||
97 | + assertThat(result.getErrorResponse().getRequestId()).isEqualTo("5ac44e02-e6be-49c3-a55f-6b2a29bc3aa4"); | ||
98 | + } | ||
99 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static org.assertj.core.api.Assertions.assertThat; | ||
20 | +import static org.assertj.core.api.Assertions.fail; | ||
21 | + | ||
22 | +import org.junit.Test; | ||
23 | + | ||
24 | +public class FixedChannelTokenSupplierTest { | ||
25 | + @Test(expected = NullPointerException.class) | ||
26 | + public void constructedInstanceAlwaysNonNullTest() { | ||
27 | + // Do | ||
28 | + FixedChannelTokenSupplier.of(null); | ||
29 | + | ||
30 | + // Verify | ||
31 | + fail("NullPointerException is not occurred."); | ||
32 | + } | ||
33 | + | ||
34 | + @Test | ||
35 | + public void getTest() { | ||
36 | + ChannelTokenSupplier target = FixedChannelTokenSupplier.of("FIXED_TOKEN"); | ||
37 | + | ||
38 | + // DO | ||
39 | + String result = target.get(); | ||
40 | + | ||
41 | + // Verify | ||
42 | + assertThat(result).isEqualTo("FIXED_TOKEN"); | ||
43 | + } | ||
44 | +} |
1 | +/* | ||
2 | + * Copyright 2016 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Collections.singletonList; | ||
20 | +import static org.assertj.core.api.Assertions.assertThat; | ||
21 | +import static org.mockito.Mockito.when; | ||
22 | + | ||
23 | +import java.net.URI; | ||
24 | + | ||
25 | +import org.junit.Rule; | ||
26 | +import org.junit.Test; | ||
27 | +import org.mockito.Mock; | ||
28 | +import org.mockito.junit.MockitoJUnit; | ||
29 | +import org.mockito.junit.MockitoRule; | ||
30 | + | ||
31 | +import okhttp3.mockwebserver.MockWebServer; | ||
32 | +import okhttp3.mockwebserver.RecordedRequest; | ||
33 | + | ||
34 | +public class HeaderInterceptorWireMockTest extends AbstractWiremockTest { | ||
35 | + @Rule | ||
36 | + public final MockitoRule mockitoRule = MockitoJUnit.rule(); | ||
37 | + | ||
38 | + @Mock | ||
39 | + ChannelTokenSupplier channelTokenSupplier; | ||
40 | + | ||
41 | + @Test(timeout = ASYNC_TEST_TIMEOUT) | ||
42 | + public void forChannelTokenSupplier() throws Exception { | ||
43 | + // Do | ||
44 | + when(channelTokenSupplier.get()).thenReturn("1st"); | ||
45 | + lineMessagingClient.getProfile("TEST"); | ||
46 | + | ||
47 | + // Verify | ||
48 | + final RecordedRequest request1st = mockWebServer.takeRequest(); | ||
49 | + assertThat(request1st.getHeaders().toMultimap()) | ||
50 | + .containsEntry("Authorization", singletonList("Bearer 1st")); | ||
51 | + | ||
52 | + // Do again with another channel token. | ||
53 | + when(channelTokenSupplier.get()).thenReturn("2nd"); | ||
54 | + lineMessagingClient.getProfile("TEST"); | ||
55 | + | ||
56 | + // Verify | ||
57 | + final RecordedRequest request2nd = mockWebServer.takeRequest(); | ||
58 | + assertThat(request2nd.getHeaders().toMultimap()) | ||
59 | + .containsEntry("Authorization", singletonList("Bearer 2nd")); | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + protected LineMessagingClient createLineMessagingClient(final MockWebServer mockWebServer) { | ||
64 | + return LineMessagingClient.builder(channelTokenSupplier) | ||
65 | + .apiEndPoint(URI.create("http://localhost:" + mockWebServer.getPort())) | ||
66 | + .build(); | ||
67 | + } | ||
68 | +} |
1 | +/* | ||
2 | + * Copyright 2019 LINE Corporation | ||
3 | + * | ||
4 | + * LINE Corporation licenses this file to you under the Apache License, | ||
5 | + * version 2.0 (the "License"); you may not use this file except in compliance | ||
6 | + * with the License. You may obtain a copy of the License at: | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
12 | + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
13 | + * License for the specific language governing permissions and limitations | ||
14 | + * under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package com.linecorp.bot.client; | ||
18 | + | ||
19 | +import static java.util.Collections.emptyList; | ||
20 | +import static java.util.Collections.singletonMap; | ||
21 | +import static org.assertj.core.api.Assertions.assertThat; | ||
22 | +import static org.mockito.ArgumentMatchers.any; | ||
23 | +import static org.mockito.ArgumentMatchers.eq; | ||
24 | +import static org.mockito.Mockito.only; | ||
25 | +import static org.mockito.Mockito.verify; | ||
26 | +import static org.mockito.Mockito.when; | ||
27 | + | ||
28 | +import java.io.IOException; | ||
29 | + | ||
30 | +import org.junit.Rule; | ||
31 | +import org.junit.Test; | ||
32 | +import org.junit.rules.Timeout; | ||
33 | +import org.mockito.InjectMocks; | ||
34 | +import org.mockito.Mock; | ||
35 | +import org.mockito.junit.MockitoJUnit; | ||
36 | +import org.mockito.junit.MockitoRule; | ||
37 | +import org.mockito.stubbing.OngoingStubbing; | ||
38 | + | ||
39 | +import com.linecorp.bot.model.response.BotApiResponse; | ||
40 | + | ||
41 | +import okhttp3.Headers; | ||
42 | +import okhttp3.MediaType; | ||
43 | +import okhttp3.Request; | ||
44 | +import okhttp3.ResponseBody; | ||
45 | +import retrofit2.Call; | ||
46 | +import retrofit2.Callback; | ||
47 | +import retrofit2.Response; | ||
48 | + | ||
49 | +public class LineBlobClientImplTest { | ||
50 | + private static final byte[] ZERO_BYTES = {}; | ||
51 | + private static final String REQUEST_ID_FIXTURE = "REQUEST_ID_FIXTURE"; | ||
52 | + private static final BotApiResponseBody BOT_API_SUCCESS_RESPONSE_BODY = | ||
53 | + new BotApiResponseBody("", emptyList()); | ||
54 | + private static final BotApiResponse BOT_API_SUCCESS_RESPONSE = | ||
55 | + BOT_API_SUCCESS_RESPONSE_BODY.withRequestId(REQUEST_ID_FIXTURE); | ||
56 | + | ||
57 | + @Rule | ||
58 | + public final MockitoRule mockitoRule = MockitoJUnit.rule(); | ||
59 | + | ||
60 | + @Rule | ||
61 | + public final Timeout timeoutRule = Timeout.seconds(5); | ||
62 | + | ||
63 | + @Mock | ||
64 | + private LineBlobService retrofitMock; | ||
65 | + | ||
66 | + @InjectMocks | ||
67 | + private LineBlobClientImpl target; | ||
68 | + | ||
69 | + @Test | ||
70 | + public void getMessageContentTest() throws Exception { | ||
71 | + whenCall(retrofitMock.getMessageContent(any()), | ||
72 | + ResponseBody.create(MediaType.parse("image/jpeg"), ZERO_BYTES)); | ||
73 | + | ||
74 | + // Do | ||
75 | + final MessageContentResponse contentResponse = target.getMessageContent("ID").get(); | ||
76 | + | ||
77 | + // Verify | ||
78 | + verify(retrofitMock, only()).getMessageContent("ID"); | ||
79 | + assertThat(contentResponse.getLength()).isEqualTo(0); | ||
80 | + assertThat(contentResponse.getMimeType()).isEqualTo("image/jpeg"); | ||
81 | + } | ||
82 | + | ||
83 | + @Test | ||
84 | + public void getRichMenuImageTest() throws Exception { | ||
85 | + whenCall(retrofitMock.getRichMenuImage(any()), | ||
86 | + ResponseBody.create(MediaType.parse("image/jpeg"), ZERO_BYTES)); | ||
87 | + | ||
88 | + // Do | ||
89 | + final MessageContentResponse messageContentResponse = target.getRichMenuImage("ID").get(); | ||
90 | + | ||
91 | + // Verify | ||
92 | + verify(retrofitMock, only()).getRichMenuImage("ID"); | ||
93 | + assertThat(messageContentResponse.getLength()).isZero(); | ||
94 | + } | ||
95 | + | ||
96 | + @Test | ||
97 | + public void uploadRichMenuImageTest() throws Exception { | ||
98 | + whenCall(retrofitMock.uploadRichMenuImage(any(), any()), | ||
99 | + null); | ||
100 | + | ||
101 | + // Do | ||
102 | + final BotApiResponse botApiResponse = | ||
103 | + target.setRichMenuImage("ID", "image/jpeg", ZERO_BYTES).get(); | ||
104 | + | ||
105 | + // Verify | ||
106 | + verify(retrofitMock, only()) | ||
107 | + .uploadRichMenuImage(eq("ID"), any()); | ||
108 | + assertThat(botApiResponse).isEqualTo(BOT_API_SUCCESS_RESPONSE); | ||
109 | + | ||
110 | + } | ||
111 | + | ||
112 | + // Utility methods | ||
113 | + | ||
114 | + private static <T> void whenCall(Call<T> call, T value) { | ||
115 | + final OngoingStubbing<Call<T>> callOngoingStubbing = when(call); | ||
116 | + callOngoingStubbing.thenReturn(enqueue(value)); | ||
117 | + } | ||
118 | + | ||
119 | + private static <T> Call<T> enqueue(T value) { | ||
120 | + return new Call<T>() { | ||
121 | + @Override | ||
122 | + public Response<T> execute() throws IOException { | ||
123 | + throw new UnsupportedOperationException(); | ||
124 | + } | ||
125 | + | ||
126 | + @Override | ||
127 | + public void enqueue(Callback<T> callback) { | ||
128 | + final Headers headers = Headers.of(singletonMap("x-line-request-id", REQUEST_ID_FIXTURE)); | ||
129 | + callback.onResponse(this, Response.success(value, headers)); | ||
130 | + } | ||
131 | + | ||
132 | + @Override | ||
133 | + public boolean isExecuted() { | ||
134 | + throw new UnsupportedOperationException(); | ||
135 | + } | ||
136 | + | ||
137 | + @Override | ||
138 | + public void cancel() { | ||
139 | + throw new UnsupportedOperationException(); | ||
140 | + } | ||
141 | + | ||
142 | + @Override | ||
143 | + public boolean isCanceled() { | ||
144 | + throw new UnsupportedOperationException(); | ||
145 | + } | ||
146 | + | ||
147 | + @Override | ||
148 | + public Call<T> clone() { | ||
149 | + throw new UnsupportedOperationException(); | ||
150 | + } | ||
151 | + | ||
152 | + @Override | ||
153 | + public Request request() { | ||
154 | + throw new UnsupportedOperationException(); | ||
155 | + } | ||
156 | + }; | ||
157 | + } | ||
158 | +} |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-api-client/src/test/java/com/linecorp/bot/client/LineOAuthClientTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/README.md
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/build.gradle
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/FriendDemographicsGetCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/MessagePushCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/RichMenuCreateCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/RichMenuDeleteCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/RichMenuGetCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/RichMenuImageDownloadCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/RichMenuImageUploadCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/RichMenuListCommand.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/arguments/Arguments.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/arguments/PayloadArguments.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/main/java/com/linecorp/bot/cli/arguments/PayloadProvider.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-cli/src/test/java/com/linecorp/bot/cli/arguments/PayloadProviderTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/liff/request/LiffAppAddRequest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/liff/response/LiffAppsResponse.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/action/CameraAction.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/action/CameraRollAction.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/action/LocationAction.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/action/MessageAction.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/action/PostbackAction.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/action/URIAction.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/error/ErrorDetail.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/error/ErrorResponse.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/AccountLinkEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/BeaconEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/CallbackRequest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/EventMode.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/FollowEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/JoinEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/LeaveEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/MemberJoinedEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/MemberLeftEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/MessageEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/PostbackEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/ReplyEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/ThingsEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/UnfollowEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/UnknownEvent.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/link/LinkContent.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/source/GroupSource.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/source/RoomSource.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/source/Source.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/event/source/UserSource.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/AudioMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/FlexMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/ImageMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/ImagemapMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/LocationMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/Message.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/StickerMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/TemplateMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/TextMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/VideoMessage.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/sender/Sender.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/message/template/Template.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/narrowcast/Filter.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/narrowcast/Limit.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/response/BotApiResponse.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/richmenu/RichMenu.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/richmenu/RichMenuArea.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/richmenu/RichMenuBounds.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/richmenu/RichMenuResponse.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/main/java/com/linecorp/bot/model/richmenu/RichMenuSize.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/NarrowcastTest.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/error/ErrorResponseTest.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/event/CallbackRequestTest.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/event/MessageEventTest.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/event/ReplyEventTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/message/AudioMessageTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/message/FlexMessageTest.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/message/ImageMessageTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/message/TextMessageTest.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/message/VideoMessageTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/java/com/linecorp/bot/model/testutil/TestUtil.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/resources/callback/line-things-scenario-result.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-model/src/test/resources/response/GetMessageEventResponse.json
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-parser/src/main/java/com/linecorp/bot/parser/LineSignatureValidator.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-parser/src/main/java/com/linecorp/bot/parser/SignatureValidator.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-parser/src/main/java/com/linecorp/bot/parser/WebhookParseException.java
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-parser/src/main/java/com/linecorp/bot/parser/WebhookParser.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/line-bot-parser/src/test/java/com/linecorp/bot/parser/WebhookParserTest.java
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/lombok.config
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/manage_audience/click.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/manage_audience/imp.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/manage_audience/list.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/manage_audience/show.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/manage_audience/upload.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/__message_form.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/__retargeting.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/broadcast/form.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/broadcast/result.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/multicast/form.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/multicast/result.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/narrowcast/form.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/push/form.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/push/result.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/report/quota.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/message/report/sent.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-manage-audience/src/main/resources/templates/request_log/index.ftlh
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-spring-boot-echo-kotlin/src/main/resources/application-template.yml
0 → 100644
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.

121 KB

170 KB

99.1 KB
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
line-bot-sdk-java/sample-spring-boot-kitchensink/src/main/resources/static/buttons/1040.jpg
0 → 100644

62.8 KB

8.21 KB
line-bot-sdk-java/sample-spring-boot-kitchensink/src/main/resources/static/imagemap_video/1040
0 → 100644
No preview for this file type
line-bot-sdk-java/sample-spring-boot-kitchensink/src/main/resources/static/imagemap_video/240
0 → 100644
No preview for this file type
line-bot-sdk-java/sample-spring-boot-kitchensink/src/main/resources/static/imagemap_video/300
0 → 100644
No preview for this file type
line-bot-sdk-java/sample-spring-boot-kitchensink/src/main/resources/static/imagemap_video/460
0 → 100644
No preview for this file type
line-bot-sdk-java/sample-spring-boot-kitchensink/src/main/resources/static/imagemap_video/700
0 → 100644
No preview for this file type
No preview for this file type

5.77 KB
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
line-bot-sdk-java/settings.gradle
0 → 100644
This diff is collapsed. Click to expand it.
line-bot-sdk-java/system.properties
0 → 100644
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment